angularjs change element based on dropdown select - angularjs

Using angularjs
I have 3 select dropdowns and a button to get a json list
Focus select dropdown looks like this:
<select id='sort' ng-model='sort'>
<option value='1'>ID</option>
<option value='2'>Departmentname</option>
<option value='3'>Number of employees</option>
</select>
<button ng-click="getinfo()">GET INFO</button>
The table looks like this
<table>
<tr> <td>{{ depid }}</td> <td>{{ depname }}</span></td> <td>{{ depemp }}</td></tr>
In the controller I have:
$scope.depid = "Department id";
$scope.depname = "Departmentname";
$scope.depemp = "Number of employees";
$scope.getinfo = function() {
var url = "";
...
}
Based on selection "sort" I want the sort column to be bold/strong or uppercase.
How do I do thIS?

You can use ng-class on the td elements:
<tr>
<td ng-class="{bold : sort == 1}">{{ depid }}</td>
<td ng-class="{bold : sort == 2}">{{ depname }}</span></td>
<td ng-class="{bold : sort == 3}">{{ depemp }}</td>
</tr>
And add a CSS rule:
.bold {
font-weight: bold;
}
Here's a Fiddle demonstration.

Following Omri Aharon I changed
ng-class="{bold : sort == 1}"
to
ng-class="{bold : sortby == 1}"
and followed Nayish I put following inside controller
$scope.getinfo = function() {
var url = "";
...
$http.get(url)
.success(function(response) {
$scope.names = response;
$scope.sortby = $scope.sort;});
}
Thanks a lot to the two of you!

Related

Ranking table with sorting & dynamic columns

I'm trying to do a ranking table :
I have an object scores with the total of points, and each "challenge" with the points associated to this challenge. My principal problem is to run through scores to create a th tag for each challenge & to sort these after.
The aims :
The number of challenge must be dynamic
Sort by total (done) & by challenge
My problems :
How use ng-repeat for the array of challenge
How to sort these
My advancement :
var myApp = angular.module('myApp',[]);
function MyCtrl($scope) {
$scope.sortType = 'points';
$scope.sortReverse = false;
$scope.scores = {
"6":{
"total":5,
"challenges":{
"1":{
"challengeId":1},
"2":{
"point":2,
"challengeId":2}
}
},
"21":{
"total":2,
"challenges":{
"1":{
"point":1,
"challengeId":1},
"2":{
"point":1,
"challengeId":2}
}
},
}
}
myApp.filter('orderObjectBy', function() {
return function(items, field, reverse) {
var filtered = [];
angular.forEach(items, function(item) {
filtered.push(item);
});
filtered.sort(function (a, b) {
return (a[field] > b[field] ? 1 : -1);
});
if(reverse) filtered.reverse();
return filtered;
};
});
<div ng-controller="MyCtrl">
<table>
<tr>
<th>Rank</th>
<th>
<span ng-click="toggleSort($index);sortReverse=false">+</span>
Total
<span ng-click="toggleSort($index);sortReverse=true">-</span>
</th>
<th ng-repeat="challenge in scores.challenges">
<span ng-click="toggleSort($index);sortReverse=false">X</span>
Challenge n°
<span ng-click="toggleSort($index);sortReverse=true">Y</span>
</th>
</tr>
<tbody ng-repeat="score in scores | orderObjectBy:sortType:sortReverse">
<tr>
<td>{{ $index+1 }}</td>
<td>{{ score.total }}</td>
<td ng-repeat="challenge in score.challenges">{{ challenge.point }}</td>
</tr>
</tbody>
</table>
</div>
JSFiddle
Thank you!
I updated the fiddle. When you want to order by a nested value this is how you specify the orderString (In your case it will be by a particular challenge ID):
$scope.orderType = "challenges."+challengeId+'.point';
Also I added a filter which convert the object in an array:
.filter('orderObjectBy', function() {
return function (items, field, reverse) {
var filtered = [];
angular.forEach(items, function(item, key) {
item.key = key;
filtered.push(item);
});
return filtered;
};
});
Then your html should look like this:
<tbody ng-repeat="score in scores| orderObjectBy | orderBy: orderType:sortReverse">
<tr>
<td>{{ $index+1 }}</td>
<td>{{ score.total }}</td>
<td ng-repeat="challenge in score.challenges">{{ challenge.point }}</td>
</tr>
</tbody>
Check this working sample: http://jsfiddle.net/Lvc0u55v/13564/

