I'm trying to make a checkBox using AngularJS, I found this code :
http://jsfiddle.net/t7kr8/211/
and following its steps my code was :
JS File:
'use strict';
var app = angular.module('myApp.Carto', ['ngRoute'])
.config(['$routeProvider', function($routeProvider) {
$routeProvider.when('/Carto', {
templateUrl: 'Carto/carto.html',
controller: 'CartoCtrl'
});
}])
app.controller('CartoCtrl', function($scope) {
$scope.array = [];
$scope.array_ = angular.copy($scope.array);
$scope.list = [{
"id": 1,
"value": "apple",
}, {
"id": 3,
"value": "orange",
}, {
"id": 5,
"value": "pear"
}];
});
app.directive("checkboxGroup", function() {
return {
restrict: "A",
link: function(scope, elem) {
// Determine initial checked boxes
if (scope.array.indexOf(scope.item.id) !== -1) {
elem[0].checked = true;
}
// Update array on click
elem.bind('click', function() {
var index = scope.array.indexOf(scope.item.id);
// Add if checked
if (elem[0].checked) {
if (index === -1) scope.array.push(scope.item.id);
}
// Remove if unchecked
else {
if (index !== -1) scope.array.splice(index, 1);
}
// Sort and update DOM display
scope.$apply(scope.array.sort(function(a, b) {
return a - b;
}));
});
}
};
});
However, when I run the code in the browser the checkbox appears but I can't chack the boxes, does that mean the directive doesn't work ?
I could'nt figure out what was going wrong because I practically just copied the code in the link provided above , can you please help me how to fix this ?
Thank you in advance
PS: I think it's due to materialize but I still don't know how or how to fix it
I think you've made a mistake with the module name.
I recreated your sample code and it works perfectly fine: JSFiddle
Code:
var myApp = angular.module('myApp', []);
//myApp.directive('myDirective', function() {});
//myApp.factory('myService', function() {});
function MyCtrl($scope) {
$scope.array = [];
$scope.array_ = angular.copy($scope.array);
$scope.list = [{
"id": 1,
"value": "apple",
}, {
"id": 3,
"value": "orange",
}, {
"id": 5,
"value": "pear"
}];
}
myApp.directive("checkboxGroup", function() {
return {
restrict: "A",
link: function(scope, elem) {
// Determine initial checked boxes
if (scope.array.indexOf(scope.item.id) !== -1) {
elem[0].checked = true;
}
// Update array on click
elem.bind('click', function() {
var index = scope.array.indexOf(scope.item.id);
// Add if checked
if (elem[0].checked) {
if (index === -1) scope.array.push(scope.item.id);
}
// Remove if unchecked
else {
if (index !== -1) scope.array.splice(index, 1);
}
// Sort and update DOM display
scope.$apply(scope.array.sort(function(a, b) {
return a - b
}));
});
}
}
});
HTML:
<div ng-controller="MyCtrl">
<div ng-repeat="item in list">
<input type="checkbox" checkbox-group />
<label>{{item.value}}</label>
</div>
</div>
The error was due to the presence of both bootstrap and Materialize , apparently there is a conflict between the two and when I deleted bootstrap, it all worked well
Related
I have an ng-repeat like this:
<div ng-repeat="user in staff | profAndDr">
And a custom filter that shows people with title "Dr." and "Prof." only:
app.filter('profAndDr', function() {
return function(input) {
var out = [];
angular.forEach(input, function(title) {
if (title.title === 'PROF.'||title.title==='DR.') {
out.push(title)
}
})
return out;
}
I need to add a checkbox that does show people with title "Prof. Amaritos" if checked. So, basically I need to remove my filter from ng-repeat if checked.
Link to Codepen
Thanks!
You can pass variables into your filter and then use this to determine if your checkbox is checked.
e.g.
<div ng-repeat="user in staff | profAndDr: isChecked">
Then
app.filter('profAndDr', function() {
return function(input, isChecked) {
var out = [];
angular.forEach(input, function(title) {
if (title.title === 'PROF.' || title.title==='DR.' || (isChecked && [othercondition])) {
out.push(title)
}
})
return out;
}
You can write additional ng-repeat without filter but its bad practice. I suggest you to pass true/false flag to filter that should return input as is.
HTML
<div ng-app="staffApp">
<div ng-controller="StaffListCtrl">
<label for="amaritos">Show Amaritos</label>
<input id="amaritos" type="checkbox" ng-model="showFlag">
<hr />
<div
ng-cloak
ng-repeat="user in staff | profAndDr:showFlag">
{{user.title}} {{user.first}}
</div>
</div>
</div>
filter
phonecatApp.filter('profAndDr', function() {
return function(input) {
var out = [];
angular.forEach(input, function(title) {
if (title.title === 'PROF.'||title.title==='DR.') {
out.push(title)
}
})
return out;
}
});
You can pass the value of the checkbox as a parameter to your filter. In case you want to show everything, just return the original input.
app.filter('profAndDr', function() {
return function(input, showAmaritos) {
if (showAmaritos) {
return input;
}
var out = [];
angular.forEach(input, function(title) {
if (title.title === 'PROF.'||title.title==='DR.') {
out.push(title)
}
});
return out;
}
}
HTML
<input id="amaritos" ng-model="showAmaritos" type="checkbox">
<div ng-repeat="user in staff | profAndDr:showAmaritos">
See improved codepen
updated js
var phonecatApp = angular.module('staffApp', []);
"use strict";
phonecatApp.controller('StaffListCtrl', ['$scope', '$filter', function ($scope) {
$scope.title=false;
$scope.staff = [
{
"first": "POZIK",
"last": "GOLDSMITH",
"title": "PROF."
},
{
"first": "LOSHOK",
"last": "GALIMIY",
"title": "DR."
},
{
"first": "SHMOK",
"last": "GOLDSMITH",
"title": "PROF. AMARITOS"
},
]
}])
phonecatApp.filter('profAndDr', function() {
return function(input,test) {
var out = [];
angular.forEach(input, function(title) {
if(test == false){
if (title.title === 'PROF.'||title.title==='DR.') {
out.push(title)
}
}
else if(test == true){
if (title.title === 'PROF. AMARITOS') {
out.push(title)
}
}
})
return out;
}
});
and in your html
<input id="amaritos" type="checkbox" ng-model='title'>
you can intercept the value of your inputs by assigning them a variable in an ng-model property. You can then add condition to your filter to do different things based on the value of your inputs.
http://codepen.io/anon/pen/oYmpvZ
Hope this helps.
i am beginner in angular and i have a dynamic list like this
{.name:superParent,id:0,parrentId:null}
{.name:a,id:1,parrentId:0}
{.name:b,id:2,parrentId:0}
{.name:c,id:3,parrentId:1}
{.name:e,id:4,parrentId:3}
{.name:d,id:5,parrentId:2}
how can i implement it as nested list using angular and Recursive template? and also i want to keep each item-id in it self in the some attribute or property
i create this , but it dose not show the tree ,i can see the data only when i use ng-repeat in li
<ul>
<li ng-repeat="col in tree">{{col.Name}}</li>
</ul>
</div>
</div>
<script>
var app = angular.module('APP', []);
app.controller('IndexCtrl', function ($scope, $http) {
$scope.tree = [];
$scope.getList = function () {
//get data from server
$http.get("/person/GetTree")
.then(function (data) {
console.log("data:", data);
$scope.tree = data.data;
$scope.loading = false;
} )
}
$scope.getList();
});
app.directive('treeView', ['$compile', function($compile) {
return {
priority : 0,
restrict : "E",
replace : true,
scope : {
head: "=head",
children: "=children"
},
template: '<div><h4 id="{{head.id}}" ng-show="head.id>0">{{head.Name}}</h4> <ul> <li ng-repeat="item in items"> <tree-view head="item" children="children"></tree-view> </li> </ul></div>',
controller : ['$scope', function ($scope) {
var array = $scope.children;
var head = $scope.head;
//I used plugin linq.js
$scope.items = array.filter(function(val){
return val.parrentId==head.id;
});
}],
compile : function compile(element) {
var contents = element.contents().remove();
var contentsLinker;
return function (scope, iElement) {
if (angular.isUndefined(contentsLinker)) {
contentsLinker = $compile(contents);
}
contentsLinker(scope, function (clonedElement) {
iElement.append(clonedElement);
});
};
}
};
}]);
You can see example.
First I added main head item into your collection (it will be super parent for all other items):
{ name: "superparent", id: 0, parentId: null }
Then your collection will be looks like this:
tree = [
{name:'superparent',id:0,parrentId:Null},
{name:'a',id:1,parrentId:0},
{name:'b',id:2,parrentId:0},
{name:'c',id:3,parrentId:1},
{name:'e',id:4,parrentId:3},
{name:'d',id:5,parrentId:2},
];
All what we can do - create recursive directive (treeView) with such html template:
<div>
<h4 id="{{head.id}}" ng-show="head.id>0">{{head.name}}</h4>
<ul>
<li ng-repeat="item in items">
<tree-view head="item" children="children"></tree-view>
</li>
</ul>
</div>
I used TypeScript, but I sure you will easily undestand this code (d.compile function was taken from this answer):
module Directives {
export interface TreeItem {
name: string;
parrentId?: number
id: number;
}
TreeView.$inject = ['$compile'];
export function TreeView($compile): ng.IDirective {
var d: ng.IDirective = {};
d.priority = 0;
d.restrict = "E";
d.replace = true;
d.scope = {
head: "=head",
children: "=children"
};
d.templateUrl = '/somepath/treeView.html';
d.controller = ['$scope', function ($scope) {
var array: Array<TreeItem> = $scope.children;
var head: TreeItem = $scope.head;
$scope.items = array.filter(function(val){
return val.parrentId==head.id;
});
}];
d.compile = function compile(element) {
var contents = element.contents().remove();
var contentsLinker;
return function (scope, iElement) {
if (angular.isUndefined(contentsLinker)) {
contentsLinker = $compile(contents);
}
contentsLinker(scope, function (clonedElement) {
iElement.append(clonedElement);
});
};
};
return d;
}
}
At the end, into your html page, directive will be inserted this way, where tree[0] as you guessed is super parent:
<tree-view head="tree[0]" children="tree" ng-if="tree"></tree-view>
I have checked all the other posts and trust me, this is not a duplicate. Hope someone can help me. Here is the code.
HTML Code- When user clicks on Report, buildData gets executed. multiselect directive name is mu-ls.
<button ng-click="buildData(selected_items)">Report</button>
<div>Universe:</div>
<div><mu-ls pre-selected="member.roles" model="selected_items" options="roles"></muls></div>
Directive Code- The directive name is muLs. User can select multiple options using this directive. The $scope.model gives the array of ids which user selected.
angular.module('Select').directive('muLs', function () {
return {
restrict: 'E',
scope: {
model: '=',
options: '=',
pre_selected: '=preSelected'
},
template: "<div data-ng-class='{open: open}'>" +
"<button data-ng-click='open=!open;openDropdown()'>Select...</button>" +
"<ul aria-labelledby='dropdownMenu'>" +
"<li data-ng-repeat='option in options'> <a data-ng-click='setSelectedItem()'>{{option.name}}<span data-ng-class='isChecked(option.id)'></span></a></li>" +
"</ul>" +
"</div>",
controller: function ($scope) {
$scope.openDropdown = function () {
$scope.selected_items = [];
for (var i = 0; i < $scope.pre_selected.length; i++) {
$scope.selected_items.push($scope.pre_selected[i].id);
}
};
$scope.setSelectedItem = function () {
var id = this.option.id;
if (_.contains($scope.model, id)) {
$scope.model = _.without($scope.model, id);
} else {
$scope.model.push(id);
}
console.log($scope.model);
return false;
};
$scope.isChecked = function (id) {
if (_.contains($scope.model, id)) {
return 'glyphicon glyphicon-ok pull-right';
}
return false;
};
}
}
});
Controller Code- This should show the list of selected items listed above in the controller side. It shows undefined at the moment.
'use strict'
var Modd= angular.module('Select', []);
Modd.controller('SelectController', function ($scope, $timeout, $rootScope) {
$scope.roles = [
{ "id": 1, "name": "USA" },
{ "id": 2, "name": "France" },
{ "id": 3, "name": "Russia" }
];
$scope.member = { roles: [] };
$scope.selected_items = [];
$scope.buildData = function (selected_items) {
console.log("This is", $scope.model);
}
});
QUESTION- How can i use this directive value $scope.model in the controller side ??? Please suggest guys !!!
I tried $scope.selected_items first. It gives a list of selected items only once. Once i click Report button, it will give the list. If i again start clicking and deselecting list items, it would still show the previous values. not the current ones.
$scope.model continues to show the latest values selected.
You are passing selected_items to your directive so it will contain the value of model in your controller.
$scope.buildData = function () {
console.log("This is", $scope.selected_items);
}
model is two-way bound. So if you assign a $scope variable from your controller to the module attribute, it will be updated when the selected value changes.
Therefore you can console.log($scope.selected_items);
With the command console.log($scope.data) I can see my json file. I can also see the whole items in the view with <div ng-repeat="item in data"> but console.log($scope.data[0]) or console.log($scope.data[0].name) return an error "undefined"and console.log($scope.data.length) return 0.How can I access the items in the controller.
edit
$scope.data contain a json file. $scope.data = service.query(); and it looks like
I don't understand why is length return 0 when ng-repeat is working
It seems that you've stripped down all the relevant details (e.g. service.query implementation) from the question.
This plunker may shed some light on what's going on.
var app = angular.module('app', []);
app.factory('data', function ($timeout) {
var data = [];
return {
query: function () {
$timeout(function () {
data.push(1, 2, 3);
}, 1000);
setTimeout(function () {
data.push('Oops, ng-repeat is unconscious of this one');
}, 2000);
return data;
}
};
});
app.controller('AppController', function($scope, data) {
$scope.data = {
agile: [1, 2, 3],
lazy: data.query()
};
$scope.$watch('data.lazy', function (newVal, oldVal) {
if (newVal === oldVal) return;
console.log($scope.data.lazy[0]);
}, true);
});
I have a strangely structured object which I am trying to convert to an array so that I am able to use filters with ng-repeat.
Here is an example object:
var sysData = {
"walkerduct": {
"id": 0,
"uri": "walkerduct",
"name": "Walkerduct",
"imageS": "img/callcenter.jpg",
"imageL": "img/callcenter.jpg",
"copy": "Walkerduct info",
"relatedSys": [],
"relatedApp": []
}
}
My controller where I attempt to convert it to an array,
inFloorControllers.controller('ApplCtrl', ['$scope', '$routeParams',
function ($scope, $routeParams) {
//alert("OtherCtrl hit");
$scope.appData = appData;
$scope.sysData = sysData;
$scope.title = appData.title;
$scope.sysArr = [];
var hasData = true;
var idx = 0;
while (hasData) {
var data = sysData[idx];
alert("yo");
if (data) {
$scope.sysArr.push(data);
idx++;
}
else {
hasData = false;
}
}
for (i = 0; i < $scope.sysArr.length; i++) {
alert($scope.sysArr[i]);
}
}
]);
And finally my HTML,
<div ng-repeat="sys in sysArr | limitTo:3">
<a href=#/systems/{{sys.uri}}>{{sys.name}}</a>
</div>
I'm not seeing what I am doing wrong... it doesn't even hit if(data)... thanks.
Just use Object.keys combined with Array.map, like this:
inFloorControllers.controller('ApplCtrl', ['$scope', '$routeParams',
function ($scope, $routeParams) {
$scope.appData = appData;
$scope.sysData = sysData;
$scope.title = appData.title;
$scope.sysArr = Object.keys($scope.sysData).map(function(key){
return $scope.sysData[key];
});
}
]);
If you need support for IE8 you will need the polyfill for the map function.
That is not a valid json. remove the last comma
{
"walkerduct": {
"id": 0,
"uri": "walkerduct",
"name": "Walkerduct",
"imageS": "img/callcenter.jpg",
"imageL": "img/callcenter.jpg",
"copy": "Walkerduct info",
"relatedSys": [],
"relatedApp": []
}
}