Two way binding an array of strings in ng-repeat - javascript

I have an array of strings, and I want each of the strings to be bound to an input.
However, editing the input doesn't seem to update the array (isolated scope issues maybe?).
Suggestions?
function Ctrl($scope) {
$scope.fruits = ['Apple', 'Mango', 'Banana', 'Strawberry'];
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app>
<div ng-controller="Ctrl">
<div style="margin: 20px 0" ng-repeat="fruit in fruits">
<input type="text" ng-model="fruit" />
</div>
Fruits: {{fruits}}
</div>
</div>

You need the array reference which you can get from $index. Note however that this won't work if any filtering is done on the ng-repeat as the indexing then is based on filtered array not the original
<div style="margin: 20px 0" ng-repeat="fruit in fruits track by $index">
<input type="text" ng-model="fruits[$index]" />
</div>
DEMO

Ok, so it seems to me like a case of
'ng-model requires a dot in the model name to work correctly with the
scope, otherwise it would create a local scope'
What i would suggest is to change your data structure from plain strings to objects containing the strings as a property, something like :
$scope.fruits = [
{'title':'Apple'},
{'title':'Mango'},
{'title':'Banana'},
{'title':'Strawberry'},
];
Now, when you bind it to ng-model like this
<div style="margin: 20px 0" ng-repeat="fruit in fruits">
<input type="text" ng-model="fruit.title" />
</div>
then it will not create any local/child scope, instead it would be able to bind to the title property on the items in the fruits array.
example fiddle: http://jsfiddle.net/HB7LU/24008/

Related

How to define a ng-model dynamically when using $index

I wan't to use $index in order to create a new $scope variable:
<div ng-repeat="i in items track by $index">
<input autocomplete="off" type="text"
ng-model="myVariableName{{$index}}" >
....
I wan't to declare the variable: myVariableName0, myVariableName1, etc...
In the controller declare empty object
$scope.myVariableName = {};
And in the template assign the model value as a property of an object.
ng-model="myVariableName[$index]"
Instead of doing this you can have an array, and each item of that array can refer to the current ng-model via ng-model="myVariableName[$index]"
angular.module('app', [])
input,
span {
display: block
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app='app'>
<input type='text' ng-repeat='temp in [0,1,2,3]' ng-model='$parent["myVariableName" + $index]' />
<span>0: {{myVariableName0}}</span>
<span>1: {{myVariableName1}}</span>
<span>2: {{myVariableName2}}</span>
<span>3: {{myVariableName3}}</span>
</div>

Add a value to the i variable of Angular's ngFor

I want to create two rows of five inputs using ngFor. I want to store the inputs in an array so I figured I would use the index in the ngModel. However, when I try to add a value for the second row to the let i = index, I get Template parse errors.
<div class="row" *ngFor="let row of [0,5]">
<div class="col-md-5ths" *ngFor="let number of [0,1,2,3,4]; let i = index + row">
<input type="text" [(ngModel)]="input[i]">
{{input[i]}}
</div>
</div>
I tried some variations with a ternary operator and ngForOf, but to no success. It seems Angular is a lot stricter than AngularJS in this regard.
Plunker here.
Any suggestions?
It can be achieved so:
<div class="col-md-5ths" *ngFor="let number of [0,1,2,3,4]; let i = index">
<input type="text" [(ngModel)]="input[i+row]">
{{input[i+row]}}
</div>

using ng-options within ng-repeat

I am new to angular and I'm confused over this thing. I'm trying to populate a select box based on object inside an array. I want selectbox by using ng-repeat for that array... but initially i need to show only one selectbox after clicking add() next selectbox has to come. for ref:[initially one selectbox has to come]
HTML
<div class="col-lg-12" id="variant1" style="margin-top:10px" ng-repeat="variant in variants">
<div class="col-lg-4" style="text-align:right;padding-top:2px;padding-right: 20px" >
<label for="variant1name">Variant Name</label>
</div>
<div class="col-lg-6" >
<div >
<select class="form-control" ng-model="filterFormInputs.apps" ng-options="app.Application for app in variants" >
<option value="" disabled selected>Select an Application</option>
</select>
<label ng-repeat="checkbox in filterFormInputs.apps.details">
<input class="ecomtexttype1" type="checkbox" ng-model="checkbox.checked"> {{checkbox.name}}
</label>
</div>
</div>
</div>
Controller:
$scope.variants =
[
{"Application": "Color", "details":[{"name":"red"},{"name":"blue"},{"name":"black"}]},
{"Application": "Color", "details":[{"name":"red"},{"name":"blue"},{"name":"black"}]},
{"Application": "Color", "details":[{"name":"red"},{"name":"blue"},{"name":"black"}]}
]
I think that you can just have your add() function update the array... if things are configured correctly the new row should render due to the binding on the array.
As mentioned in comments you did not provide enough source code, so here is the assumed pseudo-code:
in html you might have
<button ng-click="$scope.add()">Add</button>
so in the controller
$scope.variants = [
// array of whatever you are displaying
{"foo":"bar1"},
{"foo":"bar2"}
];
$scope.add = function() {
variants.push({"foo":"bar_new"});
}
Have you considered using a Directive for this? That may work better, depending on your situation. Look into this: https://docs.angularjs.org/guide/directive

Binding Object key with value in ng-model

I have a object which holds the key and value pair.
$scope.groups= {
1050 : 'Test',
1850 : 'Test1'
}
$scope.AnotherArray = [1050,1850];
item from ng-repeat is passed to the object as key to obtain the text 'Test'
<div ng-repeat="item in AnotherArray">
<input type="text" ng-model="groups[item]" />
</div>
Is there a way in angular to do this ?
As you were asking for an "Angular-way" to do this, here is a mildly modified version of Angular's ngRepeat example:
<div ng-repeat="(key, obj) in groups">
[{{key}}] {{obj}}
<input type="text" ng-model="obj"/>
</div>
http://plnkr.co/edit/0IRvLZpbUZUQBXOnebOt?p=preview
It makes use of Angular's internal conversion of array-like objects.
Link to Angular's ngRepeat-documentation: https://docs.angularjs.org/api/ng/directive/ngRepeat

how to bind angularjs objects to their keys and values

I read through some articles on angular model binding, and just out of curiousity, I was wondering if its possible to bind keys to input too,
http://jsfiddle.net/x3azn/jM28y/4/
so I am hoping ot update the main arr through the input boxes and achieve 2 way key-binding.
Is this possible?
as explained here Binding inputs to an array of primitives using ngRepeat => uneditable inputs, yes you can, but not that way
try this
function ctrl($scope) {
$scope.arr = [{name:'1', lastname: '2'},
{name:'3', lastname: '4'},
{name:'5', lastname: '6'}]
}
<div ng-repeat="person in arr">
<input type="text" ng-model="person.name" />
<input type="text" ng-model="person.lastname" />
</div>
http://jsfiddle.net/jM28y/5/
No, it is not possible to bind a key to an input.
The closest thing that I found you can do is abuse ngRepeat's $index property and bind it to the input. You can't change keys for existing values but you can change what value is shown as well as create new key-value pairs. By no means am I recommending this as a solution, I just wanted to share the hackery that ensued when I was investigating this question.
JSFiddle: http://jsfiddle.net/DanielBank/v6tFG/
JavaScript:
function ctrl($scope){
$scope.obj = {
'0': 'a',
'1': 'b',
'2': 'c',
'George': 'Clooney',
};
}
HTML:
<div ng-app>
<div ng-controller="ctrl">
<div ng-repeat="value in obj">
<input type="text" ng-model="$index"/>
<input type="text" ng-model="obj[$index]"/>
<input type="text" ng-model="value"/>
</div>
{{obj}}
</div>
</div>

Categories