How to assign reassign checkbox ng-model on ng-repeat - javascript

Please help me out. I have a checkboxes with models defined. I am displaying checkboxes and using the model to set if the checkbox is selected or not. Below is the code for setting the ng-model.
LoadValues(obj) {
vm.index = false;
vm.create = false;
vm.edit = false;
vm.delete = false;
vm.other = false;
var pList = obj.Functions;
var currentModule = obj.Name;
for (var i = 0; i < pList.length; i++) {
var currentItem = pList[i];
console.log(currentItem)
if (currentItem.search("Index") > 0) {
vm.index = true;
console.log(vm.index);
} else if (currentItem.search("Create") > 0) {
vm.create = true;
} else if (currentItem.search("Edit") > 0) {
vm.edit = true;
} else if (currentItem.search("Delete") > 0) {
vm.delete = true;
} else if (currentItem.search("Other") > 0) {
vm.other = true;
}
}
}
Below is the check boxes.
<tbody>
<tr ng-repeat="item in list">
<td>
{{item.Name}}
</td>
<td>
<input id="Index" type="checkbox" ng-model="vm.index" ng-click="EditRole(Right,item.Module,'Index')">
</td>
<td>
<input id="Create" type="checkbox" ng-model="vm.create" ng-click="EditRole(item.Role,'Create')">
</td>
<td>
<input id="Edit" type="checkbox" ng-model="vm.edit" ng-click="EditRole(item.Role,item.Module,'Edit')">
</td>
<td>
<input id="Delete" type="checkbox" ng-model="vm.delete" ng-click="EditRole(item.Role,item.Module,'Delete')">
</td>
<td>
<input id="Other" type="checkbox" ng-model="vm.other" ng-click="EditRole(item.Role,item.Module,'Other')">
</td>
</tr>
</tbody>
The problem is it assigns the same ng-model to all the items in the list. I have tried to find solutions nothing is helping. Your help would be very much appreciated.
i am reading my data from a json file. Below is some example data:
[
{"Role":"Staff","Admins":[{"Name":"Username","userRights":["UserEdit","UserCreate"]
}]

The easiest way to use ng-model on a checkbox is to pass it an abject. The code below converts an array of items into an object for the checkboxes.
I created a variable called $scope.userRights which contains all of the available options.
In the HTML we loop though each field displaying its name and then loop though all of the userRights.
The submit button then converts the object back into the array format we received.
HTML
<div ng:controller="MainCtrl">
<button ng-click="submit()">Submit</button>
<table>
<tr ng-repeat="field in fields">
<td ng-bind="field.Name"></td>
<td ng-repeat="right in userRights">
<label>
<input type="checkbox" ng-model="field.userRights[right]" /> {{right}}
</label>
</td>
</tr>
</table>
<pre ng-bind="fields | json"></pre>
</div>
JavaScript
app.controller('MainCtrl', function($scope) {
$scope.userRights = ["UserEdit","UserCreate","UserSomethingElse"];
$scope.fields = [
{"Name":"Username","userRights":["UserEdit","UserCreate"]},
{"Name":"Password","userRights":["UserEdit"]}
];
// Convert array to object
$scope.fields.forEach(function(field) {
var res = {};
field.userRights.forEach(function(right) {
res[right] = true;
});
field.userRights = res;
});
function objectValues(obj) {
var res = [];
var keys = Object.keys(obj);
for (var i=0; i<keys.length; i++) {
if (obj[keys[i]]) res.push(keys[i]);
}
return res;
}
// Convert object to array
$scope.submit = function() {
$scope.fields.forEach(function(field) {
field.userRights = objectValues(field.userRights);
});
};
});
Demo

Your ng-model has to be like so:
ng-model="item.index"
And then in your controller inside the for loop:
current_item.index = true;
Hope it helps =)

Related

Checklist-model in Angular usage

i have departments as a title and employees as a subtitle. what i want to do is when the user check the title or department all employees or subtitles should be checked. i am using fieldset and table in html and ng-repeat. it looks like this issue but the main differ is getting data from db Angular checklist-model checkboxes with reverse action
i cannot find what i miss. any idea any help. thanks .
The HTML
<fieldset id="field3">
<table>
<tr ng-repeat="emp in empdepts | groupBy:'dep_LDesc'">
<td>
<label ng-click="showContent = !showContent"></label>
<details ng-open="showContent">
<summary> <input type="checkbox" class="test" ng-model="check_all_domains" ng-click="toggle_select_all()" /> {{emp[0].dep_LDesc}}</summary>
<div ng-repeat="semployee in emp" class="test">
<input type="checkbox" checklist-model="objects_selected" checklist-value="semployee">
{{semployee.Sname}}<div style="display:none;">{{semployee.staffkey}}{{semployee.depkey}}</div>
</div>
</details>
</td>
</tr>
</table>
</fieldset>
The Controller
/// <reference path="Scripts/angular.js" />
///
///
Assign.controller("AssignController", function ($scope, Assignments) {
Loaddepts();
function Loaddepts()
{
Assignments.getdepts().then (function(response){
$scope.depts = (response.data);
console.log($scope.depts);
})
}
//$scope.employees = [];
//$scope.checked = { employees: ['semployee'] }
//$scope.checkAll = function () {
// $scope.checked.employees = angular.copy($scope.employees);
//};
//$scope.uncheckAll = function () {
// $scope.checked.employees = [];
//};
//$scope.emp = $scope.empdepts;
$scope.objects_selected = [];
$scope.check_all_domains = false;
$scope.toggle_select_all = function () {
$scope.objects_selected = true;
//$scope.check_all_domains = true;
//$scope.objects_selected = angular.copy($scope.emp);
//angular.copy($scope.emp, $scope.objects_selected);
};
LoadEmpDepts();
function LoadEmpDepts()
{
Assignments.getempdepts().then (function (response){
$scope.empdepts = (response.data);
console.log($scope.empdepts);
})
}
$scope.selectedRow1 = null; // initialize our variable to null
$scope.setClickedRow1 = function (employee) { //function that sets the value of selectedRow to current index
$scope.selectedRow1 = employee;
}
$scope.save = function()
{
}
});
}
Thanks in advance
<table>
<tr ng-repeat="e in empdepts | groupBy:'dep_LDesc'">
<td>
<label ng-click="showContent = !showContent"></label>
<details ng-open="showContent">
<summary><input type="checkbox" ng-model="chk" /> {{e[0].dep_LDesc}}</summary>
<div ng-repeat="employee in e">
<input type="checkbox" ng-checked="chk"> {{employee.Sname}}
</div>
</details>
</td>
</tr>
</table>

