Assigning ng-model to checkboxes generated by ng-repeat - angularjs

I have set up a json containing a list of countries with an ID and Country code attached:
It looks like this:
$scope.countries = [
{"name":"Afghanistan","id":"AFG","country-code":"004"},
{"name":"Ă…land Islands","id":"ALA","country-code":"248"},
{"name":"Albania","id":"ALB","country-code":"008"},
{"name":"Algeria","id":"DZA","country-code":"012"}
]
I then use the ng-repeat directive to create checkbox inputs for every country.
<div ng-repeat="country in countries">
<label><input type="checkbox" ng-model="{{country.id}}" ng-true-value="'{{country.name}}'" ng-false-value="''">{{country.name}}</label>
</div>
However when I run the code I only get the following to display:
Location
checkbox here {{country.name}}
If I remove the ng-model part of the repeat my checkboxes generate fine but I need a unique ng-model to be attached to every checkbox
ng-model="{{country.id}}"
How would I go about attaching a unique ng-model value?
This answer (Generate ng-model inside ng-repeat) does not provide a unique ng-model value

I will suggest you, use:
<div ng-repeat="country in countries">
<label><input type="checkbox" ng-model="myCountry.selected[country.id]" ng-true-value="'{{country.name}}'" ng-false-value="''">{{country.name}}</label>
</div>
{{myCountry.selected}}
JS:
$scope.myCountry = {
selected:{}
};

Related

angularjs radiobutton groups having its own model

I want to create a a 3 radio button groups each having its own unique model using one ng-repeat. How can I achieve this?
<div class="radio" data-ng-repeat="item in selItem.items" >
<label class="control-label">
<input type="radio"
data-ng-value={{item.vm}}
data-ng-model="????"
name="{{selItem.Title}}"/>{{item.dm}}
</label>
</div>
First and foremost, why would you do that? Radio buttons are for a unique selection among a group of options, so having the same model for all radio buttons is the way to go.
However, for setting unique ng-models for each item iteration inside ng-repeat, you have to use object bracket notation, using $index or a property of each iteration itself to name the property of the object model.
<div ng-repeat="item in items">
<input type="text" ng-model="myModel[item.name]" >
</div>
check this fiddle to see it working

Using multiple ng-models in a single ng-repeat

I'm trying to get multiple values selected form a checkbox list generated using ng-repeat in anguler
<div ng-repeat="item in items">
<input type="checkbox" ng-model="model.ID" ng-true-value="'{{item.ID}}'" ng-false-value="''"/>{{item.Name}}
</div>
But what I want is to have different ng-models for different check boxes. How can I do that. Is there a way to do what ng-repeat does with out using ng-repeat
In Angular one checkbox is linked with one model, but in practice we usually want one model to store array of checked values from several checkboxes.
Checklist-model solves that task without additional code in controller. examples
use $index as key
<div ng-repeat="item in items">
<input type="checkbox" ng-model="model[$index].ID"/>{{item.Name}}
</div>
or use item unique id:
<div ng-repeat="item in items">
<input type="checkbox" ng-model="model[item.ID]"/>{{item.Name}}
</div>

Trigger filter only on click

I have a list of data, this data is filtered by a dropdown menu.
The problem is, i want the filtering to be triggered only on a button click, not on the dropdown change.
<select ng-model="annee" ng-options="annee.titre for annee in annees track by annee.id">
</select>
<input type="submit" name="submit" value="Filtrer">
<ul>
<li ng-repeat="x in accueils | filter:annee" >
{{x.titre}}
<div ng-bind-html="x.description | to_trusted"></div>
{{x.date}}
{{x.cout}} $
{{x.participants}} participants
</li>
</ul>
Here is a working example :
http://plnkr.co/edit/MbfrhdKfbTObybsQvxrR?p=preview
I want the filter to be triggered on clicking on the "filter" button
Is it possible ?
Thanks a lot!
Note that your filter code here doesn't match your Plunker; it's filter:{annee:annee.id} in the Plunker.
You want to decouple the ng-repeat from the ng-model. One way to do this is to filter based on a new property and update that property only when the Filter button is clicked.
In your HTML:
Add a <form> element and set ng-submit to call submit() when the Filter button is pressed:
<form ng-app="myApp" ng-controller="customersCtrl" ng-submit="submit()">
Change the ng-repeat filter to use a new property instead of the property used by the <select> element's ng-model:
<li ng-repeat="x in accueils | filter:{annee:currentAnnee.id}">
In your controller:
Create the new property initialized with an invalid id:
$scope.currentAnnee = {
"id": 0
};
Create a submit() function that sets the new property from the <select> element's ng-model:
$scope.submit = function() {
$scope.currentAnnee = $scope.annee;
};
See this Plunker for a complete example.
As pointed by #msmolens, there were some differences in your plunker and the code you posted here. Secondly, the two arrays that you have used, have nothing in common so for demonstration purposes i have changed the structure of the second array that will be used as filter.
To start with, decouple your Array filter from the model value of the select drop down.
<select ng-model="annee" ng-options="annee.date for annee in annees track by annee.id">
</select>
<input type="submit" name="submit" value="Filtrer" ng-click="filter()">
<ul>
<li ng-repeat="x in accueils | filter:filterExpr" >
{{x.titre}}
<div ng-bind-html="x.description | to_trusted"></div>
{{x.date}}
{{x.cout}} $
{{x.participants}} participants
</li>
</ul>
As visible in the code, we have a model variable for the filter expression in the ng-repeat.
We then initialize the filter expression with a blank value.
$scope.filterExpr = {"date" : ''};
There after, you just need to capture ng-click of the filter button and modify the variable being used as a filter.
$scope.filter = function() {
$scope.filterExpr = {"date" : $scope.annee.date};
};
You can find the updated plunker here.

