AngularJS ng-repeat checkbox update ng-model [duplicate] - angularjs

I am trying to do it in proper way with less pain, but i can't figure out how to deal with ng-model and binding it to the selected list etc and moreover i need to populate that list in later time and keep selected objects in it.
categories = [ { "name": "Sport", "id": "50d5ad" } , {"name": "General", "id": "678ffr" } ]
<span ng-repeat="category in categories">
<label class="checkbox" for="{{category.id}}">
<input type="checkbox" value="{{category.id}}" ng-model="??" ng-click="??" name="group" id="{{category.id}}" />
{{category.name}}
</label>
</span>
I have to override the categories each time the list is populated since it will be pulled out from a server.
So I guess I need to have arrays and the second one will hold the selected objects?
If I am right, how do I preselect checkboxes?
Do I need ng-click in order call custom function to store the selected object in the other array?
Do I need ng-model in checkbox And what for?
What is the proper-way with less pain?

I have to override the categories each time the list is populated
since it will be pull out form server. So i quess i need to have
arrays and the second one will hold the selected objects?
Yes, since it is a list you can/should use arrays. The information about the selected items/objects should be stored on your scope model (example below).
If I am right, how do I preselected checkboxes?
Save the ID's of the selected options/checkboxes on your model and let the ng-model do the rest.
Do I need ng-click in order call custom function to store the selected
object in the other array?
No, you don't need it, ng-model is enough.
Do i need ng-model in check box? And what for?
Yes, you need it. The ng-model is responsible for storing the selected options on your model and for making the ('pre-')selection automatic.
jsfiddle http://jsfiddle.net/bmleite/PQvQ2/

Related

Using ng-repeat to build a list of checkboxes, that submit to controller

I have an app where I call for a list of businesses from the server, which I display as checkboxes in my view, using ng-repeat:
<md-checkbox
ng-repeat="business in businesses"
ng-model="business.$index"
value="business._id"
aria-label="Checkbox"
>
{{business.business_name}}
</md-checkbox>
My challenge is trying to update an object/array in my controller, where I can send an updated list of IDs to the server.
For some reason when I click on one of the checkboxes they all get selected.
Would love to know how others:
1)dynamically generate a number of checkboxes from an object array pulled from a service.
2)display them in the view, then pass the checked status of the checkboxes back to the controller.
I'm sure it's something simple, but I'm just not making any progress.
Add a selected property to your objects init by default to false (if you want your checkboxes not selected by default).
Your property will be true when checked, false otherwise.
<md-checkbox
ng-repeat="business in businesses track by business._id"
ng-init="business['selected']=false;"
ng-model="business['selected']"
aria-label="Checkbox"
>
{{business.business_name}}
</md-checkbox>
From your controller, if you loop inside your businesses array, you will have within each object property selected true or false, in order to know if they are selected or not, and if selected just access the _id of that object.
For example you can have all the selected items of your array in this way inside your controller:
console.log($scope.businesses.filter(el => el.selected));
assuming md-checkbox behaves like a checkbox...
<md-checkbox
ng-repeat="business in businesses"
ng-model="business.$index"
value="business._id"
aria-label="Checkbox">
{{business.business_name}}
</md-checkbox>
business.$index would evaluate to something like business.3 which is not valid and probably not what you're expecting.
you could use something like business.selected as quirimmo suggested.
this would make the checkmark unchecked if selected is undefined or false and when we check the checkbox, it would set selected to true.
on the other end, when you want to save those selections, you will have to make sure your controller is looking for the selected property.

AngularJS dependable dropdowns from json tree bind issue

building an app that retreives data from a database.
Created 2 dependable dropdowns
1.Categories
2. branches
all select options are coming from a json tree (Array in an Array) that is fetched by a service(Categories).
in controller i fetch json with :
$scope.categories = Categories.query();
in html i try below code:
<select class="form-control" name="category" ng-model="params.category" ng-options="item as item.name for item in categories track by item.category">
</select>
<select class="form-control" name="branch" ng-model="params.branch" ng-options="branch as branch.name for branch in categories[params.category].branches track by item.category.branch">
</select>
Dropdown 1. Categories fetched ok but Dropdown 2. branches doesnt work.
Can you guide??
Since you have an array of arrays, I think the params.category variable will hold a reference to an array, so you can't use it in the second select with categories[params.category] because you need to use the index and not the reference. I suggest you try: categories[categories.indexOf(params.category)].
EDIT:
Since I don't know what your categories array looks like, and what a branch array looks like, I can only guess according to your code. IF your data structure is similar to what I think - here is a working plunker.
The main idea is that if an element inside your categories array is an object and has a branches property, then after you put a reference to it in $scope.params.category than you can just access the branches property using dot notation (no need to go back to the categories array).

angular.js with ng-model using ng-repeat

I have a dictionary of objects with some duplicate ids like this:
var groups = {"0": "attributes":[{"id":2, "name":"abc"},
{"id":5, "name":"xyz"}],
"1": "attributes":[{"id":2, "name":"abc"}]}
I want to fetch this group into input text fields of form like this
<div ng-repeat="group in groups">
<input type="text" ng-model="group.value"/>
</div>
Its working fine if I have all the distinct ids but I want the input fields with duplicate ids to be attached with same ng-model, so that if one input is filled then another one gets filled automatically.
Searched almost everything but couldn't come up with any solution. Any help would be appreciated.
Thanks in advance :)
The HTML standard requires elements to have unique IDs to be valid. Use a class to select multiple elements using a shared selector. You could write some code to have each element with the same ID have the same ng-model value.

