I am using angularjs. I have sample list of json. I am display the list using ng-repeat and I have checkbox in html.
I need to find user checkbox is clicked or not(not checked or not).
Here's a working example:
var app = angular.module('MyApp', []);
app.controller('MainCtrl', function($scope) {
$scope.result = {};
$scope.result.name = 'World';
var data = '[ { "button": 1, "name": "Test-1", "checked" : 0 }, { "button": 2, "name": "Test-2", "checked" : 0 }, { "button": 3, "name": "Test-3", "checked" : 1 }, { "button": 4, "name": "Test-4", "checked" : 0 }, { "button": 5, "name": "Test-5", "checked" : 1 } ]';
$scope.result.list = JSON.parse(data);
});
<script src="https://code.angularjs.org/1.4.9/angular.js"></script>
<div ng-app="MyApp" ng-controller="MainCtrl">
<p>Hello {{name}}!</p>{{result.list.name}}
<ul>
<li ng-repeat="list in result.list">
<input type="checkbox" ng-model="list.isChecked" ng-checked="list.checked == 1">- {{list.name}}</li>
</ul>
</div>
Expected output:
Find user clicked the checkbox or not.
If checkbox already checked (3 & 5). If user unchecked means I need to identify.
Alternatively, here's a Plunker.
As far as I understood, You want to check if the checkbox was clicked by user or not. Check out the below code changes or on Plunker
This code adds, isClicked attribute to the check-boxes that were clicked. Also it stores the current value of check-boxes in checked attribute.
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.result = {};
$scope.result.name = 'World';
var data = '[ { "button": 1, "name": "Test-1", "checked" : 0 }, { "button": 2, "name": "Test-2", "checked" : 0 }, { "button": 3, "name": "Test-3", "checked" : 1 }, { "button": 4, "name": "Test-4", "checked" : 0 }, { "button": 5, "name": "Test-5", "checked" : 1 } ]';
$scope.result.list = JSON.parse(data);
});
<!DOCTYPE html>
<html ng-app="plunker">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script>
document.write('<base href="' + document.location + '" />');
</script>
<link rel="stylesheet" href="style.css" />
<script data-require="angular.js#1.4.x" src="https://code.angularjs.org/1.4.9/angular.js" data-semver="1.4.9"></script>
<script src="app.js"></script>
</head>
<body ng-controller="MainCtrl">
<p>Hello {{name}}!</p>{{result.list}}
<ul>
<li ng-repeat="list in result.list">
<input type="checkbox" ng-model="list.checked" ng-click="list.isClicked = true" ng-true-value="1" ng-false-value="0">- {{list.name}}</li>
</ul>
</body>
</html>
Related
How to apply ng-style on ng-click dynamically without using ng-class in angular? something like changing color for selected active menu only. something like this DEMO but with ng-style. Below is my code which is toggle function. Can anyone solve this by changing the code or use your own example to change color or font-size for active item when clicked and rest of the items to default state.
<div ng-style="x.selected && {'color':'white','font-weight':'bold'}"
ng-click="select(x)" ng-repeat="x in myData" ></div>
var app = angular.module('anApp', ['angular.filter']);
app.controller('aCtrl', function($scope) {
$scope.data = [
{
"id": 100,
"value": "2452"
},
{
"id": 100,
"value": "2458"
},
{
"id": 1,
"value": "2457"
},
{
"id": 1,
"value": "2459"
},
{
"id": 4,
"value": "2460"
},
{
"id": 5,
"value": "3458"
}
];
$scope.select = function(x){
x.selected = !x.selected;
}
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.22/angular.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular-filter/0.4.7/angular-filter.js"></script>
<div ng-app="anApp" ng-controller="aCtrl">
<div ng-style="x.selected && {'color':'red','font-weight':'bold'}"
ng-click="select(x)" ng-repeat="x in data" >
{{x.value}}
</div>
</div>
Try like this.
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.menuItems = ['Home', 'Contact', 'About', 'Other'];
$scope.activeMenu = $scope.menuItems[0];
$scope.setActive = function(menuItem) {
$scope.activeMenu = menuItem
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.22/angular.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular-filter/0.4.7/angular-filter.js"></script>
<div ng-app="plunker" ng-controller="MainCtrl">
<div class="account-item" ng-repeat='item in menuItems'>
<div class="account-heading" ng-style="activeMenu === item && {'background' :'red' }">
<h4 class="account-title">
{{ item }}
</h4>
</div>
</div>
</div>
Can you try using $index as below example with plunker below,
http://plnkr.co/edit/Z977olOlajTNZENbqx7D?p=preview
<div ng-repeat="x in data" ng-click="setSelected($index)" ng-style="$index === selectedId && {'background' :'red' }">
{{x.value}}
</div>
Please help me with the below code. I have created this so that anyone can make changes and give me a solution.
HTML
<!DOCTYPE html>
<html ng-app="plunker">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script>
document.write('<base href="' + document.location + '" />');
</script>
<link rel="stylesheet" href="style.css" />
<script data-require="angular.js#1.4.x" src="https://code.angularjs.org/1.4.8/angular.js" data-semver="1.4.8"></script>
<script src="app.js"></script>
</head>
<body ng-controller="MainCtrl">
<ul>
<li ng-repeat="continent in destinations">
<input type="checkbox" ng-model="continent.selected" ng-change="parentChange($index)"> {{continent.name}} ({{continent.countries_selected}}
/ {{continent.countries.length}}) - {{continent.all_selected}}
<ul>
<li ng-repeat="country in continent.countries">
<input type="checkbox" ng-model="country.selected"> {{country.name}} </li>
</ul>
</li>
</ul>
<p>You have selected: {{total_selected}} Countries in Total</p>
</body>
</html>
Controller
app.controller('MainCtrl', function($scope) {
$scope.total_selected = 0;
$scope.$watch('destinations', function(destinations){
var total_selected = 0;
angular.forEach(destinations, function(continent){
continent.countries_selected = 0;
angular.forEach(continent.countries, function(country){
total_selected += country.selected ? 1 : 0
continent.countries_selected += country.selected ? 1 : 0
if (continent.countries_selected == continent.countries.length) {
continent.selected = true;
} else {
continent.selected = false;
}
});
});
$scope.select_all = function(continent){
continent.selected = true;
}
$scope.total_selected = total_selected;
}, true);
$scope.select = function(continent){
console.log(continent)
continent.selected = true;
}
$scope.parentChange = function(index) {
angular.forEach( $scope.destinations[index].countries, function(country) {
country.selected = $scope.destinations[index].selected;
});
};
$scope.destinations = [
{
"name": "India",
"countries": [
{
"name": "Mumbai"
},
{
"name": "Delhi"
},
{
"name": "Calicut"
}
]
},
{
"name": "America - US",
"countries": [
{
"name": "New York"
},
{
"name": "Canada"
},
{
"name": "Miami"
},
{
"name": "Hackensack"
}
]
}
];
});
Fiddle Link
What I want to do is:
For Ex: If I select a child node (Delhi) then the parent node (India) should be checked automatically.
In other words, any child node checked should immediately check the parent node and vice-versa
Thanks,
Kimz.
It's a pretty simple change, right now you're watching the collection for changes and doing this inside of it
if (continent.countries_selected == continent.countries.length) {
continent.selected = true;
} else {
continent.selected = false;
}
Whereas what you really want is if at least 1 country is selected for that continent to be selected, so just change it to
if (continent.countries_selected > 0) {
continent.selected = true;
} else {
continent.selected = false;
}
Fiddle For Example
I need, based on an in page variable, to change value of a binding element.
Here it is the in page var:
<script type="text/javascript">
var myVar = 'value1';
</script>
This is the select with the bind element:
<select value="">
<option ng-repeat="value in valueList">
{{myNewValue()}}
</option>
</select>
Here is the controller:
$scope.inPageVar = $window.myVar;
$http.get(jsonUrl).then(function(result) {
$scope.valueList = result.data.valueList;
$scope.myNewValue = function() {
return $scope.valueList[0].additional + $scope.inPageVar;
};
});
Here the JSON structure:
"valueList": [
{
"additionnal": {
"value1": "this is value 1",
"value2": "this is value 2"
}
},
{
"additionnal": {
"value1": "this is value 3",
"value2": "this is value 4"
}
}
]
I would like to know how to concatenate the in-page var value with the element of the get function.. Thank you!
(function() {
angular.module("CombineModule", []).controller('MyController', function() {
this.values = [{
"additional": {
"value1": "this is value 1",
"value2": "this is value 2"
}
}, {
"additional": {
"value1": "this is value 3",
"value2": "this is value 4"
}
}];
this.myNewValue = function(index) {
return this.values[index].additional[myVar];
};
});
})();
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<!DOCTYPE html>
<html lang="en" ng-app="CombineModule">
<head>
<title></title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script>
var myVar = 'value1';
</script>
</head>
<body ng-controller="MyController as v">
<select value="">
<option ng-repeat="value in v.values">
{{v.myNewValue($index)}}
</option>
</select>
<script src="app.js"></script>
</body>
</html>
If you want to expose myVar globally,
write window.myVar = 'some value' instead of var myVar = 'someval'.
Or if you want to make this available into $rootScope.myVar = 'some value'
Then in your logic,
return $scope.valueList[0].additional[window.myVar];
For some reason, when I splice an object into my ng-repeat array, it doubles what I splice in and hides the last object in the array.
However, if I click the toggle hide and "refresh" the ng-repeat, it shows the right data.
Does anyone know why this would be happening and what I can do to fix it?
angular.module('app', [])
.controller('ctrl', function($scope) {
$scope.workflow = {
flow: [{
"id": "1334f68db820f664",
"step_number": 1,
"tasks": [{
"id": "1334f68e3f20f665"
}]
}, {
"id": "134967a5ba205f5b",
"step_number": 2,
"tasks": [{
"id": "134972c5b420e027"
}]
}, {
"id": "1334f68e7d209ae6",
"step_number": 3,
"tasks": [{
"id": "1334f68ef6209ae7"
}]
}]
};
$scope.insertStep = function() {
var insertStepIndex = 1,
task_data = {
"id": null,
"step_number": (insertStepIndex + 2),
"tasks": []
};
//go through each item in the array
$.each($scope.workflow.flow, function(index, step) {
//if the step number is greater then the place you want to insert it into, increase the step numbers
if (step.step_number > $scope.workflow.flow[insertStepIndex].step_number) step.step_number++;
});
$scope.workflow.flow.splice((insertStepIndex + 1), 0, task_data);
}
$scope.toggleHide = function() {
$scope.hide = !$scope.hide;
}
});
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.14/angular.js"></script>
<div ng-app="app" ng-controller="ctrl">
<div ng-click="insertStep()">Insert Step</div>
<br />
<br />
<div ng-click="toggleHide()">Toggle Repeat</div>
<br />
<br />
<div ng-if="!hide">
<div ng-repeat="data in workflow.flow | orderBy:'+step_number'" ng-init="$stepIndex = workflow.flow.indexOf(data)">
{{ workflow.flow[$stepIndex].step_number }}
</div>
</div>
</div>
I got the problem. This is a tricky but the simple part. The ng-init directive only execute once. So your assignment to $stepIndex = workflow.flow.indexOf(data) will not updated when you push a new data to the array/list.
So adding a scope function will fix this problem since Angular will auto call the function when it's returning value changes.
angular.module('app', [])
.controller('ctrl', function($scope) {
$scope.workflow = {
flow: [{
"id": "1334f68db820f664",
"step_number": 1,
"tasks": [{
"id": "1334f68e3f20f665"
}]
}, {
"id": "134967a5ba205f5b",
"step_number": 2,
"tasks": [{
"id": "134972c5b420e027"
}]
}, {
"id": "1334f68e7d209ae6",
"step_number": 3,
"tasks": [{
"id": "1334f68ef6209ae7"
}]
}]
};
$scope.insertStep = function() {
var insertStepIndex = 1
var task_data = {
"id": null,
"step_number": (insertStepIndex + 2),
"tasks": []
};
//go through each item in the array
angular.forEach($scope.workflow.flow, function(step, index) {
//if the step number is greater then the place you want to insert it into, increase the step numbers
if (step.step_number > $scope.workflow.flow[insertStepIndex].step_number) step.step_number++;
});
$scope.workflow.flow.splice((insertStepIndex + 1), 0, task_data);
}
// This is a new function which I added to fix the problem
$scope.getIndex = function(data) {
return $scope.workflow.flow.indexOf(data);
};
$scope.toggleHide = function() {
$scope.hide = !$scope.hide;
};
});
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.14/angular.js"></script>
<div ng-app="app" ng-controller="ctrl">
<div ng-click="insertStep()">Insert Step</div>
<br />
<br />
<div ng-click="toggleHide()">Toggle Repeat</div>
<br />
<br />
<div ng-if="!hide">
<div ng-repeat="data in workflow.flow | orderBy:'+step_number'">
{{ workflow.flow[getIndex(data)].step_number }}
</div>
</div>
</div>
Hello suppose I have a JSON Object
`var books = [{
"Genre": "Sci-fic",
"Name": "Bookname1"
}, {
"Genre": "Sci-fic",
"Name": "Bookname2"
}, {
"Genre": "Non sci-fic",
"Name": "Bookname3"
}, {
"Genre": "Non sci-fic",
"Name": "Bookname4"
}];`
now how I want to show it like
Sci-fic
Bookname1
Bookname2
Non-scific
Bookname3
Bookname3
I am well aware by angular unique property but unique discard the changes I want to segregate data based on similar string in json object
I have tried so far with unique but no luck. Any suggestion please.
You need to apply a filter. 'orderBy' is being provided by angular.js. You can do something like the following to get the expected result :
INDEX.HTML
<!DOCTYPE html>
<html ng-app="plunker">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script>document.write('<base href="' + document.location + '" />');</script>
<link rel="stylesheet" href="style.css" />
<script data-require="angular.js#1.4.x" src="https://code.angularjs.org/1.4.9/angular.js" data-semver="1.4.9"></script>
<script src="app.js"></script>
</head>
<body ng-controller="MainCtrl">
<div ng-repeat="bookPerGenre in booksToFilter() | filter:filterGenres">
<b>{{bookPerGenre.Genre}}</b>
<li ng-repeat="book in books | filter:{Genre: bookPerGenre.Genre}">{{book.Name}}</li>
</div>
</body>
</html>
APP.JS
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.books = [{
"Genre": "Sci-fic",
"Name": "Bookname1"
}, {
"Genre": "Sci-fic",
"Name": "Bookname2"
}, {
"Genre": "Non sci-fic",
"Name": "Bookname3"
}, {
"Genre": "Non sci-fic",
"Name": "Bookname4"
}];
$scope.booksToFilter = function(){
indexedGenres = [];
return $scope.books;
};
$scope.filterGenres = function(book) {
var genreIsNew = indexedGenres.indexOf(book.Genre) == -1;
if (genreIsNew) {
indexedGenres.push(book.Genre);
}
return genreIsNew;
};
});
You can refer this plnkr
{{ books[0].Genre }}
{{ books[0].Name }}
like arrays books[0] used to access the first element.
I hope this will help!
I guess you also need to use groupBy filter like the following question
How can I group data with an Angular filter?
Something like
<ul ng-repeat="(key, value) in books | groupBy: 'Genre'">
{{ key }}
<li ng-repeat="book in value">
{{ book.Name }}
</li>
</ul>
Try it.