concatenate an ng repeat item as an object inside ng-model - javascript

I'm trying to concatenate an ng-repeat item to ng-model object. I was wondering if this possible.
so for example:
//array
$scope.array = [
{
param: 'color',
....
},
{
param: 'weight',
.....
}
]
html
<div ng-repeat="item in array">
{{ item.param }}
<input type="text" ng-model="form.name.{{ item.param }}" >
</div>
so lets say {{ item.param }} is color, the ng-model will be form.name.color.
form object will be something like this:
{
name: {
color: 'value of input',
weight: 'value of input'
}
}
How can I concatenate the item.param to the object form.name? I've been trying so many ways but no results. I trying to use $index, but don't know where to begin.
Your help will be appreciated!

Check out this fiddle.
Your ng-model should look like this:
ng-model="form.name[item.param]"

Related

How to ignore property in angular filter

I'm trying to ignore a property called title in my angular filter. I have a dataset like the below example:
const data = [
{
title: 'Title 1'
groups: [
{...},
{...},
{...}
]
},
{
title: 'Title 2'
groups: [
{...},
{...},
{...}
]
},
{
title: 'Title 3'
groups: [
{...},
{...},
{...}
]
}
];
And i'm using the ng-repeat with filter to iterate over the objects, and other loop to iterate over the groups:
<input ng-model="search">
<div ng-repeat="item in data | filter:search">
<h1>{{item.title}}</h1>
<ul>
<li ng-repeat="group in item.group | filter:search">
<span>{{group.something}}</span>
</li>
</ul>
</div>
Is working fine, but now i would like to ignore the title in the search. I did try several things, like: filter:search:item.title (in the first ng-repeat), or remove the first filter:search, but all tries failed. What i'm missing? Do i need a custom search or something like that?
Thank you.
You can specifically enter properties you want to filter and leave out title:
<li ng-repeat="group in item.groups | filter: { something: search }">
The above code will only filter based on the something property.
More answers and explanations here: AngularJS filter only on certain objects
If you type and no filtering the title property, just remove the first filter. This way when you type the li's isnt match will hide, but their h1's will stay the same place.
You should create custom filter, where you can specify which property should be excluded(ignore parameter) from consideration:
angular.module('app', []).controller('MyController', ['$scope', function($scope) {
$scope.data = [
{name:"Tom", title:'London'},
{name:"Max", title:'Moscow'},
{name:"Henry", title:'NY'},
{name:"Paul", title:'NY'},
{name:"Sam", title:'Paris'}
];
}]).filter('myfilter',function(){
return function(input, search, ignore){
if(!search)
return input;
var result = [];
for(var item of input)
for(var prop in item)
if(prop != ignore && item[prop].indexOf(search) != -1)
{
result.push(item) ;
break;
}
return result;
}
});
<script src="//code.angularjs.org/snapshot/angular.min.js"></script>
<body ng-app="app">
<div ng-controller="MyController">
search: <input type='text' ng-model='search' ng-init='search="a"'/>
ignore: <input type='text' ng-model='ignore' ng-init='ignore="title"'/>
<ul>
<li ng-repeat='item in data | myfilter: search: ignore'>
{{item.name}} {{item.title}}
</li>
</ul>
</div>
</body>

Angular - Get ng-repeat object

I need to get the current object out of an ng-repeat on ng-click, I can't use $index because I'm using orderBy and therefore it gives me the wrong index relative to the scope object. Idealy I want to be able to click on the object (thumbnail) and have $scope.activePerson gain all that objects values.
My data is structured as follows:
[
{
'name': 'john'
},
{
'name': 'toby'
},
{
'name': 'sarah'
}
]
This is very much simplified, my real objects have 30+ KV pairs and subobjects. There are 10 objects that I'm repeating from (in batches of 4).
My current HTML is:
.item.fourth(ng-repeat="person in people | orderBy:'-name' " ng-show="$index <= 3" nid="{{person.guid}}"
Thanks
It's just person in ng-repeat="person in people";
I'm not sure what kind of markdown you're using, you definitely don't have html there, but you want something like:
<div
ng-repeat="person in people | orderBy:'-name' "
ng-show="$index <= 3"
nid="{{person.guid}}"
ng-click="activePerson = person">
</div>
Note that ng-repeat creates a child scope, so you'll want to have activePerson already set in the parent scope.
You can just use orderBy and copy the current object from ng-repeat, see this plunkr. Relevant code:
Controller
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.stuff = [
{
'name': 'john'
},
{
'name': 'toby'
},
{
'name': 'sarah'
}
];
$scope.setActivePerson = function (obj) {
$scope.activePerson = obj;
};
});
View
<body ng-controller="MainCtrl">
<div ng-repeat="thing in stuff | orderBy: 'name'">
<input type="radio" ng-click="setActivePerson(thing)" />
{{ thing.name }}
</div>
<br />
<div ng-model="activePerson">Active: {{ activePerson.name }}</div>
</body>

Dynamically bind objects to inputs in angular