How to bind data depending on if checkbox is checked?

Just getting started on Angular, I'm using checkboxes to determine which parameters get sent during a get request (this is my attempt):
<input type="checkbox" ng-click="submit('color[]', 'red')"/>
<input type="checkbox" ng-click="submit('color[]', 'green')" checked/>
<input type="checkbox" ng-click="submit('color[]', 'blue')"/>
I have a variable $scope.params that stores the parameters of my http get request. My submit function is very simple:
$scope.submit = function (attribute, value) {
$scope.params[attribute] = value;
};
It simply adds color[] to the params object. Unlike radio, checkbox values can be stored as arrays and submitted as such: api?color[]=red&color[]=green as my backend is PHP this is the preferred format. However my submit function simply overwrites this every time. I'm not sure how to store multiple params with the same "key".
My other problem is that ng-click is not appropriate for this task as it doesn't take in the current state of the checkbox. Notice that my green checkbox is initially loaded as checked. Is there a way to bind this to my $scope.params object?
Ideally I want to implement something like:
$scope.params = {
"color[]" = ['red', 'green', 'blue']
};
According to Semicolon's answer below, I can use:
<input type="checkbox" ng-model="params.colors[]" ng-true-value="'red'"/>
<input type="checkbox" ng-model="params.colors[]" ng-true-value="'blue'"/>
<input type="checkbox" ng-model="params.colors[]" ng-true-value="'green'"/>
But naming anything with "[]" just breaks the code.
Checkboxes, like all input elements, are supported with ng-model. This core directive is a cousin of ng-bind. It says "the state of this element represents this model". Its behavior is determined by the input type. In the case of a checkbox, the value you are modeling is going to be boolean typically, since a checkbox is fundamentally a "boolean" input (checked/unchecked == true/false).
<input type="checkbox" ng-model="colors.red"/>
In the controller function:
$scope.colors = {
red: false,
green: true,
blue: false
};
Actually you can map checked/unchecked to non-boolean values too, using ng-true-value and ng-false-value. You can read more about these and other options for ng-model with checkboxes in the Angular docs:
https://docs.angularjs.org/api/ng/input/input%5Bcheckbox%5D
The core difference between ng-bind and ng-model is that the former is unidirectional (just a view) and the latter is bidirectional (the element can be used to change the model).
A more general answer regarding the premise of MVC in Angular:
In the example in your question, you were using a jQuery-like solution to try to achieve binding between the view and controller. This is really not ideal. Only bind a function to click events when you are specifically interested in having something take place "on click".
What if a user uses the tab key and the spacebar to check the box? The model would not get updated.
Or let's say you want to change the value in the model somewhere else -- maybe you have a "reset" button that returns them to the original values. The view would not get updated.
If the connection between the view and the model is all through "actions" it is easy for them to be out of sync. You'd have to make sure you handled every possible way the user could interact with the element and each time you change the data programmatically you would need to push the change to the view explicitly. But using ng-model and ng-bind lets you keep them synced no matter where the model is changed or how the user interacts. Really this is the main point of Angular.

dependent ng-models inputbox and select Angular js

I am having one text box and one dropdown.
I want filtering in ng-repeat section based on both of the above control.
Means if i select name in dropdown and in text box as I typing the filtering should work based on name
and if in dropdown if i select EployeeID then filtering should be work based on Employee.
<input id="txtSearchText" ng-model="searchText"/>
<select>
<option>name</option>
<option>EmployeeID</option>
</select>
<div ng-repeat="u in users">
name : {{u.name}} || EID: {{u.eid}} :
<!-- here i want result -->
</div>
The link that domakas directed you to above should help, but the example is slightly different since it filters using 3 different text input boxes.
You are missing a few things here. The first thing is you need to apply a filter to in the ng-repeat for the users div.
<div ng-repeat="u in users | searchText">
The problem that you run into here, which I am sure you are aware of is that it will filter on all of the values in the users array. You seem to want to only filter on the value in the users array that the dropdown has specified. This means we will have to tie the filter to the dropdown in some fashion to make it dynamic.
The way I would do this is to make the filter an object and not just pure text.
$scope.searchText = {name: '', eid: ''};
Now you need to have the model of your input box tied to this object, but where it stores the value needs to be dynamic based on what the value of the dropdown
<input id="txtSearchText" ng-model="searchText[filter]" />
<select ng-model="filter">
<option value="name" selected>name</option>
<option value="eid">EmployeeID</option>
</select>
The above code will store the value of the dropdown in the correct value of the searchText object. This means that the filter will now use this object to filter out the results in the users div instead of just a string, which it would compare to the full JSON object.
Edit:
Added a watch on the 'searchText' object to clear the other value if the dropdown is switched. Without this the old filter value was still in the 'searchText' object, which caused it to filter on both values.
$scope.$watch('filter', function() {
if($scope.filter == "eid") {
$scope.searchText.name = '';
} else {
$scope.searchText.eid = '';
}
});
Here is a JSFiddle with a working example:
http://jsfiddle.net/glandrum101/NM5A5/1/

Resources