Why is angular ng-repeat adding properties to my model?

I'm working on an angular 1.2.x project and I have a list of radio button generated with ng-repeat and an array of objects.
markup
<div ng-repeat="answer in question.answers track by $index">
<label>
<input type="radio" name="answers" ng-value="answer" ng-model="myDataModel">{{answer.text}}
</label>
</div>
array
[
{
"id":"0",
"parentId":"0a4540dfec6549b4a3bd1b8fb6169d77",
"text":"peanuts"
},
{
"id":"1",
"parentId":"deka9fkac6549b4a3bd1b8fb6169d77",
"text":"cashews"
},
{
"id":"2",
"parentId":"0a4540dfec6asdf4a3bd1b8fb6169d77",
"text":"brazil nuts"
}
]
If I use pre tags to view my model as I select through the radios like this...
<pre>{{myDataModel | json}}</pre>
I see random properties climbing onto my data like this
{
"id":"0",
"parentId":"0a4540dfec6549b4a3bd1b8fb6169d77",
"text":"peanuts",
"spc_mXSzO":0,
"idx_mXSzO":0
}
This is causing issues when I try to pre-select a radio button after loading data from my server. When my controller sets my model equal to one of the answers it doesn't have those properties so it doesn't select the radio. Additionally those property names change every time that I refresh the page so I'm not able to mock them. Where do these come from and what might I try to get around them when preselecting answers?
Alright, I found the culprit. It was this library https://github.com/isteven/angular-multi-select
It attaches spc and idx properties for it's purposes.
I can't reproduce what you're seeing either - here's a plunker with what you have above working:
http://plnkr.co/edit/1td3XtqQjMDk1XYBbjEn?p=preview
One issue which what you have is the ng-model directive in your input tag. You shouldn't bind to primitives directly on the $scope. Here's a good description of why:
https://github.com/angular/angular.js/wiki/Understanding-Scopes
And an update to your code:
<div ng-repeat="answer in question.answers track by $index">
<label>
<input type="radio" name="answers" ng-value="answer" ng-model="myDataModel.myAnswer" />{{answer.text}}
</label>
</div>

Reference the inputs created with ng-repeat in angular based on the number of variable options

The problem I'm facing, as outlined in the code, is that I can't seem to find out how to bind the second checkboxes (created with ng-repeat) to some model which I would then be able to use further down the code (showing/hiding yet another set of options). Also, I managed to show the additional number of inputs based on the count parameter in the $scope.availableOptions by using the $scope.getItterator function, but now I don't see how would I access the values of these checkboxes? I know I have to somehow use the option "ng-model" but am failing to do so, so any help appreciated.
My code is here, but am showing it here too:
html:
<div ng-controller='MyCtrl'>
Show additional options <input type="checkbox" ng-model="additionalOptions">
<div ng-show="additionalOptions">
<ul>
<li ng-repeat="option in availableOptions">
<label class="checkbox" for="opt_{{option.id}}">
<input type="checkbox" name="opt_{{option.id}}" id="opt_{{option.}}" />
{{option.name}}
<ul ng-show="if the upper checkbox is clicked">
<li>
<input type="text" ng-repeat="i in getItterator(option.count)" ng-model="SOME_VALUE_TO_BE_USED_BELOW"/>
Output the value based on what's entered above in the textboxes (SOME_VALUE_TO_BE_USED_BELOW)
</li>
</ul>
</label>
</li>
</ul>
</div>
</div>
and my js:
function MyCtrl($scope) {
$scope.availableOptions = [{"id":"1","name":"easy","count":"2"},{"id":"2","name":"medium","count":"3"},{"id":"3","name":"hard","count":"2"}];
$scope.getItterator=function(n){
var a = new Array();
for(var i=1; i <= n; i++)
a.push(i);
return a;
};
}
Try ng-model="option.checked":
<input type="checkbox" name="opt_{{option.id}}" id="opt_{{option.}}" ng-model="option.checked"/>
And then you can access this property further below like this:
<ul ng-show="option.checked">
DEMO
If you need to also reference the text box inputs. You create a new property (values) on the option. Like this:
{"id":"1","name":"easy","count":"2",values:[]}
Html:
<div ng-repeat="i in getItterator(option.count)">
<input type="text" ng-model="option.values[$index]"/>
{{option.values[$index]}}
</div>
DEMO
Use this:
<input type="checkbox" name="opt_{{option.id}}" id="opt_{{option.}}" ng-model="option.clicked"/>
{{option.name}}
<ul ng-show="option.clicked">
Basically, you are saying that the top checkbox should store its value in a model for each option option.clicked. And then only showing the information based on the scope item.
Updated Fiddle:
http://jsfiddle.net/CkHhJ/26/
UPDATE:
Here is another updated fiddle to answer your questions second part: http://jsfiddle.net/CkHhJ/27/
The difficulties you were having is likely because you are trying to build dynamic input models. Just bear in mind that you need to use an object for the dynamic values (not a plain string, eg: option.answers[$index].value and not just option.answers[$index]. See: AngularJS: Updating an input with a dynamic ng-model blurs on each key press

Resources