I have these objects right here that I will use to save data from a form, and later send it to an api as JSON :
$scope.price = {}
$scope.item = {"price":$scope.price, };
I also have these field which will be used to dynamically generate inputs on a html page:
$scope.fields = [
{
name: $scope.item.title,
title: 'Title',
type: {
view: 'input'
}
},
{
name: $scope.price.regular,
title: 'Regualar Price',
type: {
view: 'input'
}
}
];
Now in order to generate the form I use this code:
<div class="form-group" ng-repeat="field in fields">
<label>{{ field.title }}:</label>
<span ng-switch on="field.type.view">
<span ng-switch-when="input">
<input
ng-model=field.name
type="text"
/>
</span>
</span>
</div>
And with this code, it is not assigning the values in the input to the objects. Is there a way to do it? I know I can do it this way:
ng-model="item[field.name]"
But that limits me to only one level of the object. I want to be able to bind nested objects. And I just can't seem to figure it out. Thank You!

Angular filter in ng-repeat with deep object

I am following this question to filter ng-repeat by a field
ng-repeat :filter by single field
However my case is different, it's actually a field in the object value of the main object. Basically I want to show only data.a == 1
The following code works on the first list. The second list gives me error:
angular.module('myapp', [])
.controller('mainCtrl', function ($scope) {
$scope.items = [{
name: "John",
data: {
a: 1
}
}, {
name: "Lee",
data: {
a: 2
}
}, {
name: "Rue",
data: {
a: 3
}
}, {
name: "Peter",
data: {
a: 1
}
}];
});
HTML
<div ng-controller="mainCtrl">
<h1>List 1</h1>
<p ng-repeat="item in items">{{ item.name }}</p>
<h1>List 2</h1>
<p ng-repeat="item in items | filter: {data.a :1}">{{ item.name }}</p>
</div>
http://plnkr.co/edit/nh4GryqZJbEiXSzMzTKk
Any help on how to do this or is there a nicer way?
UPDATE 1
I tried angular.filter filterBy and it didn't work either. Giving me blank array.
http://plnkr.co/edit/nh4GryqZJbEiXSzMzTKk?p=preview
<p ng-repeat="item in items | filterBy: ['item.data.a'] :1">{{ item.name }}</p>
UPDATE 2
I tried this below
<p ng-repeat="item in items | filter: {data :{a:1}}">{{ item.name }}</p>
It seems to work but I need exact match, not substring match. I read this but not seem to find a way to add true AngularJS Filter Exact Match
Any clue?
UPDATE 3 (CORRECT ANSWER):
This works http://plnkr.co/edit/qJl6MtY6fOlVtD9Rv999?p=preview
Basically I added this to the controller
$scope.filteredItems = $filter('filter')($scope.items, {data :{a:1}}, true);
and do ng-repeat on filteredItems instead. I don't see a way to pass true param in the view directly.
If you want to access the inner property you need to access it with object notation:
<p ng-repeat="item in items | filter: {data :{a:1}}">{{ item.name }}</p>
Check this plunker.
If you are using \ can upgrade to angular 1.3, then you can use this: 1.3 filters These are faster. In particular, you can use filterBy
See: plunkr example
<p ng-repeat="item in items | filterBy: ['data.a'] :1">{{ item.name }}</p>
Otherwise, use a custom function. See my answer here: custom function

How to set the selected value for multiple select elements in a single AngularJS context

I try to create multiple select elements on a AngularJS page in a single context. names is a array of available name objects and cores is the array with available cores. For each name, I would like to have a drop down with the available cores. This works fine, but I'm not able to pre-select the currently selected core. That one is stored in name.core.
<ul>
<li ng-repeat='name in names'>
{{ name.name }} - {{ name._url }} <span ng-click='delete_name(name)'>[x]</span>
<select ng-model='?'
ng-options='core.id as core.instance for core in cores'
ng-change='coreChanged(name, ?)'>
<option value=''>No core assigned</option>
</select>
</li>
</ul>
I'm quite new to AngularJS, so if another structure or additional controllers, scopes, ... would be more appropriate, I'm open for suggestions.
Update:
ng-model='name.core' as proposed by haki does not work, probably because name.core is not an instance from the cores array. I tried ng-model='name.core.id' but that results in every drop down having the same (wrong) selection.
This works fine for me:
<ul>
<li ng-repeat='name in names'>
{{ name.name }} - {{ name._url }} <span ng-click='delete_name(name)'>[x]</span>
<select ng-model='name.core'
ng-options='core.id as core.instance for core in cores'
ng-change='coreChanged(name)'>
<option value=''>No core assigned</option>
</select>
</li>
</ul>
Double-check on how your view corresponds to your model. My scope variables look like this:
.controller('MyController', function($scope){
$scope.names = [
{ name: 'Marc', url: 'http://www.example.com/one', core: "1" },
{ name: 'Achim', url: 'http://www.example.com/two', core: "2" },
{ name: 'Jenny', url: 'http://www.example.com/three', core: "3" }
];
$scope.cores = [
{ id: '1', instance: 'First' },
{ id: '2', instance: 'Second' },
{ id: '3', instance: 'Third' }
];
$scope.coreChanged = function(name){
console.log(name);
}
});
Working Plunker

Categories

Resources