Binding Object key with value in ng-model - javascript

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

Related

Dynamic V-model name in a v-for loop Vue 2

I am developing an application and I am using Vue 2 as the javascript framework,
inside a v-for loop I need the counter of the loop to be bound to the v-model name of the elements, this my code:
<div v-for="n in total" class="form-group">
<input type="hidden" id="input_id" :name="'input_name_id[' + n + ']'" v-model="form.parent_id_n" />
</div>
I need n to be the counter of the loop, for example for the first element it should be:
<div class="form-group">
<input type="hidden" id="input_id" :name="'input_name_id[1]" v-model="form.parent_id_1" />
</div>
the name attribute binding works but I have no idea how to get the v-model working as well?
To use v-model with form.parent_id[n]:
form should be a data property.
form.parent_id should be an array.
Then you can do the following:
<div id="demo">
<div v-for='n in 3'>
<input v-model="form.parent_id[n]">
</div>
<div v-for='n in 3'>
{{ form.parent_id[n] }}
</div>
</div>
by having a vue instance setup like:
var demo = new Vue({
el: '#demo',
data: {
form: {
parent_id: []
}
}
})
Check this fiddle for a working example.
Another way achieve this is using bracket notation of accessing object property.
<div v-for="n in total" class="form-group">
<input type="hidden"
id="input_id"
:name="'input_name_id[' + n + ']'"
v-model="form['parent_id_' + n ]" />
</div>
Repeated text filed 10 times and separated v-model for each
<v-text-field
v-for="(n,index) in 10"
:key="index"
v-model="pricing.name[n]"
color="info"
outline
validate-on-blur
/>
storing data
data() {
return {
pricing:{
name: [],
}
}
When you modify an Array by directly setting an index (e.g. arr[0] = val) or modifying its length property. Similarly, Vue.js cannot pick up these changes. Always modify arrays by using an Array instance method, or replacing it entirely. Vue provides a convenience method arr.$set(index, value) which is syntax sugar for arr.splice(index, 1, value).
this code worked for me:
HTML
<input type="number" #input="updateValue($event, i, 'pci')" :value="form.neighbours[i].pci" />
JS
updateValue(event, i, key) {
const neighbour = {...this.form.neighbours[i]};
neighbour[key] = event.target.value;
this.form.neighbours.splice(i, 1, neighbour)
}
Assuming input_name_id is a string, What you need to do is :name="'input_name_id' + n"
Here is a working solution

ng-repeat display key value in view

http://jsfiddle.net/qq2L34eb/1/
I want to display Monday but the value attr is equal to one using ng-repeat.
$scope.days = [{
"Mondays": 1
}, {
"Tuesdays": 2
}];
But I got the entire object instead.
http://jsfiddle.net/qq2L34eb/1/
Any clue?
You need to use another ng-repeat inside,
<div ng-controller="MyCtrl">
<span ng-repeat="(key, value) in days">
<span ng-repeat="(key, value) in value">
<input type='checkbox' value="{{value}}" check-list='checked_days'> {{key}}
</span>
</span>
</div>
DEMO
http://jsfiddle.net/sajeetharan/2obrb921/
2 things -
1) Your object array can be changed.
Your $scope.days is an array, it should be object instead.
Like this
$scope.days = {
"Mondays": 1
,
"Tuesdays": 2
}
See fiddle
2) If you don't wish to change object array then add another ng-repeat within that like this. Like #Sajeetharan mentioned -
<span ng-repeat="(key, value) in days">
<span ng-repeat="(key, value) in value">
<input type='checkbox' value="{{value}}" check-list='checked_days'> {{key}}
</span>
</span>
According to your js fiddle in html write---
<span ng-repeat="pp in days">
<input type='checkbox' value="{{pp.key}}" check-list='checked_days'> {{pp.value}}
</span>
In Controller---
$scope.days = [{
"key": "1","value":"Monday"
}, {
"key": "2","value":"Tuesday"
}, ]
you can find result like this--
js fiddle
http://jsfiddle.net/qq2L34eb/2/

Two way binding an array of strings in ng-repeat

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/

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>

Angularjs dynamic directives

Note: I'm quite new to angularjs
What is the best solution/practice for problem:
I have an array or typed values, for each type there should be different input(template and input validation)?
E.g. and simplified
var vars = [
{
type: 'int',
value: 42,
min: 0,
max: 42
},
{
type: 'text',
value: 'foobar'
},
]
for 'int' template will be
<input type="range" max="{{max}}" min="{{min}}" value="{{value}}" />
and for 'text'
<textarea>{{value}}</textarea>
In real case there will be quite many inputs with weird interfaces
An ng-switch (docs) can help you out here; something like this:
<div ng-repeat="item in items">
<div ng-switch on="item.type">
<div ng-switch-when="int">
<input type="range" max="{{item.max}}" min="{{item.min}}"
ng-model="item.value" />
</div>
<div ng-switch-when="text">
<textarea ng-model="item.value"></textarea>
</div>
</div>
</div>
[Update]
Since you mentioned you want to dynamically include a template based on the type, take a look at ng-include (docs) which takes an Angular expression evaluating to a URL:
<div ng-repeat="item in items">
<div ng-include="'input-' + item.type + '-template.htm'"></div>
</div>
If you don't like the inline string concatenation, you can use a controller method to generate the URL:
<div ng-repeat="item in items">
<div ng-include="templatePathForItem(item)"></div>
</div>
The example on the ngInclude documentation page is pretty good.
Note that the included template will be given a prototypal child scope of the current scope.

Categories