AngularJS table orderBy checkbox

I want to sort a table when a checkbox is clicked and be able to filter the table also. The code below has been fixed and works now....
HTML
<table>
<tr ng-repeat="x in myArray | filter : name | orderBy : sortOrder">
<td>{{ x.name }}</td>
<td>{{ x.age }}</td>
</tr>
</table>
<input type="checkbox" ng-model="sortByName" ng-change="setSortOrder()">
<input type="text" ng-model="name">
AngularJS
app.controller("myController", function($scope, $http)
{
$scope.filterString = '';
$scope.sortByName = false;
$scope.sortOrder = '';
$scope.setSortOrder = function()
{
if($scope.sortByName)
{
$scope.sortOrder = 'name';
}
else
{
$scope.sortOrder = '';
}
}
You are missing telling your checkbox to call the controller method that selects the sort criteria when its checked status changes. You can do this by using the ngChange directive. Try the following:
<input type="checkbox" ng-model="sortByName" ng-change="setSortOrder()">

AngularJS ng-click change color on two tds within ng-repeat

I have some code that lists out items in a table from a database. The click function toggles the cells between green and red.
<tr ng-repeat="team in Pool">
<td ng-class="{'btn-danger': namestarted[$index], 'btn-success': !namestarted[$index]}" ng-click="changeColor(team.chrTeamName, $index)">{{ team.chrTeamName }}</td>
<td>{{ team.intSeed }}</td>
<td ng-class="{'btn-danger': divstarted[$index], 'btn-success': !divstarted[$index]}" ng-click="changeColor(team.chrDivision, $index)">{{ team.chrDivision }}</td>
</tr>
Controller:
$scope.namestarted = [];
$scope.divstarted = [];
$scope.changeColor= function (status, index) {
if(status == "Name"){
//How to know if the 'Name" is Selected or NotSelected???
$scope.namestarted [index] = !$scope.namestarted [index];}
else
$scope.divstarted [index] = !$scope.divstarted [index];
}
Now When i click "Name" or "Division", i need to know whether it is Selected or NotSelected (active or not)??

Is it possible to have 2 datasources for ng-repeat?

Is it possible to have
<tbody ng-repeat="Emp in Employees" ng-repeat="Dept in Department">
<td> <span>{{Emp.id}}</span></td>
<td> <span>{{Emp.name}}</span></td>
<td> <span>{{Dept.Deptid}}</span></td>
</tbody>
That means two different sources.... It is for a composite UI requirement. If not available, what is the alternate way?
I am not looking for
<tbody ng-repeat="Emp in Employees" >
<td> <span>{{Emp.id}}</span></td>
<td> <span>{{Emp.name}}</span></td>
</tbody>
<tbody ng-repeat="Dept in Department">
<td> <span>{{Dept.Deptid}}</span></td>
<td> <span>{{Dept.Deptname}}</span></td>
</tbody>
Something similar to LINQ in C# like
var x = (from a in AList
join b in BList on a.item = b.item
select new{....});
You can do it by merging two arrays
app.controller('MainCtrl', function($scope) {
$scope.Employees = [{
'id':1,
'name':'rachit1'
},
{
'id':2,
'name':'rachit2'
}];
$scope.Department=[{
'Deptid':'1D',
'Deptname':'dep1'
},
{
'Deptid':'2D',
'Deptname':'dep2'
}];
$scope.result=merge($scope.Employees,$scope.Department);
function merge(obj1,obj2){ // Our merge function
var result = {}; // return result
for(var i in obj1){ // for every property in obj1
if((i in obj2) && (typeof obj1[i] === "object") && (i !== null)){
result[i] = merge(obj1[i],obj2[i]); // if it's an object, merge
}else{
result[i] = obj1[i]; // add it to result
}
}
for(i in obj2){ // add the remaining properties from object 2
if(i in result){ //conflict
continue;
}
result[i] = obj2[i];
}
return result;
}
});
HTML:-
<body ng-controller="MainCtrl">
<table>
<tbody ng-repeat="Emp in result">
<td> <span>{{Emp.id}}</span></td>
<td> <span>{{Emp.name}}</span></td>
<td> <span>{{Emp.Deptid}}</span></td>
<td> <span>{{Emp.Deptname}}</span></td>
</tbody>
</table>
</body>
Plunker
The answer is :Can't. Because may the looping count is difference.
can you write a looping statement on a another one looping statement?
for (var i=0;i<Empcount;i<DeptCount;i++)
{
// code
}
Is it impossible, Same as what the answer for your question. You can think the result.
I know that it is not really an answer, but I must to say this: your data organised incorrectly. Data integrity is violated.
But if you can't change the source structure for some reason try to combine that data in the controller:
$scope.employees = employees.map(function (employee, index) {
employee.department = departments[index];
return employee;
})
Then use it in the ng-repeat:
<tbody>
<tr ng-repeat="employee in employees">
<td>{{ employee.id }}</td>
<td>{{ employee.name }}</td>
<td>{{ employee.department.deptId }}</td>
</tr>
</tbody>
NOTES:
Do not repeat <tbody> tag.
Apply the technique if Departments.length === Employees.lengh and the order is correct.
Do not capitalize not constructors. Rename Departments to departments, Employees to employees.
If you don't have any styles on td > span then remove unnecessary span's

angularjs ng-repeat with Filter or ng-if condition

I want to render text if it is Name or Value. I don't want to loop if it is createdate or enventId. I'm trying with Filter and ng-if condition. It is not working.
HTML CODE
<tr ng-repeat="event in events | filter:Name ">
<td >{{event.Name}} : </td>
<td>{{ event.Value }}</td>
</tr>
JS CODE
Events: [
{
CreatedTime: "/Date(1420757322810-0800)/",
EventId: 13,
Name: "AdGroupId",
Value: "2367898"
},
{
CreatedTime: "/Date(1420757322810-0800)/",
EventId: 13,
Name: "AdGroupId",
Value: "2367898"
}
]
I expect the result should be
AdGroupId :2367898
Assuming that what you are trying to ask is how to exclude items with neither a name nor a value, you'll need a custom function for this. This should suffice:
$scope.filterEvents = function(e){
return e.Name || e.Value;
};
And then:
<tr ng-repeat="event in events | filter:filterEvents">
<td >{{event.Name}} : </td>
<td>{{ event.Value }}</td>
</tr>
Example
Alternatively, if you are saying you want to filter the values based on a specified name and/or value, you can do so like this:
$scope.filterEvents = function (e) {
return ($scope.Name || $scope.Value) &&
(!$scope.Name || $scope.Name === e.Name) &&
(!$scope.Value || $scope.Value === e.Value);
};
(HTML is same as above)
Example
Assuming you are looking for a filter to cut out the Events that has no Name and Value properties in it.
Here is a sample for you:
Controller:
$scope.filterNameValue = function(e){
if(angular.isDefined(e.Name) && angular.isDefined(e.Value))
return e;
};
Html
<table>
<tbody>
<tr ng-repeat="event in events | filter: filterNameValue">
<td >{{event.Name}} : </td>
<td>{{ event.Value }}</td>
</tr>
</tbody>
</table>
Working Sample here

Resources