AngularJS - Nested ng-repeat for table - javascript

I just started with AngularJS and I'm trying to make a users table that shows the users for the application and the roles they are in (e.g. Admin, Editor, Anon) with checkboxes to take the users in and out of roles.
<tbody>
<tr data-ng-repeat="item in pagedItems[currentPage] | orderBy:sortingOrder:reverse">
<td class="table-item-title"><a title="{{item.UserName}}" href="" ng-click="loadEditForm(item.UserName)">{{item.UserName}}</a></td>
<td class="hmax479">{{item.Email}}</td>
<td align="center" data-ng-repeat="role in roles" style="align:center;">
<input type="checkbox" data-ng-model="role.IsChecked" style="align:center;"/>
</td>
</tr>
</tbody
With the above code it updates the checkboxes for the entire group based on the last user that was clicked rather than for a single user. Is there any way I can change this code with something like a "user in users" ng-repeat to change this or do I need to add a new function in the controller?

Each user could have an array of roles to show the roles that has been assigned to the user. For each user, while looping through the roles, you use a filter to only check assigned roles. You could use a function in your controller to add/remove roles as the check boxes are selected/deselected.
<tbody>
<tr data-ng-repeat="item in pagedItems[currentPage] | orderBy:sortingOrder:reverse">
<td class="table-item-title"><a title="{{item.UserName}}" href="" ng-click="loadEditForm(item.UserName)">{{item.UserName}}</a></td>
<td class="hmax479">{{item.Email}}</td>
<td align="center" data-ng-repeat="role in roles" style="align:center;">
<input type="checkbox" data-ng-checked="role | hasRole:item.Roles" data-ng-click="addOrRemove($parent.$index, role)" style="align:center;"/>
</td>
</tr>
</tbody>
The filter
app.filter('hasRole', function() {
return function (role, userRoles) {
var result = false;
userRoles.forEach(function(value, index) { // loop through the roles
// return true if the user has the role
if(role.Name == value.Name) // This is replaced by any method of comparing roles
result = true;
});
return result;
}
}
In your controller, you implement addOrRemove()

Related

How do I filter a table by any matching code/name and not every available field

I'm trying to do the following: I have a table populated with data from the DB. Apart from that, I have an input where you can write something and a button that will filter, only showing the lines that have that string. This is working now!
The thing is, the input should only allow you to filter by foo.name/foo.code (two propertys of my entity).
I'm adding the code I have in case anyone can guide me out, I've tried several things but this are my first experiences with JQuery while I have a strict story-delivery time. Thanks everyone!
<tbody>
<c:forEach var="foo" items="${foo}">
<tr id = "fooInformation" class="mtrow">
<th id="fooName" scope="row">${foo.name}</th>
<td id="fooCode" class="left-align-text">${foo.code}</td>
<td class="left-align-text">${foo.country}</td>
<td class="left-align-text">${foo.region}</td>
<td class="left-align-text">${foo.subregion}</td>
</tr>
</c:forEach>
</tbody>
$("#search").click(function () { -> button id
var value = $("#fooRegionSearch").val(); -> value of the input
var rows = $("#fooRegionTable").find("tr"); -> table id
rows.hide();
rows.filter(":contains('" + value + "')").show();
});
To start with, your HTML is invalid - there cannot be elemenets with duplicate IDs in HTML. Use classes instead of IDs.
Then, you need to identify which TRs pass the test. .filter can accept a callback, so pass it a function which, given a TR, selects its fooName and fooCode children which contain the value using the :contains jQuery selector:
$("#search").click(function() {
var value = $("#fooRegionSearch").val();
var rows = $("#fooRegionTable").find("tr");
rows.hide();
rows.filter(
(_, row) => $(row).find('.fooName, .fooCode').filter(`:contains('${value}')`).length
).show();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="fooRegionTable">
<tr id="fooInformation" class="mtrow">
<th class="fooName" scope="row">name1</th>
<td class="fooCode" class="left-align-text">code1</td>
<td class="left-align-text">${foo.country}</td>
<td class="left-align-text">${foo.region}</td>
<td class="left-align-text">${foo.subregion}</td>
</tr>
<tr id="fooInformation" class="mtrow">
<th class="fooName" scope="row">name2</th>
<td class="fooCode" class="left-align-text">code2</td>
<td class="left-align-text">${foo.country}</td>
<td class="left-align-text">${foo.region}</td>
<td class="left-align-text">${foo.subregion}</td>
</tr>
</table>
<button id="search">click</button><input id="fooRegionSearch" />

Loop for object n HTML

My code is quite simple. I only want to add John and Marie to my table.
Works great but my issue is if there is no John and Marie I want to create a row and show a - in my td.
How do I know if there was not added any row when the ng-repeat ends?
<tr class="text-center" ng-if="name == 'John' || name == 'Marie'" ng-repeat="name in vm.names track by $index">
<td>{{name}}</td>
</tr>
Use the ng-switch directive:
<tr class="text-center" ng-switch"name" ng-repeat="name in vm.names track by $index">
<td ng-switch-when="John">{{name}}</td>
<td ng-switch-when="Marie">{{name}}</td>
<td ng-switch-when="Paul">{{name}}</td>
<td ng-switch-default>-</td>
</tr>
You could map your original object in the controller with something like this:
this.names = this.names.map(name => {
name ? name : '-';
})

AngularJs: uncheck checkbox after item is removed

after spending a lot of time on this simple issue and having made a lot of research, I was wondering if someone could give me some help.
I have data which is generated inside of a table like so:
<tbody>
<tr class="odd gradeX" ng-repeat="user in ctrl.datas | orderBy:ctrl.sortType:ctrl.sortTypeReverse">
<td>
<input type="checkbox" class="checkboxes" value="{{user.id}}" ng-click="ctrl.addItem(user)"/>
</td>
<td>
{{user.given_name}}
</td>
<td>
{{user.family_name}}
</td>
<td>
{{user.email}}
</td>
<td class="center" ng-bind-html="ctrl.convertToDate(user.created_at) | date: 'dd-MMMM-yyyy hh:mm'"></td>
<td>
<span class="btn blue-hoki"> Details </span>
</td>
</tr>
</tbody>
Above is a container where I get the items selected via a checkbox, add the in an array and give the user the ability to delete the selected item:
<tr ng-repeat="user in ctrl.checkedObject track by $index" ng-show="user.id">
<td>{{user.family_name}}</td>
<td>{{user.given_name}}</td>
<td>
<button class="btn blue" ng-click="ctrl.removeItem($index)">Unselect</button>
</td>
</tr>
In my controller, here are the two functions used to do so:
this.checkedObject = [];
//Add selected user
this.addItem = function (user) {
self.checkedObject.push(user);
};
this.removeItem = function(obj){
delete self.checkedObject[obj];
};
What i'd like to achieve is to uncheck the corresponding checkbox if a user changes his selection.
The thing is, I have no idea how to target the corresponding checkbox. Does anyone have a clue?
Thanks in advance
Try ng-checked like:
<input type="checkbox" ng-checked="user !== null" class="checkboxes" value="{{user.id}}" ng-click="ctrl.addItem(user)"/>
And set the item (user) to null on button click (inside removeItem() ) or a other variable.
I set up a simple plunker to show one approach, which would be to assign a selected property to each user when his/her checkbox is checked, and set an ng-checked attribute on the checkbox corresponding to user.selected (so will be unchecked when false).
Using this approach you won't need to push and delete from the array of checkedUsers, you can just filter all the users by whether they are selected or not.
function getSelected() {
ctrl.checkedObject = _.filter(ctrl.datas, {selected: true});
}
ctrl.selectUser = function (user) {
user.selected = true;
getSelected();
};
ctrl.removeUser = function(user){
user.selected = false;
getSelected();
};

how to exchange date from one controller to another by using services in angularjs?

I want to get the selected data from the radio button and that particular data should be taken to that vote function and i need to view that data in another view or html by using the service.
How can i pass the values of selected attribute to another view using services?
Here is my code:
<body>
<table>
<tr id="$index" ng-repeat= "a in data ">
<td> {{a.condidateID}} </td>
<td> {{a.condidateName}} </td>
<td> {{a.territory}} </td>
<td> {{a.voteCount}} </td>
<td> <input type="radio" name="chickenEgg" value="egg" ng-model="chekratiovalue" ng-change="chengeEvnt($index)"></td>
</tr>
</table>
<button style="left: 40%;top: 40%;float: left;position: relative" ng-click="voteForPerson()">Vote</button
</body>
angular.module('Design')
.controller('MainCtrl',['profService',function($scope,profService) {
$scope.data = [{
condidateID:"1",
condidateName:"test",
territory:"APAC",
voteCount:"1",
chekratiovalue:"egg"
},
{
condidateID:"2",
condidateName:"test2",
territory:"APAC",
voteCount:"2",
chekratiovalue:"chicken"
}];
$scope.chengeEvnt = function(index) {
$scope.activeRow = index; // get the index when changing the radio button
var selected = $scope.data[$scope.activeRow]; // get the row of selected radio button using the `$scope.activeRow` function
}
$scope.voteForPerson = function() {
}
}]);

AngularJS, easy way to show a delete button when a checkbox is checked in the list of users under ng-repeat

I am trying to toggle a delete button which has already a function bound to it. The list is created with ng-repeat checking the users object. But the methds I have seen so far are either simple model show which does not work in my case. Or complex directive controller methods.
All I need is to check whether at least one checkbox is checked. Here is the snippet from the code:
<table class="table">
<tr ng-repeat="user in ctrl.commonUserService.users | filter:ctrl.commonUserService.suppressLoggedOnUserFilter()">
<td><input type="checkbox" ng-model="user.selected" value="y" /></td>
<td title="User Name"><strong>{{user.userName}}</strong></td>
How can I easily do this with Angular? I tried to create a function looping users and looking if they are selected at all but don't think I can put this function to ng-show.
You'll have to check if at least one box is selected when the state changes:
<td><input type="checkbox" ng-model="user.selected" ng-change="ctrl.userSelected()" value="y" /></td> <!-- use ng-change to notify when a checkbox is clicked -->
<button ng-click="ctrl.delete()" ng-show="ctrl.usersSelected">Delete</button> <!-- if ctrl.usersSelected is true show delete -->
In the controller:
this.userSelected = function userSelected() { // when checkbox is clicked check users to see if at least one is selected and save the state in this.userSelected
this.usersSelected = this.commonUserService.users.some(function(user) {
return user.selected;
});
};
You can do this fairly easily using the ng-change directive on your inputs. See this plunkr for the working example, but it basically goes like this:
View:
<table class="table">
<tr ng-repeat="user in users">
<td><input type="checkbox" ng-change="isSelected()" ng-model="user.selected" /></td>
<td title="User Name"><strong>{{user.userName}}</strong></td>
</tr>
</table>
<button class="delete" ng-show="showDelete">Delete</button>
Controller:
$scope.isSelected = function() {
var somethingSelected = false;
$scope.users.forEach(function(user, index) {
if (user.selected) somethingSelected = true;
});
$scope.showDelete = somethingSelected;
};

Categories

Resources