Angular custom sort with multiple parameters and random value

I know various variations of this have been asked multiple times before, but nevertheless I am having trouble with it. I have a small angular app wherein I am comparing two characters (it's a D&D initiative roll). I am looking to sort the ng-repeat in the following code:
var dmTools = angular.module('dmTools', []);
dmTools.controller('initTracker', function($scope, $http) {
var charInit = function() {
this.name = "";
this.mod = 0;
this.init = 0;
}
$scope.characters = [
];
$scope.character = new charInit();
$scope.addChar = function() {
$scope.characters.push($scope.character);
$scope.character = new charInit();
}
$scope.deleteChar = function(character) {
$scope.characters.splice($scope.characters.indexOf(character), 1);
}
$scope.charSort = function(a, b) {
//first we go by initiative roll
if (a.init < b.init) {
return -1;
}
if (a.init > b.init) {
return 1;
}
//if initiative rolls are the same, go by initiative mod
if (a.mod < b.mod) {
return -1;
}
if (a.mod > b.mod) {
return 1;
}
//if both are the same, roll off until one gets a higher roll than the other.
var aRoll = 0;
var bRoll = 0;
while (aRoll == bRoll) {
aRoll = Math.floor(Math.random() * 20) + 1;
bRoll = Math.floor(Math.random() * 20) + 1;
if (aRoll < bRoll) {
return -1;
}
if (aRoll > bRoll) {
return 1;
}
}
//while this should not be possible to reach, we'll put it in for safeties sake.
return 0;
};
$scope.rollInit = function() {
for (x in $scope.characters) {
$scope.characters[x].init = Math.floor(Math.random() * 20) + 1 + $scope.characters[x].mod;
}
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div class="app" id="initTracker" data-ng-controller="initTracker">
<h3>Initiative Tracker</h3>
<div class="form-group">
<label>Name
<input type="text" data-ng-model="character.name" class="form-control" />
</label>
</div>
<div class="form-group">
<label>Mod
<input type="number" data-ng-model="character.mod" class="form-control" />
</label>
</div>
<div>
<input class="btn btn-primary" style="margin:5px;" data-ng-click="addChar()" type="button" value="Add Character" />
<input class="btn btn-success" style="margin:5px;" data-ng-click="rollInit()" type="button" value="Roll Initiative" />
</div>
<table class="table table-striped">
<tr>
<th>Name</th>
<th>Modifier</th>
<th>Initiative</th>
<th>Delete</th>
</tr>
<tr data-ng-repeat="character in characters | orderBy: charSort">
<td data-ng-bind="character.name"></td>
<td data-ng-bind="character.mod"></td>
<td data-ng-bind="character.init"></td>
<td>
<input type="button" class="btn btn-danger" value="Delete" data-ng-click="deleteChar(character)" />
</td>
</tr>
</table>
</div>
My charSort function is a working sort that could easily be passed to an array.sort(function) sort of call, but angular is only passing in 1 character object to the function. How can I get a proper custom comparison based sort of this variety in an angular template?
Do you need to sort the array in the data-ng-repeat? You could just sort the array in rollInit().
If anything changes the array with inserts or deletes, you could $watchCollection on the array and re-sort as things are added or removed.
Then you can do any kind of sorting you like in Javascript, and the data-ng-repeat will always see the data in the correct order.
if you have three property for an object , you can sort them in priority of property A , property B and property C like below
<tr data-ng-repeat="character in characters | orderBy:['A','B','C']">

push increment item into an array in Angularjs

http://plnkr.co/edit/NDTgTaTO1xT7bLS1FALN?p=preview
<button ng-click="addRow()">add row</button>
<div ng-repeat="row in rows">
<input type="text" placeholder="name"><input type="tel" placeholder="tel">
</div>
I want to push new row and save all the fields but now I'm stuck at adding new rows. How to know the current number of row and do increment to push into the array?
Look at this example I created which allows you to generate up to eight unique input fields for Telephone and Text Entries.
var app = angular.module("MyApp", []);
app.controller("MyCtrl", function($scope) {
$scope.rows = [];
var Row = function(tel, text) {
// Private data
var private = {
tel: tel,
text: text
}
// Expose public API
return {
get: function( prop ) {
if ( private.hasOwnProperty( prop ) ) {
return private[ prop ];
}
}
}
};
$scope.addRow = function(){
if($scope.rows.length < 8){
var newItemNum = $scope.rows.length + 1;
var row = new Row('item' + newItemNum, 'item' + newItemNum);
$scope.rows.push(row);
}
};
$scope.saveAll = function(){
// $scope.result = 'something';
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="MyApp">
<div ng-controller="MyCtrl">
<h2>Setting</h2>
<button ng-click="addRow()">Add Row</button>
<br />
<div ng-repeat="row in rows">
<input type="text" placeholder="Text" ng-model="row.textModel" >
<input type="tel" placeholder="Phone" ng-model="row.telModel" >
</div>
<br />
{{rows}}
</div>
</div>
Move functions inside controller 'Ctrl'.
In your script:
function Ctrl($scope) {
$scope.result = "something";
$scope.rows = ['1'];
$scope.addRow = function(){
if ($scope.rows.length < 8) {
$scope.rows.push($scope.rows.length + 1);
}
}
$scope.saveAll = function(){
// $scope.result = 'something';
}
}

knockout automatically presses button after updating view

I have a table with TRbind in foreach loop:
<tbody data-bind="foreach: data">
<tr>
<td><input type="text" class="form-control" data-bind="value: DeviceSerialNumber" required /></td>
<td><input type="datetime" class="form-control datepicker" placeholder="Od" data-bind="value: StartDate" required /></td>
<td><button class="btn btn-default" data-bind='click: $root.removeRow'>Delete</button></td>
</tr>
</tbody>
the button is bind to this function:
self.removeRow = function (eq) {
self.data.removeAll([eq]);
};
I add data in this way:
var a = new Eq();
console.log(self);
a.StartDate(self.StartDateTemp());
a.DeviceId(self.DeviceTemp());
console.log(a);
console.log(self.data().length);
self.data.push(a);
console.log(self.data().length);
and data is:
var ViewModel = function () {
var self = this;
self.DeviceTemp = ko.observable();
self.StartDateTemp = ko.observable();
self.data = ko.observableArray([]);
}
The problem is occurring only in IE10. If I add anything to the data array the view is Updated. As in the view I add the is button bind to remove at the end of the tr. For unknown reason knockout or browser clicks that button and removes freshly added row.
Can You help me?
JSFIDDLE
Try adding return false after self.data.push(a); self.Test(""); to prevent event from bubbling:
self.searchKeyboardCmd = function (data, event) {
if (event.keyCode == 13) {
if ((self.StartDateTemp() === undefined)
|| (self.number() != 1 && self.Test() != undefined)
&& (self.number() != 1 && self.Test() != "")) {
alert("Bledna konfiguracja. Urzadzenia posiadajace numer seryjny nie moga byc dodane wiecej niz 1 raz")
return true;
}
if (self.number() < 1 || isNaN(self.number())) {
alert("Bledna ilosc");
return true;
}
var a = new Eq();
a.StorageId(self.StorageTemp());
a.StartDate(self.StartDateTemp());
a.DeviceSerialNumber(self.Test());
a.DeviceId(self.DeviceTemp());
a.Issue(self.Issue())
a.IssueDesc(self.IssueDesc());
a.Quantity(self.number());
a.Project(self.Project());
a.MeUser(self.MeUser());
self.data.push(a);
self.Test("");
return false;
}
return true;
};

JS validation for checkbox not working when put name []

I have an JS validation for checkbox.
function ActionCcdCheck (theForm)
{
if (theForm.ccd_chk.checked)
{
theForm.ccd_pos[0].className = 'part';
theForm.ccd_pos[1].className = 'part';
theForm.ccd_pos[2].className = 'part';
theForm.ccd_pos[0].disabled = false;
theForm.ccd_pos[0].checked = false;
theForm.ccd_pos[1].disabled = false;
theForm.ccd_pos[1].checked = false;
theForm.ccd_pos[2].disabled = false;
theForm.ccd_pos[2].checked = false;
}
else
{
theForm.ccd_pos[0].disabled = true;
theForm.ccd_pos[1].disabled = true;
theForm.ccd_pos[2].disabled = true;
}
}
The checkbox
<td colspan="1" rowspan="2" width="35">CCD</td>
<td>Check</td>
<td><input type="checkbox" name="ccd_chk" value="yes" class="part" onclick="ActionCcdCheck (this.form);" onkeypress="FocusChange (this.form, 5, 4);"/> Yes</td>
<tr>
<td>Position</td>
<td>
<input type="checkbox" name="ccd_pos[]" value="front" class="part" onkeypress="FocusChange (this.form, 6, 3);"/> Front
<input type="checkbox" name="ccd_pos[]" value="back" class="part" onkeypress="FocusChange (this.form, 7, 2);"/> Back
<input type="checkbox" name="ccd_pos[]" value="fb" class="part" onkeypress="FocusChange (this.form, 8, 1);"/> FB
</td>
<tr>
Now I am facing problem when I put checkbox name like this name="ccd_pos[]". The JS validation not working. I use that because I want to submit multiple value of checkbox.
So anyone can give me an suggestions ? Thanks.
In your code:
theForm.ccd_pos[0]
is looking for a ccd_pos property of the form, there isn't one. What you need is something like:
theForm['ccd_pos[]'][0]
as form controls with the same name will be returned as a collection, so:
theForm['ccd_pos[]']
returns a collection of the three controls with name ccd_pos[]. Then use normal index names to access the various members of the collection.
Note that in javascript, dot notation is a shortcut to formal property access and can only be used where the name is complies with the rules for identifiers. Otherwise, you must use square bracket (formal) notation.
So your code can be something like:
var box, boxes = theForm.['ccd_pos[]'];
for (var i=0, iLen=boxes.length; i<iLen; i++) {
box = boxes[i];
if (theForm.ccd_chk.checked) {
box.className = 'part';
box.disabled = false;
box.checked = false;
} else {
box.disabled = true;
// and probably
box.className = '';
}
}

Categories

Resources