I have a table with 'n' number of rows and each row has a checkbox. Upon selection of checkbox I am trying to display information coded inside <div> tag.
But even if check box has false value the data inside div is still displayed, am using ng-show in div tag to check if checkbox is true or false.
Below is the code I have used in table column:
<td>
<input id="{{test}}" type="checkbox" value="" ng-checked="selection.indexOf(test) > -1" ng-click="toggleSelection(test)" />
</td>
In JavaScript I have the below toggle function
toggle selection for a given line item by index
$scope.toggleSelection = function toggleSelection(test) {
var idx = $scope.selection.indexOf(test);
if it is currently selected
if (idx > -1) {
$scope.selection.splice(idx, 1);
}
if it is newly selected
else {
$scope.selection.push(test);
}
};
Please point me if I am doing in wrong way, am pretty new to angular world.
this example might be pretty good for your case
<a href="http://jsfiddle.net/t7kr8/211/" >Click here </a>
Make sure you are binding model with ng-show
var app = angular.module('myApp', []);
app.controller('formCtrl', function($scope) {
var _this = this;
$scope.tempArr = [{
status: false,
data: 'hey'
}, {
status: false,
data: 'hey'
}, {
status: false,
data: 'hey'
}];
$scope.tempArr = [{
status: false,
data: 'hey'
}, {
status: false,
data: 'hey'
}, {
status: false,
data: 'hey'
}];
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div data-ng-app="myApp" ng-controller="formCtrl">
<table>
<tr ng-repeat="item in tempArr">
<td>
<input type="checkbox" ng-model="item.status">
</td>
<td><span ng-show="item.status">{{item.data}}</span>
</td>
</tr>
</table>
</div>
<div ng-app="checkbox" ng-controller="homeCtrl">
<div ng-repeat="item in list">
<input type="checkbox" checkbox-group />
<label>{{item.value}}</label>
</div>{{array}}
<br>{{update()}}
</div>
var app = angular.module('checkbox', []);
app.controller('homeCtrl', function($scope) {
$scope.array = [1, 5];
$scope.array_ = angular.copy($scope.array);
$scope.list = [{
"id": 1,
"value": "apple",
}, {
"id": 3,
"value": "orange",
}, {
"id": 5,
"value": "pear"
}];
$scope.update = function() {
if ($scope.array.toString() !== $scope.array_.toString()) {
return "Changed";
} else {
return "Not Changed";
}
};
})
.directive("checkboxGroup", function() {
return {
restrict: "A",
link: function(scope, elem, attrs) {
// 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
}));
});
}
}
});
Related
A quick question:
I'm creating a filter in angularjs to get dynamically a variable and to be used like this from frontend.
<div ng-if="(services | searchValue : 'type' : 'facebook').active == true">
...
</div>
This is the javascript.
.filter('searchValue', function () {
return function (array, name_var, value) {
angular.forEach(array, function(v, k) {
if (v[name_var] == value) {
return v;
}
});
return [];
};
})
Unfortunately even if the result was found it wasn't passed to the template.
If I'll use it like this:
{{(services | searchValue : 'type' : 'facebook')}}
This will get no value. Any suggestion?
I've created a sample example for the info you've provided. Run the below example check. Hope this helps you.
I guess ng-if itself expects only the variable and not the expression. only provide the variable with value i.e (services | searchValue : 'type' : 'facebook').active not the expression.
var app = angular.module('application', []);
app.filter('customfilter', function() {
return function(array, name_var, value) {
var filteredArray = {};
angular.forEach(array, function(v, k) {
if (v[name_var] == value) {
filteredArray = v;
return false;
}
});
return filteredArray;
}
});
app.controller('sampleController', function($scope, $filter) {
$scope.data = [{
"type": "facebook",
"active": false
}, {
"type": "linkedin",
"active": false
}, {
"type": "twitter",
"active": false
}, {
"type": "google",
"active": false
}];
$scope.anotherdata = [{
"type": "facebook",
"active": true
}, {
"type": "linkedin",
"active": false
}];
});
<script data-require="angular.js#1.3.x" src="https://code.angularjs.org/1.3.17/angular.js" data-semver="1.3.17"></script>
<body ng-app="application">
<div ng-controller="sampleController">
First div - Active : false
<div ng-if="(data | customfilter:'type':'facebook').active">
Your div content goes over here
</div>
<br>
<br>Second div - Active : true
<div ng-if="(anotherdata | customfilter:'type':'facebook').active">
Second div rendered
</div>
</div>
</body>
I want to modify this product angular / javascript filter
When user select for example: Processor - 2GHz and Memory - 32GB I want to show only product that have all those properties.
Right now filter shows all products with 2GHz and all products with 32GB.
Plunker
https://plnkr.co/edit/vr9o2aHkHvCL1cvgKILd?p=preview
angular.module('app', [])
.controller('Controller', function($scope) {
$scope.items = [{
"name": "Product - 2GHZ, 32GB, Black",
"tags": [{
"category": 1,
"tag": 2
}, {
"category": 2,
"tag": 4
}, {
"category": 3,
"tag": 8
}]
}, {
"name": "Product - 2GHz, 128GB, Black",
"tags": [{
"category": 1,
"tag": 2
}, {
"category": 2,
"tag": 5
}, {
"category": 3,
"tag": 8
}]
}, {
"name": "Product - 1GHz, 128GB, White",
"tags": [{
"category": 1,
"tag": 1
}, {
"category": 2,
"tag": 5
}, {
"category": 3,
"tag": 7
}]
}];
$scope.items_dup = $scope.items
// checkbox selection
$scope.selectionTag = [];
$scope.selectionCat = [];
$scope.toggleSelection = function toggleSelection(tag, category) {
var idxTag = $scope.selectionTag.indexOf(tag);
if (idxTag > -1) {
$scope.selectionTag.splice(idxTag, 1);
} else {
$scope.selectionTag.push(tag);
}
// this is not working, probably need twodimensional array
// category
var idxCat = $scope.selectionCat.indexOf(category);
if (idxCat > -1) {
$scope.selectionCat.splice(idxCat, 1);
} else {
$scope.selectionCat.push(category);
}
};
// filter list
$scope.filter = function() {
filterTag($scope.selectionTag, $scope.items);
function filterTag(selected, items) {
var out = [];
angular.forEach(items, function(value, key) {
angular.forEach(selected, function(inner_value, key) {
angular.forEach(value.tags, function(inner_value2, key) {
if (value.tags[key].tag === inner_value) {
if (out.indexOf(value) == -1) {
out.push(value)
}
}
})
})
})
if (out.length > 0) {
$scope.items_dup = out;
} else {
$scope.items_dup = $scope.items;
}
}
};
})
<!DOCTYPE html>
<head>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.0/angular.min.js"></script>
<script src="script.js"></script>
</head>
<body ng-app="app">
<div ng-controller="Controller">
<h1>Product filtering!</h1>
<li ng-repeat="item in items_dup">
{{item.name}}
</li>
<hr>
<p data-category="1">Processor</p>
<label>
<input type="checkbox" value="1" ng-click="toggleSelection(1,1)"> 1GHz
</label>
<br>
<label>
<input type="checkbox" value="2" ng-click="toggleSelection(2,1)"> 2GHz
</label><br>
<hr>
<p data-category="2">Memory</p>
<label>
<input type="checkbox" value="4" ng-click="toggleSelection(4,2)"> 32GB
</label>
<br>
<label>
<input type="checkbox" value="5" ng-click="toggleSelection(5,2)"> 128GB
</label><br>
<hr>
<p data-category="3">Color</p>
<label>
<input type="checkbox" value="7" ng-click="toggleSelection(7,3)"> White
</label>
<br>
<label>
<input type="checkbox" value="8" ng-click="toggleSelection(8,3)"> Black
</label><br>
<br><br>
<button ng-click="filter()">Filter list</button>
</div>
</body>
</html>
You could use Array#every to check if each selection appears in an item's tag list. If you want to switch back from an and to an or filter, you can use Array#some instead.
The good thing about these methods is that they return as soon as they know their result, ending the loop early when possible.
$scope.filter = function() {
$scope.items_dup = $scope.items.filter(function(item) {
return $scope.selectionCat.every(function(c) {
return item.tags
.some(function(t) {
return t.category === c &&
$scope.selectionTag.indexOf(t.tag) !== -1;
});
})
});
}
In a plunker: here
An example of how you could create a map, and how it would affect your filter:
var $scope.items = [ /* ... */ ].map(function(item) {
var tagMap = item.tags.reduce(function(result, t.tag) {
result[t.tag] = true; // Add the tag Id to the map
return result;
}, {});
// Add the tag map to the item
return Object.assign(item, { tagMap: tagMap });
});
// Now, you can filter like so:
var matches = selectedTagIds.every(function(id) {
return item.tagMap[id];
});
another approach is using filter with filter object on ng-repeat, in this case items are filtered immediately when check boxes state changes:
<li ng-repeat="item in items_dup | filter : mainFilter : true">
{{item.name}}
</li>
all check boxes use ng-model and trigger update function:
<label>
<input type="checkbox" ng-change="updateFilters()" ng-model="filters.processor['1GHZ']"> 1GHz
</label>
update function:
$scope.updateFilters = function updateFilters() {
$scope.mainFilter = {};
angular.forEach($scope.filters, function (category, categoryKey) {
angular.forEach(category, function (value, valueKey) {
if (value) {
if ($scope.mainFilter[categoryKey]) {
delete $scope.mainFilter[categoryKey];
}
else {
$scope.mainFilter[categoryKey] = valueKey;
}
}
});
});
};
each item has processor, memory and color attributes added.
plunker: https://plnkr.co/edit/6BDVYzV430N0MSaopGXt?p=preview
Having one select tag in html now i want to make select tag dynamic through angularjs so that i can get drop downs from one select options and also want to give different ng-options for every new drop down created
"<div>
<label>dropdown1</label>
<select ng-options=''></select>
</div>"
To be honest, your question is for me a little unclear, but it may help you:
<div ng-repeat="object in myObjects">
<label>{{object.name}}</label>
<select ng-options="object.myOptions"></select>
</div>
this in js:
function AppCtrl ($scope) {
$scope.myObjects = {
"Select1": {
"name": "dropdown1",
"myOptions": [
"one",
"two"
]
}, ....
var app =angular.module('pof', []);
app.controller('myController2', function($scope){
$scope.statuses = [{
id: 1,
name: "First Value"
}, {
id: 2,
name: "Second Value"
}, {
id: 3,
name: "Third Value"
}, {
id: 4,
name: "Fourth Value"
}];
$scope.selected_status = 3;
})
app.directive('bsDropdown', function ($compile) {
return {
restrict: 'E',
scope: {
items: '=dropdownData',
doSelect: '&selectVal',
selectedItem: '=preselectedItem'
},
link: function (scope, element, attrs) {
var html = '';
switch (attrs.menuType) {
case "button":
html += '<div class="btn-group"><button class="btn button-label btn-info">Action</button><button class="btn btn-info dropdown-toggle" data-toggle="dropdown"><span class="caret"></span></button>';
break;
default:
html += '<div class="dropdown"><a class="dropdown-toggle" role="button" data-toggle="dropdown" href="javascript:;">Dropdown<b class="caret"></b></a>';
break;
}
html += '<ul class="dropdown-menu"><li ng-repeat="item in items"><a tabindex="-1" data-ng-click="selectVal(item)">{{item.name}}</a></li></ul></div>';
element.append($compile(html)(scope));
for (var i = 0; i < scope.items.length; i++) {
if (scope.items[i].id === scope.selectedItem) {
scope.bSelectedItem = scope.items[i];
break;
}
}
scope.selectVal = function (item) {
switch (attrs.menuType) {
case "button":
$('button.button-label', element).html(item.name);
break;
default:
$('a.dropdown-toggle', element).html('<b class="caret"></b> ' + item.name);
break;
}
scope.doSelect({
selectedVal: item.id
});
};
scope.selectVal(scope.bSelectedItem);
}
};
});
<link href="http://st.pimg.net/cdn/libs/bootstrap/2.2/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://code.angularjs.org/1.4.8/angular.js"></script>
<script src = "http://st.pimg.net/cdn/libs/jquery/1.8/jquery.min.js">
</script>
<script src = "http://st.pimg.net/cdn/libs/bootstrap/2/js/bootstrap.min.js">
</script>
<body ng-app="pof">
<div ng-controller="myController2 as myCtrl2">
<select ng-init="selected_status = statuses[1].id" ng-model="selected_status" ng-options="status.id as status.name for status in statuses"></select>
<!--<bs-dropdown data-menu-type="button" select-val="selected_status = selectedVal"
preselected-item="selected_status" data-dropdown-data="statuses"></bs-dropdown> --> Selected Value : {{selected_status}}
</div>
</body>
I don't know what your model looks like but maybe something like this:
<div ng-repeat="item in items">
<label>{{item.label}}</label>
<select ng-options="item.options"></select>
</div>
In your controller you would have an array $scope.items that contain all your dropdowns/select elements and their options.
$scope.items = [
{'label':'Item 1','options':{"option 1.1","option 1.2"}},
{'label':'Item 2','options':{"option 2.1","option 2.2"}}
];
I have a few functions that I'm having to mix because of scope in a < select :
HTML:
<!-- COUNTRY -->
<select class="account--select" type="text" name="country" ng-model="data.country_id"
ng-options="o.code as o.name for o in content.countries" ng-change="reset();PookycountryChanged()">
<option value="">OTHER*</option>
</select>
Directive:
scope.PookycountryChanged = function() {
scope.$watch('data.country_id', function(){
if ('data.country_id' == "OTHER*") {
console.log('this is the other option selected');
}
});
}
AIM:
To be able to have a function run when the value of the option selected is equal to 'OTHER*'. Right now this is set to a simple console.log. Getting nothing in the console at the momento.
Any pointers?
UPDATE with Reset() function:
scope.reset = function(){
scope.isenabled = (scope.data.country_id == content.config.pca_country);
scope.country = _.findWhere(scope.content.countries, {code : scope.data.country_id});
};
scope.reset();
UPDATE 2:
Generated markup:
<select ng-change="reset()" ng-options="o.code as o.name for o in content.countries" ng-model="data.country_id" name="country" type="text" class="account--select ng-scope ng-valid ng-dirty"><option value="" class="">OTHER*</option><option value="0" selected="selected">United Kingdom</option></select>
Now you have a few problems with your code: in PookycountryChanged you not check value for data.country_id just create yet another watch, also in watch you compare string 'data.country_id' with string "OTHER*" so it always false.
In case where you select item with value="" model set value to null so in watch function you can check it like in snippet below.
angular.module('app', [])
.controller('ctrl', function($scope) {
$scope.reset = function() {
$scope.isenabled = ($scope.data.country_id == $scope.content.config.pca_country);
$scope.country = _.findWhere($scope.content.countries, {
code: $scope.data.country_id
});
};
$scope.content = {
config : {pca_country: 3},
countries: [{
code: 1,
name: 'name1'
}, {
code: 2,
name: 'name2'
}, {
code: 3,
name: 'name3'
}, {
code: 4,
name: 'name4'
}, {
code: 5,
name: 'name5'
}, {
code: 6,
name: 'name6'
}, {
code: 7,
name: 'name7'
}]
};
$scope.$watch('data.country_id', function(newVal) {
if (newVal === null) {
console.log('selected others');
}
})
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.2/angular.js"></script>
<div ng-app="app" ng-controller="ctrl">
<select class="account--select" type="text" name="country" ng-model="data.country_id" ng-options="o.code as o.name for o in content.countries" ng-change="reset();">
<option value="">OTHER*</option>
</select>
{{country}}
</div>
Or you can avoid even your reset function
angular.module('app', [])
.controller('ctrl', function($scope) {
$scope.content = {
config: {
pca_country: 3
},
countries: [{
code: 1,
name: 'name1'
}, {
code: 2,
name: 'name2'
}, {
code: 3,
name: 'name3'
}, {
code: 4,
name: 'name4'
}, {
code: 5,
name: 'name5'
}, {
code: 6,
name: 'name6'
}, {
code: 7,
name: 'name7'
}]
};
$scope.$watch('data.country_id', function(newVal, oldVal) {
if (newVal !== oldVal && !newVal) {
console.log('selected others');
}
})
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.2/angular.js"></script>
<div ng-app="app" ng-controller="ctrl">
<select class="account--select" type="text" name="country" ng-model="country" ng-options="o.name for o in content.countries" ng-change="data.country_id=country.code;isenabled=country.country_id==content.config.pca_country">
<option value="">OTHER*</option>
</select>
{{country}}
</div>
Remove PookycountryChanged() from your ng-change, then remove the function wrapping your $watch. There is no point having a watcher inside a function since the watch will always be running anyways.
Also change your option to this:
<option value="OTHER*">OTHER*</option>
Then you need to remove the quotation marks around data.country_id:
scope.$watch('data.country_id', function(){
if (data.country_id === "OTHER*") {
console.log('this is the other option selected');
}
});
I'm showing 8 checkboxes using ng-repeat and filtering the data by getting only checked values and showing them in comma separated list using another ng-repeat. But I need to show the exact filtered comma separated string in a textbox and update just as it is getting updated inside ng-repeat.
<div class="col-md-7">
<label class="checkbox" ng-repeat="tooth in teeth">
<input type="checkbox" ng-model="tooth.checked" ng-change="upperRight()" /> {{tooth.id}}
</label>
</div>
<div class="col-md-3">
<span ng-repeat="toothObj in teeth | filter:{ checked: true }">{{toothObj.id}}{{$last ? '' : ', '}}</span>
<input type="text" ng-model="selectedTeeth" />
</div>
Controller
$scope.teeth = [
{ id: 1, checked: false },
{ id: 2, checked: false },
{ id: 3, checked: false },
{ id: 4, checked: false },
{ id: 5, checked: false },
{ id: 6, checked: false },
{ id: 7, checked: false },
{ id: 8, checked: false }
];
Here I added it in plunker for better understanding Plunker URL
I just did it in following way
My controller
$scope.teethUR = [{ id: 1, checked: false }, { id: 2, checked: false }, { id: 3, checked: false }, { id: 4, checked: false }, { id: 5, checked: false }, { id: 6, checked: false }, { id: 7, checked: false }, { id: 8, checked: false }];
$scope.upperRight = function () {
$scope.URSelected = "";
for (var i = 0; i < $scope.teethUR.length; i++) {
if ($scope.teethUR[i].checked == true) {
if ($scope.URSelected == "") {
$scope.URSelected = $scope.teethUR[i].id;
} else {
$scope.URSelected = $scope.URSelected + ", " + $scope.teethUR[i].id;
}
}
}
}
And HTML
<div class="col-md-7">
<label class="checkbox" ng-repeat="tooth in teethUR">
<input type="checkbox" ng-model="tooth.checked" ng-change="upperRight()" /> {{tooth.id}}
</label>
</div>
<div class="col-md-3">
<input type="text" ng-model="URSelected" class="form-control" />
</div>
Have a look at the working code here PLUNKER DEMO
Demo
You can set up two-way binding between the textbox and the checkboxes. When you click the checkboxes, the text box is updated, and when you update the text box, the check boxes are updated.
First, setup two watches: one that watches teeth, and another that watches selectedTeeth:
$scope.$watch ('teeth', function(newVal) {
$scope.selectedTeeth = [];
for(var i = 0; i < newVal.length; ++i) {
if (newVal[i].checked)
$scope.selectedTeeth.push(newVal[i].id);
}
}, true);
$scope.$watch('selectedTeeth', function(newVal) {
for (var j = 0; j < $scope.teeth.length; ++j) {
var tooth = $scope.teeth[j];
if (newVal.indexOf(tooth.id) >= 0) {
tooth.checked = true;
}
else {
tooth.checked = false;
}
}
}, true);
Next set up a ngModel directive, that provides a formatter and a parser to marshal between the 'teeth' and 'selectedTeeth' and vice versa:
app.directive ('teethTextBox', function() {
return {
restrict: 'A',
require: 'ngModel',
scope: { ngModel: '=' },
link:function(scope, element, attr, ngModelController) {
ngModelController.$formatters.push(function(value) {
return value;
});
ngModelController.$parsers.push(function(value) {
var numbers = [];
var tmp = value.split(',');
for (var i = 0; i < tmp.length; ++i) {
numbers.push(parseInt(tmp[i]))
}
return numbers;
});
}
}
});
Hook up the directives in the HTML:
<body ng-controller="MainCtrl">
<div class="col-md-7">
<label class="checkbox" ng-repeat="tooth in teeth">
<input type="checkbox" ng-model="tooth.checked" ng-change="upperRight()" /> {{tooth.id}}
</label>
</div>
<div class="col-md-3">
<input type="text" ng-model="selectedTeeth" teeth-text-box />
</div>
</body>