Bind JSON object to radio button in angularjs - 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

Related

Retain checkbox state in angular when the scope changes

below is a code snippet:
<tr ng-repeat="data in ioStatusData">
<td><input type="checkbox"></td>
<td>{{data.IOStatusName}}</td>
<td>{{data.IOLabel}}</td>
<td>{{data.IOStatus}}</td>
<td>{{data.TestResult}}</td>
</tr>
scope.ioStatusData keeps updating every 5 secs.I want to retain checkbox state (checked or unchecked) even when scope.ioStatusData changes.
You are trying to check the row is selected or not ignoring the data. Define an object in your controller that store the row state like
$scope.rowState = {};
And change the checkbox model like
<input type="checkbox" ng-model="rowState['index_' + $index]" />
Actually ng-repeat create dynamically rowState object like rowState.index_0, rowState.index_1
Check the Demo
You need to have
<input type="checkbox" ng-model="myCheckboxIsChecked[$index]">
and in controller:
$scope.myCheckboxIsChecked = [];
And your checbox state will be there even if the values of your array are changing.

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>

How to dynamically add input rows to view and maintain value in angularjs ng-model as array item

I have a situation where I want the user to dynamically add <input> rows when they want to enter a new item. As shown below, the user clicks the "Add Input Item" button and a new input element is added where the user may add text.
I'm trying to associate each input element value to the model $scope.items (an array) in app.js. In my index.html, I load the $scope.items using an ng-repeat.
What I do not understand is how I can get each input/row to automatically be added to & managed by the model defined as $scope.items.
Is it possible to map each input element to an ng-model that relates to the items array and, if so, how? Or, should directives be used in this situation?
The full code and runtime is on Plunker here (so that you can view the weird output).
Snippet from index.html:
<body ng-controller="MainCtrl">
<button ng-click="addInputItem()">+ Add Input Item</button>
<div ng-repeat="item in items">
<input ng-model="items" type="text" value="{{item}}" size="40">
</div>
<pre>items = {{items | json}}</pre>
</body>
The app.js code:
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.items = ['First Item', 'Second Item'];
$scope.addInputItem = function() {
$scope.items.push('');
};
});
The first problem is with the binding on the input boxes. Due to the ng-repeat surrounding the input box, each input box has an item value available to bind to, and that is what your ng-model should be. You shouldn't be assigning anything to the value attribute.
<input ng-model="item.value" type="text" size="40">
Making that change will at least get the input boxes to display the items. But typing in the boxes won't update the underlying array. That's the second problem.
The ng-repeat directive prototypically inherits the scope from your controller (read more about scope here). Since your items are primitive strings, the elements in your ng-repeat effectively get copies of the data from the controller, and typing in the boxes updates those copies, not the actual data in the controller.
To fix this, just make your items an array of objects instead of an array of strings.
$scope.items = [
{value:'First Item'},
{value: 'Second Item'}
];
Then you would bind your textboxes like this:
<input ng-model="item.value" type="text" size="40">
Here's a Plunker showing how it works.
This certainly is possible, check out this updated plnkr
I updated your array to be an array of objects (not strings) with a property of text and changed your inputs to this:
<input ng-model="item.text" type="text" size="40">

Resources