Is this the angular way to keep track of checked items? - angularjs

I have achieved what I want, which is to create an array of all checked items in angular. I plan to use these in another function.
My solution feels a bit awkward, is there a better way to do this?
<input
ng-repeat="task in $store.taskarr track by $index"
ng-change="checked(check,$index,task)"
ng-model="check"
type="checkbox"
/>
$scope.checked = function(check,count,task){
if(check){
$scope.$store.checkedItems[count] = task;
}else{
delete $scope.$store.checkedItems[count];
}
}

I liked this as it's using less code:
<input
ng-repeat="task in $store.taskarr track by $index"
ng-change="check ? ($store.checkedItems[$index] = task) :
($store.checkedItems[$index] = undefined)"
ng-model="check"
type="checkbox"
/>

You can use a combination of a service that tracks the state of selected items and an attribute directive you can attach to the checkbox.
The data can be modeled as an object that maps IDs to whether or not an item is checked.
The directive controller can handle the responsibility of updating the service so your parent controllers don't have to care about that part, but you can still get the selection state from anywhere in your app.

Related

How to bind element once?

I want to bind item to the view only once in my angulajs project.
Here is plunker.
Here the template html:
<div class="form-group">
<div class="col-xs-8">
<span ng-repeat="city in ma.cities" class="view" ng-if="city.Id == ma.selected">
{{::city.Name}}
</span>
<select class="form-control"
ng-model="ma.selected"
ng-options="city.Id as city.Name for city in ma.cities">
</select>
</div>
</div>
I want the city.Name to be bind to template html only once.
But the problem that when I change the item in select element the city.Name is also updated.
I try to use once bind operator :: but it didn't help.
How can I bind element to the view only once and to prevent update?
The value isn't changing. You're got an ng-if nested within an ng-repeat and when the city is changed which item is displayed changes.
If I'm following what you're trying to do, I would store the currently selected city to a property on the controller when the controller is created and display that property, eliminating the ng-repeat and the ng-if in the process.
I agree with Mike, the question is a bit ambiguous. I think what you're asking for is:
<span>{{::ma.cities[ma.selected].Name}}</span>
But then again, as Mike said, you could've achieved that with another scope variable, and it would be probably a much clearer solution.
As YOU adviced I modified html template:
<span ng-repeat="city in ::ma.cities" class="view" ng-if="::city.Id == ma.selectedId">
{{city.Name}}
</span>
Here is plunker.

Angular checkboxes and ng-repeat not showing up in model

I'm not sure what I'm doing wrong but I'd like the value of checkboxes to show up as an array in the stores property. Nothing ever shows up. I feel like I'm not utilizing the ng-model properly.
Controller
$scope.parameters = {
myMainOptions:
{
teams: ['angels', 'giants', 'orioles', 'bluejays', 'athletics']
}
}
View
<li ng-repeat="t in parameters.myMainOptions.teams">
<input ng-model="form.selectedTeams[t]" type="checkbox" /> {{t}}
</li>
<button class="btn btn-sm" type="submit" ng-click="submit(form)">SUBMIT</button>
you will need to initialize an array in scope to fill the data into it,,
and also you need to use $index to access the current index of each element ,, so that you can make it as an array not with the object is sel as key like here
<input ng-model="boxes[$index]" type="checkbox" />
you can see the js fiddle here
http://jsfiddle.net/vrem17m0/
There's nothing wrong in your code. Just make sure to initialize the form.selectedTeams object and set the angular controller correctly, then you should be good to go.
You can check this JsFiddle to see it working.

How to programmatically uncheck checkbox?

I want to programmatically uncheck a checkbox. I know how to it in javascript but since I'm using angular, i think it's different.
Here's the link of jsfiddle : https://jsfiddle.net/TKVH6/499/
This is the first time I used jsfiddle so please let me know if you cant see the script and html.
This is the html
<input type="checkbox" ng-model="v" ng-click="checkAll()" />
<button ng-click="x()">eto</button>
This is the angular
$scope.x = function () {
$scope.v.checked=false;
};
I know there are lots of question like this, I've already tried those but I can't make it work.
Thanks!
<input type="checkbox" ng-checked="v" ng-click="checkAll()" />
In your controller
$scope.v = true; // or false
First thing : You have specified controller on ul and bind click event of button outside the ul so moved ng-controller on div.
Second thing: In order to check it pragmatically you need to set $scope.Items[i].Selected = true;
$scope.x = function () {
alert("x");
$scope.Items[0].Selected=true;
};
Why we need to set Selected property of Items[i] while I have not declared?
The reason behind that is your html binding is something like this:
<li ng-repeat="item in Items">
<label>{{item.Name}}
<input type="checkbox" ng-model="item.Selected" />
</label>
</li>
Here every item is element from Items array that means your checkbox checked value is now bind to selected property of that object. Even though you have not defined that property in Items collection angular will create it and will bind it to that property. So you are required to set that property. I hope it would help you.
Here is working fiddle => link

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>

Bind JSON object to radio button in angularjs

So I am trying to bind radio buttons to objects. I have spent like an hour trying to figure this up and at last admit defeat. Here's what I got:
<table>
<tr ng-repeat="theCustomer in customers">
<td>
<input type="radio" ng-model="currentCustomer" value="theCustomer" id="{{theCustomer.id}}" ng-change="currentCustomer = theCustomer">
<label for="{{theCustomer.id}}">{{theCustomer.name}}</label>
</td>
</tr>
</table>
The angular stuff:
bankApp.controller("BankController", function ($scope, CustomerRepository)
{
$scope.customers = [];
$scope.currentCustomer = {};
$scope.createCustomer = function () {
CustomerRepository.save($scope.customer, function (customer) {
$scope.customers.push(customer);
$scope.customer = {};
});
};
});
Currently, when I try and click on a radio button nothing happens, it doesn't even get checked. I'm sure there's got to be a really simple solution to this. The end goal is to have currentCustomer hold the customer reflected in the radio selection.
<input type="radio" ng-model="$parent.currentCustomer" name="foo" ng-value="theCustomer" id="{{theCustomer.id}}">{{theCustomer.name}}</td>
The key here is the ng-value="theCustomer. This is how angular knows which object is selected. The html value only knows string values and cannot map to objects.
If you insert the above code, the radio will reflect the model, even if it is changed programatically. Also, you can't forget the $parent in the ng-model because the ng-repeat creates a new scope.
Apparently, getting a radio group to work inside an ng-repeat can be a bit tricky. The issue is with the ng-repeat creating its own child scope. One solution is to bind the model to the $parent. This thread gives an example.
I also created a working fiddle that more closely resembles your example.
In essence, I think your html is the only point that needs reworking:
<table>
<tr ng-repeat="theCustomer in customers">
<td><input type="radio" ng-model="$parent.currentCustomer" name="foo" value="{{theCustomer}}" id="{{theCustomer.id}}">{{theCustomer.name}}</td>
</tr>
</table>
It is because of the scope inheritance, you can read more about the problem here.
One solution that I use in such a case, is to bind the object to an object property instead of a primitive value like ng-model="form.currentCustomer".
Demo: Plunker

Resources