I have this array of objects. that holds somethings like this.
[
{
id: 1,
name: "Extra Cheese"
},
{
id: 2,
name: "No Cheese"
}
]
im iterating thru the array here
<select ng-model="item.modifiers" multiple chosen class="chosen-select" tabindex="4" ng-options="modifier._id as modifier.name for modifier in modifiers"></select>
The thing item.modifiers model that has an array of this 2 id
[
1,2
]
I want the multi select to auto selected the two ids that are in the item.model
I want the final result to look something like this
Your code is pretty much working already, maybe some of the variables are not assigned correctly (eg. id instead of _id)
angular.module('test', []).controller('Test', Test);
function Test($scope) {
$scope.modifiers = [
{
id: 1,
name: "Extra Cheese"
},
{
id: 2,
name: "No Cheese"
}
]
$scope.item = {};
// add this for pre-selecting both options
$scope.item.modifiers = [1,2];
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js"></script>
<div ng-app='test' ng-controller='Test'>
<select ng-model="item.modifiers" multiple chosen class="chosen-select" tabindex="4" ng-options="modifier.id as modifier.name for modifier in modifiers"></select>
</div>
If I understand the question correctly, you're wanting to pre-select the two options.
To do this you will need to set your ng-model to point to the actual objects you are iterating over.
You will also need to change your ng-options to ng-options="modifier as modifier.name for modifier in modifiers" rather than just iterating over the ids.
Here's the relevant documentation under Complex Models (objects or collections)
https://docs.angularjs.org/api/ng/directive/ngOptions
Something like this should work:
HTML:
<select ng-model="$ctrl.item.modifiers"
ng-options="modifier as modifier.name for modifier in $ctrl.modifiers"
multiple chosen class="chosen-select" tabindex="4" >
</select>
JS:
app.controller("my-controller", function() {
var $ctrl = this;
$ctrl.modifiers = [{
id: 1,
name: "Extra Cheese"
}, {
id: 2,
name: "No Cheese"
}];
$ctrl.item = {
modifiers: []
}
$ctrl.$onInit = function() {
const id1 = 1;
const id2 = 2;
for (const modifier of $ctrl.modifiers) {
if (modifier.id === id1 || modifier.id === id2) {
$ctrl.item.modifiers.push(modifier);
}
}
}
}
Here's a pen showing the result:
http://codepen.io/Lahikainen/pen/WooaEx
I hope this helps...
Related
I have a product model that has a property I want to bind to a separate array of options. Basically by product model has a property called 'category', like this:
productModel = {
Id : 1,
Description: 'Widget',
Category: 0,
...
As you can see, the property is an int (from the db) but I also get a separate array of what the categories are:
Categories : [
{ "Number" : 0, Name : "N/A" },
{ "Number" : 1, Name : "Option 1" },
{ "Number" : 2, Name : "Option 2" }
]
I want to be able to have a select list with the corresponding value shown, so if the product model comes back with 0 set then the default value in the select list will be "N/A".
I have achieved this by doing:
<select ng-model="Categories[productModel.Category]" ng-options="v.name for v in Categories" ...
but the problem with this is that when I change the option the value isn't binding back to the model. Because the data is posted back the server when the user changes the value I don't really want to change the productModel to have the same Name and Number structure as the categories (I can do this if it is the best way). I really just want the user to be able to select an option and for the product model to contain the corresponding number.
Can I (should I) do this using the 'track by'?
You need to update your ng-model value to bind to productModel.Category, you also need to update your ng-options expression to the following ng-options="v.Name as v.Number for v in categories".
You can find more information regarding the ng-options and ng-model directives here.
Please see working example here
HTML:
<div ng-controller="TestController">
<select ng-model="productModel.Category" ng-options="v.Name as v.Number for v in categories"></select>
<h3>productModel.Catecogy => {{productModel.Category}}</h3>
</div>
JS:
var myApp = angular.module('myApp', []);
myApp.controller('TestController', ['$scope', function($scope) {
$scope.productModel = {
Id: 1,
Description: 'Widget',
Category: 0
};
$scope.categories = [{
"Number": 0,
Name: "N/A"
}, {
"Number": 1,
Name: "Option 1"
}, {
"Number": 2,
Name: "Option 2"
}];
}]);
Not relevant to the question but its good practice to try and keep the case of your properties and variable names the same.
I need filter for ng-repeat, that explode elements in "general" array, if element exist in "suggest" array (by id field).
$scope.general= [{id: 21323, name: 'alex'}, {id: 8787, name: 'maria'}, {id: 8787, name: 'artem'}];
$scope.suggest = [{id: 21323, name: 'alex'}, {id: 8787, name: 'maria'}];
<div ng-repeat="elem in general">{{elem.name}}</div>
You should create your own custom filter and you'll probably want to use Array.prototype.filter.
You said you wanted to exclude by the property id. The following filler optionally allows specifying a property. If the property is not specified, then the objects are excluded by strict equality (the same method used by the ===, or triple-equals, operator) of the objects.
angular.module('myFilters', [])
.filter('exclude', function() {
return function(input, exclude, prop) {
if (!angular.isArray(input))
return input;
if (!angular.isArray(exclude))
exclude = [];
if (prop) {
exclude = exclude.map(function byProp(item) {
return item[prop];
});
}
return input.filter(function byExclude(item) {
return exclude.indexOf(prop ? item[prop] : item) === -1;
});
};
});
To use this filter in your html:
<div ng-repeat="elem in general | exclude:suggest:'id'">{{elem.name}}</div>
Here is an example jsfiddle:
https://jsfiddle.net/6ov1sjfb/
Note that in your question artem's id matches maria's thus both artem and maria were filtered. I changed artem's id in the plunker to be unique to show that the filter works.
Try this :
var myApp = angular.module('myApp', []);
function MyCtrl($scope) {
$scope.general = [{
id: 21323,
name: 'alex'
}, {
id: 8787,
name: 'maria'
}, {
id: 8787,
name: 'artem'
}];
$scope.suggest = [{
id: 21323,
name: 'alex'
}, {
id: 8787,
name: 'maria'
}];
$scope.filteredArray = function () {
return $scope.general.filter(function (letter) {
for (i = 0; i < $scope.suggest.length; i++) {
return $scope.suggest[i].id !== letter.id
}
});
};
}
and
<div ng-repeat="elem in filteredArray(letters)">{{elem.name}}</div>
check out the fiddle : http://jsfiddle.net/o2er6msv/
Note: please chk ur id, they are duplicated
Does the built in Angular "filter" support filtering an array in the sense that "filter where array contains "
Such as follows:
$scope.currentFilter = "Allentown";
$scope.users = [{
name: "user1",
locations: [
{ name: "New York", ... },
{ name: "Allentown", ... },
{ name: "Anderson", ... },
]
}, ... ];
<div ng-repeat="user in users | filter : { locations: { name: currentFilter } }"></div>
In other words I'm looking to filter to only users with a "locations" array that CONTAINS a location that matches the string by name.
If not, how can I accomplish this with a custom filter?
Your code snippet works as is since Angular 1.2.13. In case you're using an older version (tested on 1.0.1) and don't need to reuse your filtering routine across controllers (in which case you should declare a proper filter), you can pass the built-in filter a predicate function :
<div ng-repeat="user in users | filter : hasLocation">{{user.name}}</div>
And write something like this :
$scope.currentFilter = "Allentown";
$scope.hasLocation = function(value, index, array) {
return value.locations.some(function(location) {
return location.name == $scope.currentFilter;
});
}
Fiddle here.
I have an object that maps IDs to their objects. I would like to display the list of these object and use a filter, but I cannot get it to work. Specifically, I'm trying to prevent object with ID 2 from appearing in the options Here's what I've got:
http://jsfiddle.net/9d2Za/
<div ng-app ng-controller="ctrl">
Unfiltered:
<select ng-model="selectedBidType"
ng-options="bidType.id as bidType.label for (bidTypeID, bidType) in bidTypes">
</select>
<br>
Filtered:
<select ng-model="selectedBidType"
ng-options="bidType.id as bidType.label for (bidTypeID, bidType) in bidTypes | filter:{id: '!2'}">
</select>
</div>
Please note: I cannot change the structure of the bidTypes object in whatever fix we come up with. Here's my AngularJS:
function ctrl($scope)
{
$scope.selectedBidType = 1;
// Bid type objects are indexed by ID for fast lookup (this cannot be changed in solution)
$scope.bidTypes = {
1: {id: 1, label: "Buy"},
2: {id: 2, label: "Sell"},
3: {id: 3, label: "Missing"}
};
}
As described by the documentation, the filter filter only accepts an array as first parameter, not an object. In such cases, I personally use a custom filter to make the transformation:
myModule.filter(
'objectToArray',
[
function ()
{
return function (object)
{
var array = [];
angular.forEach(object, function (element)
{
array.push(element);
});
return array;
};
}
]
)
;
And then, in the template:
<select ng-options="… in bidTypes | objectToArray | filter:{id:'!2'}">
I have a <select> that I am populating with a list of values. Everything works and I see the expected list. But now I would like to have the value set to a locally stored value if available.
I have the code below. When I run this code the number after the Type in the label changes to match that in the localstorage but the select box does not change.
getContentTypeSelect: function ($scope) {
entityService.getEntities('ContentType')
.then(function (result) {
$scope.option.contentTypes = result;
$scope.option.contentTypesPlus = [{ id: 0, name: '*' }].concat(result);
$scope.option.selectedContentType
= localStorageService.get('selectedContentType');
}, function (result) {
alert("Error: No data returned");
});
},
<span class="label">Type {{ option.selectedContentType }}</span>
<select
data-ng-disabled="!option.selectedSubject"
data-ng-model="option.selectedContentType"
data-ng-options="item.id as item.name for item in option.contentTypesPlus">
<option style="display: none" value="">Select Content Type</option>
</select>
Here is the code I have that sets the value in localstorage:
$scope.$watch('option.selectedContentType', function () {
if ($scope.option.selectedContentType != null) {
localStorageService.add('selectedContentType',
$scope.option.selectedContentType);
$scope.grid.data = null;
$scope.grid.selected = false;
}
});
Here is the data stored in contentTypesPlus:
0: Object
id: 0
name: "*"
__proto__: Object
1: b
id: 1
name: "Page"
__proto__: b
2: b
id: 2
name: "Menu"
__proto__: b
3: b
id: 3
name: "Content Block"
__proto__: b
How can I make the select box go to the localstorage value if there is one?
Update
Still hoping for an answer and I would be happy to accept another if some person can help me. The answer given is not complete and I am still waiting for more information. I am hoping someone can give me an example that fits with my code. Thanks
I think you need to make sure selectedContentType needs to be the id field of the option object according to the comprehension expression defined in the select directive.
The comprehensive expression is defined as
item.id as item.name for item in option.contentTypesPlus
item.id will be the actual value stored in the ng-model option.selectedContentType
Say this is your select with ng-model
<select
ng-model="language.selected"
ng-init="language.selected = settings.language[settings.language.selected.id]"
ng-options="l.label for l in settings.language"
ng-change="updateLanguage(language.selected)">
In your controller
$scope.settings = {
enableEventsNotification: true,
enableiBeaconNotification: true,
hours: [
{ id: 0, label: '3h', value: 3 },
{ id: 1, label: '6h', value: 6 },
{ id: 2, label: '9h', value: 9 },
{ id: 3, label: '12h', value: 12 },
{ id: 4, label: '24h', value: 24 }
],
language: [
{ id: 0, label: 'English', value: 'en-us' },
{ id: 1, label: 'Francais', value: 'fr-fr' }
]
};
$scope.hours = [];
$scope.hours.selected = $localstorage.getObject('hours', $scope.settings.hours[1]);
$scope.settings.hours.selected = $localstorage.getObject('hours', $scope.settings.hours[1]);
$scope.hours.selected = $scope.hours.selected;