I am trying to get the of checkbox selected and store its result in an array . when the checkboxes are selected by default its not getting its value but after toggling if if a particular checkbox is selected its
working correctly.Please tell me what i am doing wrong and thanks in advance.
here my html code:
<div ng-repeat="album in albums" ng-disabled="checked">
<input type="checkbox" ng-model="album.selected" value={{album.value}} ng-checked = "true"/> {{album.name}}
</div>
<button ng-click = "setAlbums()" type = "submit" class = "col-sm-3 btn btn-primary" style = "margin-left:3%;"> Save </button>
here my js code:
$scope.albums = [{
value: 3,
name: 'a'
},
{
value: 4,
name: 'b'
},
{
value: 5,
name: 'c'
},
{
value: 6,
name: 'd'
},
{
value: 7,
name: 'd'
},
{
value: 8,
name: 'e'
},
{
value: 9,
name: 'f'
}];
$scope.setAlbums = function () {
$scope.albumNameArray = [];
angular.forEach($scope.albums, function(album){
if (album.selected) $scope.albumNameArray.push(album.value);
});
console.log("$scope.albumNameArray",$scope.albumNameArray)
}
Initially while ng-repeat is rendering the array it will look for the album.selected value in the array itself, so if its not able to find it, it will be virtually checked due to your ng-checked = true attribute but it will not be set in the ng-model, so
try it like this, use a another property called ng-init = "album.selected = true" in,
<input type="checkbox" ng-model="album.selected" value="{{album.value}}" ng-checked="true" ng-init="album.selected = true"/>
then try with the save button click.
PLUNKER WITH YOUR CODE
Related
I have developing some code in Angular JS and i need to disable radio button based on previous selection or change in text box
in JS controller:
PPCO.cusGender = [ {
id : '1',
key : 'Male',
value : 'Male',
disable:false
}, {
id : '2',
key : 'Female',
value : 'Female',
disable:false
}, {
id : '3',
key : 'TG',
value : 'TG',
disable:false
}];
PPCO.changeapplicant = function() {
switch (PPCO.p_SALUTATION.toLowerCase().trim()) {
case 'mrs.':
case 'miss.':angular.forEach(PPCO.cusGender, function(val, key) {
if(val.key != 'Male')
{
val.disable = false;
}
});
break;
}
};
in HTML:
<input type="text" ng-model="PPCO.changeapplicant" class="color" ng-change="PPCO.changeapplicant()">
<label class="radio" ng-repeat="option in PPCO.cusGender">
<input type="radio" name="gender"
ng-model="PPCO.cusgendername" value="{{option.value}}"
ng-disabled="option.disable">
<i></i>
</label>
My question is i able change the "ng-disabled =true" value but it is not enabling again. How to make that
I have created this plnkr for this case: https://plnkr.co/edit/F4JZcf6Nm5Csbxbg
I think you have 2 errors happening at the same time:
You're iterating over one array. So, you don't need to use angular.forEach, you can use array.forEach
Also, most important, you're setting false when the element is mrs. or miss. and it's ok. BUT, you're not setting back to true. So, you will have to include one else clause like this:
if (['mrs.', 'miss.'].includes($scope.applicant.toLowerCase().trim())) {
$scope.cusGender.forEach(function(element) {
element.disable = element.key == 'Male';
});
} else {
$scope.cusGender.forEach(function(element) {
element.disable = false;
});
}
I think that would be all!
I am new to angular so forgive me if I use the incorrect terminology! I would also prefer any solutions using the latest Angular version if possible :-) I have some fairly complex use cases.
One of these is a customer edit screen. I have already built the list page and customer details forms, this works well. This also posts back some JSON. I have removed this from my example.
Something that a user must set is a customers stages which can be multiple. Therefore i will use checkboxes.
What I do is load the current user into the scope, then modify its values. then save to a web service. However i have some complex properties and figuring out how to bind these is problematic.
i found this example here which i can get to work if i put the options on my controller directly (shown in code)
http://plnkr.co/edit/cqsADe8lKegsBMgWMyB8?p=preview
however I cannot bind the check boxes on the currentUser.pipe properties. Any help would be greatly appreciated!
kind regards
jim
//our object definitions are here
function User(Firstname, Lastname, Id) {
this.Firstname = Firstname;
this.Lastname = Lastname;
this.PersonId = Id;
this.uuid = "OG6FSDHG6DF86G89DSHGDF8G6";
//hold the customers source
this.source = 2;
//these are used to populate our selection boxes
this.pipe = new Object();
//PROBLEM CODE IS HERE
//I WOULD LIKE TO OUTPUT A CHECKBOX FOR EACH ITEM AND THEN UPDATE THE SELECTED VALUE WHEN A USER CLICK IT
this.pipe.stages = [
{ id: 1, text: 'STAGE 1', selected: true },
{ id: 2, text: 'STAGE 2', selected: false },
{ id: 3, text: 'STAGE 3', selected: true },
{ id: 4, text: 'STAGE 4', selected: false }
];
this.getFullName = function () {
return this.Firstname + " " + this.Lastname + " " + Id;
};
}
function UserController($scope) {
//called to populate the customers list
$scope.populateCustomers = function () {
//this will be populated form the server. I have extra code which allows th euser ot select the customer and edit it and this works fine.
//I have removed the superflous code
$scope.userList = [
new User("John", "Doe", 1),
new User("Henri", "de Bourbon", 2),
new User("Marguerite", "de Valois", 3),
new User("Gabrielle", "d'Estrées", 4)
];
};
$scope.populateCustomers();
// the currentUser pobject is loaded by the user and modified. This works fine
$scope.currentUser = $scope.userList[0];
//if i add the stages here i can get them to update however these are different for each
//customer and would like the state to be held accordingly
$scope.stages = [
{ id: 1, text: 'STAGE 1', selected: true },
{ id: 2, text: 'STAGE 2', selected: true },
{ id: 3, text: 'STAGE 3', selected: true },
{ id: 4, text: 'STAGE 4', selected: true }
];
}
Here are the templates i have used. This one works off scope.stages
stages from scope.stages<br />
<label ng-repeat="stage in stages">
<input type="checkbox" value="{{stage.name}}" ng-model="stage.selected">{{stage.name}}
</label>
<p>stages: {{stages}}</p>
And this is what i would like to do however it shows the check boxes but doesnt bind correctly.
stages from currentUser.pipe.stages<br />
<label ng-repeat="stage in currentUser.pipe.stages">
<input type="checkbox" value="{{stage.name}}" ng-model="stage.selected">{{stage.name}}
</label>
<p>stages: {{stages}}</p>
Everything works perfectly. I think you have print the wrong variable in the currentUser.pipe.stages template. It will be <p>stages: {{currentUser.pipe.stages}}</p>.
stages from currentUser.pipe.stages<br />
<label ng-repeat="stage in currentUser.pipe.stages">
<input type="checkbox" value="{{stage.name}}" ng-model="stage.selected">{{stage.name}}
</label>
<!-- Print currentUser.pipe.stages -->
<p>stages: {{currentUser.pipe.stages}}</p>
See this PLUNKER. Its binding properly.
Here is my data
This.dynamicCmb = [{
id: 1,
label: 'aLabel',
subItem: ['aSubItem1','aSubItem2','aSubItem3']
}, {
id: 2,
label: 'bLabel',
subItem: [ 'bSubItem' ]
}];
I want to display 'subItem' data depending on the value I give i.e, either id or label. if I search any one it should display value.
<input type="text" ng-model="vm.selectedColumn" /> //Textbox to take either id or name value
<input type="button" value="Get" ng-click="GetCmbValue()" /> //On click of button it should load dropdown
<select ng-options="item.name for item in vm.selectedColumn.subItem" ng-model="vm.selected"></select>
.js file
This.GetCmbValue = function () {
// I should load drop down value here
};
for eg: if I give '1' in textbox then subItem of '1' should display. If I give 'alabel' in textbox then also subItem of 'alabel' should display. It should search either on id or label whatever I give. Please help me to do this
You can attach filter to your ngOption. So that every time you type value in textbox, it will filter data accordingly.
We bind the output of textbox to the filter.
.js file
app.filter('itemFilter', function() {
return function(input,val) {
var out = new Array();
angular.forEach(input, function(item) {
if (item.id == val || item.label == val) {
out = out.concat(item.subItem);
}
});
return out;
};
});
HTML File
<input type="text" data-ng-model="val">
<select data-ng-options="item for item in dynamicCmb | itemFilter : val" data-ng-model="selected"></select>
change your select code by this
<select ng-options="item.name for item in vm.selectedColumn.subItem|filter:{Id:vm.selectedColumn}" ng-model="vm.selected"></select>
I have a AngularJS directive that allows users to select a values from a list to filter on. Pretty simple concept which is represented here:
Problem is when I click one of the checkboxes they all select unintended. My directive is pretty simple so I'm not sure why this is happening. The code around the selection and checkboxes is as follows:
$scope.tempFilter = {
id: ObjectId(),
fieldId: $scope.available[0].id,
filterType: 'contains'
};
$scope.toggleCheck = function (id) {
var values = $scope.tempFilter.value;
if (!values || !values.length) {
values = $scope.tempFilter.value = [];
}
var idx = values.indexOf(id);
if (idx === -1) {
values.push(id);
} else {
values.splice(idx, 1);
}
};
$scope.valuesListValues = function (id) {
return $scope.available.find(function (f) {
return f.id === id;
}).values;
};
and the data resembles:
$scope.available = [{
id: 23,
name: 'Store'
values: [
{ id: 124, name: "Kansas" },
{ id: 122, name: "Florida" }, ... ]
}, ... ]
the view logic is as follows:
<ul class="list-box">
<li ng-repeat="val in valuesListValues(tempFilter.fieldId)">
<div class="checkbox">
<label ng-click="toggleCheck(val.id)">
<input ng-checked="tempFilter.value.indexOf(val.id) === -1"
type="checkbox"> {{val.name}}
</label>
</div>
</li>
</ul>
First off, it toggleCheck fires twice but populates the correct data ( second time given my code it removes it though ).
After the second fire, it checks all boxes... Any ideas?
Perhaps its that the local variable doesn't get reassigned to the property of the scope property used in the view. Since your values are then non-existent and not found, the box is checked.
$scope.tempFilter.value = values
I took the interface concept you were after and created a simpler solution. It uses a checked property, found in each item of available[0].values, as the checkbox model. At the top of the list is a button that clears the selected items.
JavaScript:
function DataMock($scope) {
$scope.available = [{
id: 23,
name: 'Store',
values: [{
id: 124,
name: "Kansas"
}, {
id: 122,
name: "Florida"
}]
}];
$scope.clearSelection = function() {
var values = $scope.available[0].values;
for (var i = 0; i < values.length; i++) {
values[i].checked = false;
}
};
}
HTML:
<body ng-controller="DataMock">
<ul class="list-box">
<li>
<button ng-click="clearSelection()">Clear Selection</button>
</li>
<li ng-repeat="val in available[0].values">
<div class="checkbox">
<label>
<input ng-model="val.checked"
type="checkbox" /> {{val.name}}
</label>
</div>
</li>
</ul>
</body>
Demo on Plunker
The repeat that I used to grab the values based on the id, was the problem area.
<li ng-repeat="val in valuesListValues(tempFilter.fieldId)">
removing that and simple listening and setting a static variable resolved the problem.
$scope.$watch('tempFilter.fieldId', function () {
var fId = $scope.tempFilter.fieldId;
if ($scope.isFieldType(fId, 'valuesList')) {
$scope.valuesListValues = $scope.valuesListValues(fId);
}
}, true);
});
and then in the view:
ng-repeat="value in valuesListValues"
Is there any function or ng-something to check if any of the displayed Checkboxes are checked?
I have the values through the ng-click="function()" and pass the values through. I can go by foot and check my array if any value is inside.
I want to activate/deactivate the "next"-button if any Checkbox is
checked.
What's the easiest way?
If you don't want to use a watcher, you can do something like this:
<input type='checkbox' ng-init='checkStatus=false' ng-model='checkStatus' ng-click='doIfChecked(checkStatus)'>
You can do something like:
function ChckbxsCtrl($scope, $filter) {
$scope.chkbxs = [{
label: "Led Zeppelin",
val: false
}, {
label: "Electric Light Orchestra",
val: false
}, {
label: "Mark Almond",
val: false
}];
$scope.$watch("chkbxs", function(n, o) {
var trues = $filter("filter")(n, {
val: true
});
$scope.flag = trues.length;
}, true);
}
And a template:
<div ng-controller="ChckbxsCtrl">
<div ng-repeat="chk in chkbxs">
<input type="checkbox" ng-model="chk.val" />
<label>{{chk.label}}</label>
</div>
<div ng-show="flag">I'm ON when band choosed</div>
</div>
Working: http://jsfiddle.net/cherniv/JBwmA/
UPDATE: Or you can go little bit different way , without using $scope's $watch() method, like:
$scope.bandChoosed = function() {
var trues = $filter("filter")($scope.chkbxs, {
val: true
});
return trues.length;
}
And in a template do:
<div ng-show="bandChoosed()">I'm ON when band choosed</div>
Fiddle: http://jsfiddle.net/uzs4sgnp/
If you have only one checkbox, you can do this easily with just ng-model:
<input type="checkbox" ng-model="checked"/>
<button ng-disabled="!checked"> Next </button>
And initialize $scope.checked in your Controller (default=false). The official doc discourages the use of ng-init in that case.
Try to think in terms of a model and what happens to that model when a checkbox is checked.
Assuming that each checkbox is bound to a field on the model with ng-model then the property on the model is changed whenever a checkbox is clicked:
<input type='checkbox' ng-model='fooSelected' />
<input type='checkbox' ng-model='baaSelected' />
and in the controller:
$scope.fooSelected = false;
$scope.baaSelected = false;
The next button should only be available under certain circumstances so add the ng-disabled
directive to the button:
<button type='button' ng-disabled='nextButtonDisabled'></button>
Now the next button should only be available when either fooSelected is true or baaSelected is true and we need to watch any changes to these fields to make sure that the next button is made available or not:
$scope.$watch('[fooSelected,baaSelected]', function(){
$scope.nextButtonDisabled = !$scope.fooSelected && !scope.baaSelected;
}, true );
The above assumes that there are only a few checkboxes that affect the availability of the next button but it could be easily changed to work with a larger number of checkboxes and use $watchCollection to check for changes.
This is re-post for insert code also.
This example included:
- One object list
- Each object hast child list.
Ex:
var list1 = {
name: "Role A",
name_selected: false,
subs: [{
sub: "Read",
id: 1,
selected: false
}, {
sub: "Write",
id: 2,
selected: false
}, {
sub: "Update",
id: 3,
selected: false
}],
};
I'll 3 list like above and i'll add to a one object list
newArr.push(list1);
newArr.push(list2);
newArr.push(list3);
Then i'll do how to show checkbox with multiple group:
$scope.toggleAll = function(item) {
var toogleStatus = !item.name_selected;
console.log(toogleStatus);
angular.forEach(item, function() {
angular.forEach(item.subs, function(sub) {
sub.selected = toogleStatus;
});
});
};
$scope.optionToggled = function(item, subs) {
item.name_selected = subs.every(function(itm) {
return itm.selected;
})
$scope.txtRet = item.name_selected;
}
HTML:
<li ng-repeat="item in itemDisplayed" class="ng-scope has-pretty-child">
<div>
<ul>
<input type="checkbox" class="checkall" ng-model="item.name_selected" ng-click="toggleAll(item)"><span>{{item.name}}</span>
<div>
<li ng-repeat="sub in item.subs" class="ng-scope has-pretty-child">
<input type="checkbox" kv-pretty-check="" ng-model="sub.selected" ng-change="optionToggled(item,item.subs)"><span>{{sub.sub}}</span>
</li>
</div>
</ul>
</div>
<span>{{txtRet}}</span>
</li>
Fiddle: example
I've a sample for multiple data with their subnode
3 list , each list has attribute and child attribute:
var list1 = {
name: "Role A",
name_selected: false,
subs: [{
sub: "Read",
id: 1,
selected: false
}, {
sub: "Write",
id: 2,
selected: false
}, {
sub: "Update",
id: 3,
selected: false
}],
};
var list2 = {
name: "Role B",
name_selected: false,
subs: [{
sub: "Read",
id: 1,
selected: false
}, {
sub: "Write",
id: 2,
selected: false
}],
};
var list3 = {
name: "Role B",
name_selected: false,
subs: [{
sub: "Read",
id: 1,
selected: false
}, {
sub: "Update",
id: 3,
selected: false
}],
};
Add these to Array :
newArr.push(list1);
newArr.push(list2);
newArr.push(list3);
$scope.itemDisplayed = newArr;
Show them in html:
<li ng-repeat="item in itemDisplayed" class="ng-scope has-pretty-child">
<div>
<ul>
<input type="checkbox" class="checkall" ng-model="item.name_selected" ng-click="toggleAll(item)" />
<span>{{item.name}}</span>
<div>
<li ng-repeat="sub in item.subs" class="ng-scope has-pretty-child">
<input type="checkbox" kv-pretty-check="" ng-model="sub.selected" ng-change="optionToggled(item,item.subs)"><span>{{sub.sub}}</span>
</li>
</div>
</ul>
</div>
</li>
And here is the solution to check them:
$scope.toggleAll = function(item) {
var toogleStatus = !item.name_selected;
console.log(toogleStatus);
angular.forEach(item, function() {
angular.forEach(item.subs, function(sub) {
sub.selected = toogleStatus;
});
});
};
$scope.optionToggled = function(item, subs) {
item.name_selected = subs.every(function(itm) {
return itm.selected;
})
}
jsfiddle demo