How to translate ids to objects in ng-option angular? - javascript

I have array of ids and I need to use this array as source of my ng-option directive inside of select. I certainly could find objects with corresponding id in my collection and create an array of objects to use it instead of array of ids but I wonder is there a way of doing it dynamicaly somehow? Like setting a function as source of ng-option?

You can do it with the help of filtering by id inside ngOptions directive expression:
angular.module('demo', []).controller('MainCtrl', function($scope) {
$scope.ids = [1, 4];
$scope.objects = [
{id: 1, name: 'One'},
{id: 2, name: 'Two'},
{id: 4, name: 'Four'}
];
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.6/angular.min.js"></script>
<div ng-app="demo" ng-controller="MainCtrl">
<pre>{{objects}}</pre>
<pre>{{ids}}</pre>
<select ng-model="model"
ng-options="id as (objects | filter:{id: id})[0].name for id in ids">
</select>
{{model}}
</div>

Related

convert ng-repeat to ng-option error

I have this following html code for select tags.
<option ng-repeat="option in AllData" value="{{item.Id}}" ng-selected="data.Symbol==item.Id">{{item.Symbol}}</option>
I want to convert this to ng-options. can someone please shed some light on this.
the value of AllData is as follows. It is an array of objects.
0:Object
Id: 1
Symbol: "GR"
1:Object
Id: 2
Symbol: "DR"
I tried something like this but was not successful.
ng-options="item as item .Symbol for item in AllData track by item.Id">
Try this
<select ng-options="option as option.Symbol for option in AllData">
</select>
when using ngOptions, you have to also bind ng-model with the initial value of select.
mention that since you used track by item.Id, the default value should at least contains property Id and meets the one of the items Id property.
refer the below sample:
angular.module("app", [])
.controller("myCtrl", function($scope) {
$scope.AllData = [{
0: Object,
Id: 1,
Symbol: "GR"
}, {
1: Object,
Id: 2,
Symbol: "DR"
}];
//$scope.data = $scope.AllData[0];
$scope.data = {
0: Object,
Id: 1,
Symbol: "GR"
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<div ng-app="app" ng-controller="myCtrl">
<select ng-model="data" ng-options="item as item.Symbol for item in AllData track by item.Id"></select> {{selectedItem}}
</div>

SELECT --> OPTION, using value vs ngValue

I just recently figured out that there is an alternative for value property on OPTION part of the SELECT, namely ngValue. The docs really lack documentation about this (all I could find: https://angular.io/docs/ts/latest/api/forms/index/NgSelectOption-directive.html). Anyway, the idea is that when you use an object for the ngModel, you can use ngValue and it works well. Otherwise, only e.g. ID is updated. If we're having just an array of strings, value is sufficient. Here are the examples:
{{myModel | json}}
<select [(ngModel)]="myModel">
<option *ngFor="let i of items" [ngValue]="i">{{i.value}}</option>
</select>
<br /><br />
{{mySimpleModel}}
<select [(ngModel)]="mySimpleModel">
<option *ngFor="let i of simpleItems" [value]="i">{{i}}</option>
</select>
While this works as expected, there's a distinctive differences between the two: if using ngValue, the predefined value is not selected in the drop down, whereas for the primitive types, the value is selected on loading. E.g.:
items: any[] = [{id: 1, value: 'item1'}, {id: 2, value: 'item2'}, {id: 3, value: 'item3'}];
myModel: any = {id: this.items[1].id , value: this.items[1].value};
simpleItems: string[] = ['item1', 'item2', 'item3'];
mySimpleModel: string = this.simpleItems[1];
See example here: https://plnkr.co/edit/JBrtmx7QkPZztBjaqYkS?p=preview
So, why does Angular set the default value for strings, but not for objects? And what is the most elegant workaround?
You don't need a "workaround" for that. When you do this
myModel = {id: this.items[1].id , value: this.items[1].value};
you are creating a new object which has the same values as this.items[1] but it is not the same object, it's a new one.
const items = [{id: 1, value: 'item1'}, {id: 2, value: 'item2'}, {id: 3, value: 'item3'}]
const myModel = {id: 2, value: 'item2'};
console.log(items[1] === myModel);
that is the reason why your select can't find that value in the <option> list.
In order to fix that, you have to use a proper reference
items = [
{id: 1, value: 'item1'},
{id: 2, value: 'item2'},
{id: 3, value: 'item3'}
];
myModel = this.items[1]
plunkr
In order to obtain default selected option using [ngValue] you can use [compareWith].
Just change in the method compareObj the correct atribute for the Object your comparing.
<select [compareWith]="compareObj" [(ngModel)]="selectedObject">
<option *ngFor="let object of objects" [ngValue]="object">
{{object.name}}
</option>
</select>
compareObj(o1: Object, o2: Object) {
return o1.id === o2.id;
}

Angular equivalent of index() from jquery

I use Angular 1.5. I have two selects and I need to update 2nd select depending on the index of the option of 1st select.
Is there an easy way to get the index of option selected? Like from 0 to 5.
My 1st select is :
<select class="form-control" name="idEtablissement" ng-model="infosEtab.idEtablissement" ng-change="updateContrats()"
ng-options='item.id as item.name for item in listeEtablissement'>
</select>
I need something like that :
// return -1, listeEtablissement is [{id: 2, name: 'Test'}, {...}]
alert($scope.listeEtablissement.indexOf($scope.infosEtab.id));
$listeEtablissement is :
[{id: 2, name: 'Test'}, {id: 5, name: 'Test 2'}]
But I need to have the index, like 0 or 1.
EDITED
Ok I'll use Javascript approach, the most simple one :
$scope.updateContrats = function() {
var index = document.getElementById('idEtablissement').selectedIndex;
// ....
}
You should do it by native JavaScript using array.findIndex(); like in this runnable demo fiddle.
MDN reference of array.findindex()
View
<div ng-controller="MyCtrl">
<select class="form-control"
name="idEtablissement"
ng-model="infosEtab.idEtablissement"
ng-change="updateContrats()"
ng-options='item.id as item.name for item in listeEtablissement'>
</select>
</div>
AngularJS Application
var myApp = angular.module('myApp', []);
myApp.controller('MyCtrl', function($scope) {
$scope.selectedIndex = null;
$scope.listeEtablissement = [{
id: 2,
name: 'Test'
}, {
id: 5,
name: 'Test 2'
}];
$scope.updateContrats = function() {
$scope.selectedIndex = $scope.listeEtablissement.findIndex(function(item) {
return item.id === $scope.infosEtab.idEtablissement
});
}
});
Change
ng-options
to
index as item.name for (index, item) in listeEtablissement

Filtering only specific fields in objects by following OR operator with AngularJS

I have a list of items. Example of one item:
{"id":7,"name":"ItemName","status":"Active","statusFrom":"2016-01-04T00:00:00","development":"Started","devStartedFrom":"2016-01-04T00:00:00","owner":"Owner"}
I would like the filter to look only in name, status and owner and return either (OR operator) objects. When filter is defined like this:
<tr ng-repeat="item in items | filter: {name:myFilterquery, status:myFilterquery, owner:myFilterquery}">
The filter returns objects by following AND operator.
How would you define a filter to query only by specific fields of an object, but following the OR operator?
You can do your own filtering where you get to chose OR over AND:
[
{id: 123, name: 'abc'},
{id: 456, name: 'xyz'},
{id: 999, name: 'qwe'},
].filter(item => item.id === 123 || item.name === 'xyz') // [{id: 123, name: 'abc'}, {id: 456, name: 'xyz'}]
Update: Ah, you meant in the mark-up!
Answered here?: How to filter multiple values (OR operation) in angularJS
Picked up the angular-filter library and defined the solution this way:
<tr ng-repeat="item in items | filterBy : ['name', 'status', 'owner'] : filterQuery">

Angularjs Multidimensional array and two relative select boxes

I have a multidimensional array that holds the product names and versions.
I want to create an interface that lets the user select the product from a select box, and then the version number in the second select box. The second select box should only show the versions numbers of the product that the user selected in the first select box.
This is my mutidimensional array:
[Object]0:
name: "Product 1"
versions: [Array]0:
number: "1.0"
number: "1.5.2"
1:
name: "Product 2"
versions: [Array]0:
number: "0.0"
number: "0.5"
The user has the option to choose multiple products, so I created an array to hold the users selection.
my controller is setup like this:
app.controller('mainController', function ($scope) {
$scope.products = [{id: 1, name: '', versions: []}];
$scope.packages = [];
$scope.packages[0] = { id: 1, name: 'Product 1', versions: [{number: 1.0}, {number: 1.5}, {number: 2.0}]};
$scope.packages[1] = { id: 2, name: 'Product 2', versions: [{number: 0.1}, {number: 0.2}, {number: 0.3}]};
$scope.addProduct = function(){
var id = $scope.products.length + 1;
$scope.products.push({id: id, name: "", version: []});
};
});
And the select boxes are setup like this with angularjs:
<div ng-repeat="product in products">
<label>Product</label>
<select ng-model="product.product" ng-options="package.name for package in packages" class="form-control"></select>
<label>Version</label>
<select ng-model="product.versions" ng-options="version.number for version in product.versions" class="form-control"></select>
</div>
<button ng-click="addProduct()">Add Product</button>
What I tried to do was setup the ng-options to select the versions object of the current product. But this doesn't work.
I created a jsFiddle of what I currently have:
http://jsfiddle.net/rkyu4rjq/
I would really appreciate any suggestions on how to link the version select box with the product selected.
TIA
Eventhough I'm not really keeping track of which version chosen for each product I fixed your relative select options.
You can find a solution here. This should get you on your way!
I missed something very simple.
In the version select box binding I should of used version.number for version in product.product.versions instead of version.number for version in product.versions
Here is a working jsFiddle: http://jsfiddle.net/rkyu4rjq/2/

Categories

Resources