I am trying to do something like tree-checkboxes.
I would like to add boolean to children of checked name : ex. after click checkbox at name : eva - all her childrens will be also checked.
Like that :
$scope.messages =
{
"family": [
{
"name": "eva",
"checked" : true,
"childrens": [
{
"name": "John",
"checked" : true,
"childrens": [
{
"name": "Jacob",
"checked" : true,
}
My code :
<div ng-repeat="key in messages">
<ul ng-repeat=" (x, y) in key" style="list-style:none;">
<li>
<input type="checkbox" ng-model="y.check" ng-change="changeValue(shapes, y.name)" /> {{y.name}} {{y.check}}</li>
<li style="margin-left:15px;" ng-repeat="(a,b) in y.childrens">
<input type="checkbox" ng-model="b.check" ng-change="changeValue(shapes, b.name)" /> {{b.name}} {{b.check}}
<ul style="margin-left:15px;" ng-repeat="p in b.childrens">
<li>
<input type="checkbox" ng-model="p.check" ng-change="changeValue(shapes, p.name)" /> {{p.name}} {{p.check}}</li>
</ul>
</li>
</ul>
</div>
Here is my plnkr : http://plnkr.co/edit/lFYUvcTt1W709vam5Dfv?p=preview
I forked your pinkr
As you can see, I update the childrens in the ng-change and this function is recursive so all childrens will be checked aswell
$scope.changeValue = function(foo, person) {
for(var i in person.childrens){
person.childrens[i].check = person.check;
$scope.changeValue(foo, person.childrens[i]);
}
};
If a person is checked, the children will be checked. If a child is check, it won't update the parent.
Related
I am working on angularjs application. Being a newbie facing issues when trying to get the below mentioned scenario.Any suggestions would be helpful.
I want to display one or two angular UI grid's based on the radio button selected at top. When user selects Show one Grid radio button and type Atlanta in From text field and Chicago in To text field and click on SearchLocations button the first angularjs ui grid should be displayed. Similarly when user selects Show two Grids radio button and type Atlanta in From and Chicago in To text field and click on SearchLocations button, two grids should be shown.
Please find the demo here.
HTML code:
<div>
<label>
Show one Grid <input type="radio" name="Passport" ng-click="ShowPassport('Y')" /></label>
<label>Show two Grids <input type="radio" name="Passport" ng-click="ShowPassport('N')" />
</label>
</div>
<div class="row">
<div class="form-group" ng-controller="citiesCtrl">
<label>From</label>
<input type="text" ng-model="places[0]" placeholder="Type Departure City" typeahead="item for item in items | filter:$viewValue | limitTo:8">
</div>
<div class="form-group" ng-controller="citiesCtrl">
<label>To</label>
<input type="text" ng-model="places[1]" placeholder="Type Destination City" typeahead="item for item in items | filter:$viewValue | limitTo:8">
</div>
</div>
<input type="button" value="SearchLocations" ng-click="submit()">
<div ng-repeat="user in users | filter: {name: searchValue} : true ">
<h3>First Grid</h3>
<div ui-grid="{ data: user.details }" ng-show="user.show" class="myGrid"></div>
</div>
<div ng-repeat="user in users | filter: {name: searchValue} : true ">
<h3>Second Grid</h3>
<div ui-grid="{ data: user.details }" ng-show="user.show" class="myGrid"></div>
</div>
js code:
angular.module('myApp', ['ngAnimate', 'ui.bootstrap','ngTouch', 'ui.grid', 'ui.grid.selection', 'ui.grid.edit','ui.grid.cellNav']);
angular.module('myApp').controller('citiesCtrl',function($scope){
// $scope. places = undefined;
$scope.items = ["Atlanta", "Chicago", "NewYork"];
$scope.selectAction = function() {
console.log($scope.places1);
};
});
/*Controller for searchLocations button*/
angular.module('myApp').controller('searchController', ['$scope', function($scope) {
$scope.places = ['', ''];
$scope.searchValue = '';
$scope.submit = function() {
if ($scope.places[0].length > 0 && $scope.places[1].length > 0) {
$scope.searchValue = $scope.places[0] + $scope.places[1];
}
};
$scope.users = [
{'name' : 'AtlantaChicago',
'show' : true,
'details' : [
{"Travel Date": "10/10/2014", commute:"Bus"},
{"Travel Date": "10/11/2014", commute:"flight"}]
},
{'name' : 'NewYorkChicago',
'show' : true,
'details': [
{"Travel Date": "3/15/2016", commute:"flight"},
{"Travel Date": "10/12/2016", commute:"flight"},
]
}
];
$scope.gridOptions = {
enableFiltering: true,
columnDefs: [
{ name: 'Travel Date', width: '5%'},
{ name: 'Departurecommute', enableFiltering: false, width: '12%' }
],
rowHeight: 20,
enableHorizontalScrollbar:2
};
}]);
You need to change few things in order to get it working as you expected.
If you want to display grids based on radio button selection:
1. you should assign ng-model and value to your radio buttons. Radio buttons in Angular
<label>
Show one Grid
<input type="radio" name="Passport" ng-model="Passport" value=1 ng-click="ShowPassport('Y')" />
</label>
<label>Show two Grids
<input type="radio" name="Passport" ng-model="Passport" value=2 ng-click="ShowPassport('N')" />
</label>
2.Assign the Passport value to another variable on button click. Show hide using Angular
$scope.submit = function() {
$scope.showGrid = $scope.Passport; //Here
if ($scope.places[0].length > 0 && $scope.places[1].length > 0) {
$scope.searchValue = $scope.places[0] + $scope.places[1];
}
};
3.Wrap your grids in a div and assign ng-show attribute
<div ng-show="showGrid==='1'||showGrid==='2'"> //first grid
<div ng-show="showGrid==='2'"> //second grid
4.Now it should work. See the Working plnkr
refer this sample code. you can easily understand
Sample Code
https://codepen.io/SusanneLundblad/pen/iBhoJ
I'm building a form of radio question types.
Here is code for view:
<div class="form-group" ng-class="{ 'has-error': form.$submitted && form[field.id].$invalid }" ng-if="field.type === 'radio'">
<label for="{{field.id}}">{{field.title}}</label>
<br>
<label ng-repeat="value in field.values">
<input type="radio" id="{{field.id}}" name="field.id" ng-model="formData[field.id]" value="{{value.title}}"> {{value.title}}</label>
<p class="form-group-note" ng-if="field.info" ng-bind="field.info"></p>
<div ng-show="form.$submitted" ng-cloack>
<span class="help-block" ng-show="form['{{field.id}}'].$error.required" ng-if="field.validations.required">Please enter a value, this field is required</span>
</div>
Selected Value is : {{formData[field.id]}}
</div>
JSON data I'm feeding is
{
"groups": [
{
"id": "4_2",
"title": "Passport",
"sections": [
{
"id": "4_2_section",
"fields": [
{
"id": "select_id",
"title": "Select type of question",
"type": "select",
"info": "Always select \"Yes\"",
"size": {
"width": 100,
"height": 1
},
"validations": {
"required": true
},
"values": [
{
"id": 0,
"title": "Not Selected"
},
{
"id": 1,
"title": "Yes"
},
{
"id": 2,
"title": "No"
}
]
}
]
The result I get for the radio questions is like following:
As you can see, all radio buttons are aligned horizontally.
How do I align them vertically?? I mean one radio button on one row.
Add a style to your HTML
.display-block {
display: block;
}
<label class="display-block" ng-repeat="value in field.values">
<input type="radio" id="{{field.id}}" name="field.id" ng-model="formData[field.id]" value="{{value.title}}"> {{value.title}}
</label>
Watch what you want to repeat.
<ul>
<li ng-repeat="value in field.values">
<label for="{{field.id}}"> {{value.title}}</label>
<input type="radio" id="{{field.id}}" name="field.id" ng-model="formData[field.id]" value="{{value.title}}">
</li>
</ul>
Wrap your inputs in ul, li. Below code will help for sure :
HTML:
<form name="myForm" ng-controller="MyCtrl">
<p>Favorite Beatle</p>
<ul>
<li ng-repeat="person in people">
<label>{{person.name}}
<input type="radio" ng-model="$parent.name" name="name" value="{{person.name}}" required />
</label>
</li>
</ul>
<p><tt>myForm.$invalid: {{myForm.$invalid}}</tt></p>
<button ng-disabled="myForm.$invalid">Submit</button>
</form>
JavaScript :
function MyCtrl($scope) {
$scope.people = [{
name: "John"
}, {
name: "Paul"
}, {
name: "George"
}, {
name: "Ringo"
}];
}
JsFiddle : https://jsfiddle.net/nikdtu/zp2131zw/
Using Angular JS, I have this object
var pages = [
{ name: 'users', title : "Users" },
{ name: 'roles', title : 'Roles' }
];
I'm trying to create a page for user roles. For that I need 4 checkboxes for each page. Each page must have 4 rules. Access, show, edit, delete.
Displaying pages in a ng-repeat
<div ng-controller='PageCtrl'>
<ul>
<li ng-repeat='page in pages'>
{{ page.title }}
<input type="checkbox" name="access"> Access
<input type="checkbox" name="show"> Show
<input type="checkbox" name="edit"> Edit
<input type="checkbox" name="delete"> Delete
</li>
</ul>
</div>
So I need to pass those checkboxes values to the $scope. How can I bind a model for each checkbox?
Like this
<input type="checkbox" name="access" ng-model='page.name+_access'> Access
Checkbox model name should start with page.name. Like users_access, users_show...
You can use the following syntax:
ng-model="page[page.name+'_access']"
But as a matter of fact, it looks one can move those groups into controller as well, then use another ng-repeat. Like this:
HTML:
<div ng-controller="PageCtrl">
<ul>
<li ng-repeat='page in pages'>{{ page.title }}
<label ng-repeat="right in rights">
<input type="checkbox" ng-model="page[page.name + '_' + right]" name="{{right}}" />{{right|capitalize}}</label>
<button ng-click="log(page)">Log</button>
</li>
</ul>
</div>
JS:
var module = angular.module('myAp', [])
.controller('PageCtrl', ['$scope', function ($scope) {
$scope.pages = [{
name: 'users',
title: "Users"
}, {
name: 'roles',
title: 'Roles'
}];
$scope.rights = ['access', 'show', 'edit', 'delete'];
$scope.log = function (page) {
console.log(page);
}
}]).filter('capitalize', function() {
return function (value) {
return value.charAt(0).toUpperCase() + value.slice(1);
};
});
Demo.
I have a list of items with a checkbox, and i have delete button. The delete only works if the item in the list is checked.
So for example i have
$scope.list = [{
name:'Groceries',
check: false
}, {
name:'Laundry',
check:false
},
{
name:'Cleaning',
check:false
}];
and in my HTML
<ul>
<li ng-repeat="values in list">
<input type="checkbox" ng-model="values.check"/>
<span>{{values.name}}</span>
</li>
</ul>
<button>Delete</button>
This is just the snippet of the code i have the controller declared and bootstrapped with ng-app
You should use Angular native directive ng-checked
<input type="checkbox" ng-checked="values.check"/>
You can use a filter for this:
HTML
<body ng-app="app" ng-controller='Ctrl'>
<ul>
<li ng-repeat="values in list">
<input type="checkbox" ng-model="values.check"/>
<span>{{values.name}}</span>
</li>
</ul>
<button ng-click="remove((list | filter:{check:true}))">Delete</button>
</body>
Controller
$scope.remove = function(items) {
alert('removing ' + items.length + ' items');
$scope.list = $filter('filter')($scope.list, { check: false});
}
Demo Plunker
<body ng-controller="MyController">
<ul>
<li ng-repeat="values in list">
<input type="checkbox" ng-model="values.check" />
<span>{{values.name}}</span>
</li>
</ul>
<button ng-click="deleteItems()">Delete</button>
</body>
controller:
myApp.controller('MyController', function($scope, $filter) {
$scope.list = [ {
name : 'Groceries',
check : false
}, {
name : 'Laundry',
check : false
}, {
name : 'Cleaning',
check : false
} ];
$scope.deleteItems = function() {
$scope.list = $filter('filter')($scope.list, {check : false})
}
})
I have a viewmodel in javascript that includes checkbox items.
Javascript is here:
var data = [
{"name": "Computers",
"subcategories":[{"name":"Mac"}, {"name":"Desktop"}]},
{"name": "Mobile Phones" ,
"subcategories":[{"name":"Nokia"}, {"name":"Sony"}, {"name":"iPhone"}]}
];
var viewModel = {
categories: ko.observableArray(data),
selectedCategories: ko.observableArray()
};
ko.applyBindings(viewModel);
HTML code is like this:
<p>Categories: </p>
<div data-bind="foreach: categories">
<div>
<input type="checkbox" data-bind="checked: $parent.selectedCategories, checkedValue: $data.subcategories"/> <label data-bind="text: name"></label>
<ul data-bind="foreach: subcategories">
<li><input type="checkbox" data-bind="checked: $root.selectedCategories, checkedValue: $data"/> <label data-bind="text: name"></label></li>
</ul>
</div>
</div>
<p>Selected items: </p>
<div data-bind="text: ko.toJSON(selectedCategories)"></div>
When I click the main checkbox of a category (Computers) subcategories(Mac, Desktop) didn't populated. So I should clik again Mac and Desktop checkbox, but duplicated records inserting in selecteditems.
Here is jsfiddle code.
What's happening is the checkedValue binding in the parent category is storing the whole subcategories array as an array of objects when checked, when what I believe you want to happen is to store each object in the subcategories array individually. One way to accomplish that is with a click handler instead of checked and checkedValue.
JavaScript:
var data = [
{
"name": "Computers",
"subcategories": [{"name":"Mac"}, {"name":"Desktop"}]
},
{
"name": "Mobile Phones" ,
"subcategories": [{"name": "Nokia"}, {"name": "Sony"}, {"name": "iPhone"}]
}
];
var viewModel = {
categories: ko.observableArray(data),
selectedCategories: ko.observableArray(),
toggleCategory: function(category, event) {
var checked = event.target.checked;
ko.utils.arrayForEach(category.subcategories, function(item) {
viewModel.selectedCategories.remove(item);
if(checked) {
viewModel.selectedCategories.push(item);
}
});
return true;
},
};
ko.applyBindings(viewModel);
HTML
<p>Categories: </p>
<div data-bind="foreach: categories">
<div>
<input type="checkbox" data-bind="click: $root.toggleCategory"/> <label data-bind="text: name"></label>
<ul data-bind="foreach: subcategories">
<li><input type="checkbox" data-bind="checked: $root.selectedCategories, checkedValue: $data"/> <label data-bind="text: name"></label></li>
</ul>
</div>
</div>
<p>Selected items: </p>
<div data-bind="text: ko.toJSON(selectedCategories)"></div>
Notice the new toggleCategory method on the view model and the click: $root.toggleCategory binding that replaced the old checked and checkedValue bindings are the only pieces that have been changed.
Working JS Fiddle (tested in Chrome): http://jsfiddle.net/L2eWg/1/