AngularJS: Preselecting Options on Multiple Select - angularjs

I'm trying to preselect options on my multiselect. In order to make my case clear, I've made a JSFiddle.
<select ng-model="properties" id="props" multiple
ng-options="option.name group by option.category for option in options"></select>
Unfortunately, I am bound by the way the object is received, so I guess I need the ng-options attribute.
Does anybody have an idea how I can get both 'Captain America' and 'Dr. Doom' selected on load?

Try changing your controller code to:
function TestCtrl($scope) {
var myOptions = [{
"id": "4",
"name": "Captain America",
"categoryId": "1",
"category": "Heroes"
}, {
"id": "5",
"name": "Iron Man",
"categoryId": "1",
"category": "Heroes"
}, {
"id": "10",
"name": "Magneto",
"categoryId": "2",
"category": "Vilains"
}, {
"id": "9",
"name": "Dr. Doom",
"categoryId": "2",
"category": "Vilains"
}];
$scope.options = myOptions;
$scope.properties = [myOptions[0], myOptions[3]];
}
Explanation: you are setting your selected options (properties) to different instances of the objects than the ones that compose the full list. Use the same object references as shown above.

You are super close, two changes. Define the attributes in your controller like this
$scope.properties = ["Captain America", "Dr. Doom"];
And add a small piece to your ng-options like this
ng-options="option.name as option.name group by option.category for option in options"
Your option.name as will determine what the saved feature looks like in $scope.properties

Related

What would be angular ng-option equivalent of this select?

I am struggling to get this into an ng-option. Is it even possible?
<select ng-model="detail_type_id">
<optgroup ng-repeat="type in data.detailTypes" label="{{type.name}}">
<option ng-repeat="t in type.children" value="{{t.id}}">{{t.name}}</option>
</optgroup>
</select>
DetailTypes looks like this:
[
{"id":7,
"parent_id":null,
"name":"Contact",
"children":[
{"id":8,
"parent_id":7,
"name":"Address",
"children":[]
},
{"id":12,
"parent_id":7,
"name":"Something else",
"children":[]
}
]},
{"id":16,
"parent_id":null,
"name":"Other",
"children":[
{"id":10,
"parent_id":16,
"name":"Remarks",
"children":[]}
]
}
]
Child id needs to be selected. Nesting cannot be deeper.
The ngOptions directive does not work with multidimensional objects. So you need to flatten your array to use it.
I wrote a filter for that:
app.filter('flatten' , function(){
return function(array){
return array.reduce(function(flatten, group){
group.children.forEach(function(child){
child.groupName = group.name;
flatten.push(child)
})
return flatten;
},[]);
}
})
And the HTML part would be like this:
<select ng-model="detail_type_id"
ng-options="item.id as item.name
group by item.groupName for item
in data.detailTypes | flatten track by item.id">
</select>
Plunker (version #1 with filter):
https://plnkr.co/edit/dxi7j8oxInv2VRJ1aL7F
I also modified your object to be like this:
[{
"id": 7,
"parent_id": null,
"name": "Contact",
"children": [{
"id": 8,
"parent_id": 7,
"name": "Address",
"children": []
}, {
"id": 12,
"parent_id": 7,
"name": "Something else",
"children": []
}]
}, {
"id": 16,
"parent_id": null,
"name": "Other",
"children": [{
"id": 10,
"parent_id": 16,
"name": "Remarks",
"children": []
}]
}]
EDIT:
After suggestion I wrote another version without the filter, but flattening the array inside the controller.
Additional Controller JS:
$scope.flattenDetailTypes = flattenDetailTypes($scope.data.detailTypes);
function flattenDetailTypes(array){
return array.reduce(function(flatten, group){
group.children.forEach(function(child){
child.groupName = group.name;
flatten.push(child)
})
return flatten;
},[]);
}
Markup:
<select ng-model="detail_type_id"
ng-options="item.id as item.name group by item.groupName for item in flattenDetailTypes track by item.id"></select>
Plunker (version #2 without filter):
https://plnkr.co/edit/D4APZ6

How to return only ids from a FireBase query?

Here is the code I have. It currently returns an array full of objects. How can i return an array full of the object ids, instead?
var ref = new Firebase('https://zip-it.firebaseio.com/zips');
$scope.detectChangeDigit1 = function() {
var query = ref.orderByChild("digit1").equalTo($scope.zipCode.firstDigit.toString());
$scope.digit1Array = $firebaseArray(query);
};
A few of your JSON objects (add these to your question next time please):
"20195": {
"city": "ALTURAS",
"digit1": "9",
"digit2": "6",
"digit3": "1",
"digit4": "0",
"digit5": "1",
"population": "3969",
"state": "CA",
"zipCode": "96101"
},
"20196": {
"city": "BLAIRSDEN-GRAEAGLE",
"digit1": "9",
"digit2": "6",
"digit3": "1",
"digit4": "0",
"digit5": "3",
"population": "1434",
"state": "CA",
"zipCode": "96103"
},
You're using AngularFire, which builds on top of the Firebase JavaScript SDK. That API will always load entire nodes, it has no option to only load object IDs.
To just get the IDs, you have a few options:
keep a separate list of only the IDs and load from that.
use the REST API, which supports a shallow=true parameter
prevent the query altogether and add a list of IDs for each digit1 value
Option 1 is tricky, given that you do an orderByChild().
Option 2 will not work either, since you cannot combine shallow=true with other query parameters.
Option 3 is likely going to be most performant. You still have two sub-options in there:
Store the entire objects under digit1:
"by_digit1":
"9":
"20195": {
"city": "ALTURAS",
"digit1": "9",
"digit2": "6",
"digit3": "1",
"digit4": "0",
"digit5": "1",
"population": "3969",
"state": "CA",
"zipCode": "96101"
},
"20196": {
"city": "BLAIRSDEN-GRAEAGLE",
"digit1": "9",
"digit2": "6",
"digit3": "1",
"digit4": "0",
"digit5": "3",
"population": "1434",
"state": "CA",
"zipCode": "96103"
},
Store only the ID of each object under the "index":
"by_digit1":
"9":
"20195": true,
"20196": true,
With both these two structure, you can immediately access the list of items that you're looking for with:
ref.child('by_digit1').child('9')
With this last structure you'll then look up each city in the main list.
ref.child('by_digit1').child('9').on('value', function(snapshot) {
snapshot.forEach(function(child) {
var cityRef = ref.child('zips').child(child.key());
cityRef.once('value', function(citySnapshot) {
console.log(citySnapshot.val());
});
});
})

select in ng-option does not update

I have the list of data that is coming from backend and I want to update the select value in the view which is not happening for some reason.
I tried ng-selected that does not works efficiently, sometime the model is update spmetimes not.
here is my code, can someone help?
<div class="listitem" ng-repeat="d in data">
{{d.name}}:
<select
ng-model="d.option"
ng-options="d.name for d in options"></select>
</div>
Controller
var myApp = angular.module('myApp', []);
myApp.controller("SomeController", function($scope) {
$scope.options = [{
"id": "id1",
"name": "p1"
}, {
"id": "id2",
"name": "p2"
}];
$scope.data = [{
"name": "data1",
"option": {
"id": "id1",
"name": "p1"
}
}];
});
http://jsfiddle.net/gFCzV/58/
You need to use select as label group by group for value in array track by trackexpr, Read DOCs
ng-options="option.name for option in options track by option.id"
DEMO, However note this will not work in Angualrjs 1.1
You have in your code:
$scope.options = [{
"id": "id1",
"name": "p1"
}, {
"id": "id2",
"name": "p2"
}];
$scope.data = [{
"name": "data1",
"option": {
"id": "id1",
"name": "p1"
}
}];
but Angular doesn't know that first option object used in $scope.options collection is same as option used in $scope.data.
I can suggest two solutions:
In $scope.data keep only option identifier "option": "id1" and in ng-options use d.id as d.name for d in options
In ng-options use "ng-options="d as d.name for d in options" and initialize $scope.data options like "option": $scope.options[0], but since it is coming from backend you may need to fix references manually.
Options 1 is better IMHO.
EDIT: Example JSFIDDLE was created in Angular 1.1, if you use Angular 1.2 or later #Satpal track by answer is also good option (no pun).

How to select specific option using ng-options

I am starting with an array of sources
$scope.sources = [
{
"type": "register",
"name": "Register 1",
"balance": 100
},
{
"type": "register",
"name": "Register 2",
"balance": 100
},
{
"type": "register",
"name": "Register 3",
"balance": 200
},
{
"type": "office",
"name": "Change Drawer",
"balance": 200
},
{
"type": "office",
"name": "Safe",
"balance": 500
}
];
I'm successfully loading the options
<div class="form-group">
<label>Transfer <strong>{{amount(count, start, selectedItem.balance) | currency}}</strong> To:</label>
<select id="transferTo" class="form-control" ng-model="form.to" ng-options="item.name for item in sources | filter:{type:'office'}">
<option value="">-- Select a Source --</option>
</select>
</div>
I've tried using a $timeout function to select it after it works, but it doesn't pass back the correct value to my function
$timeout(function () {
$('#transferTo').val('1');
}, 200);
How would I set the "Safe" as the default option selected when the form loads?
You will need to set a value on your scope that you're setting ng-model equal to:
$scope.form.to = $scope.sources[4];
If your list (sources) is dynamic you can filter the array like this, which will return an array (but leave your array untouched).
filterFilter($scope.sources, {name: 'Safe'})
fiddle

Angular do dependent Select

I want do a dependen select / dropdown.
I obtain this json sample:
[
{
"id": 15695,
"username": "user1",
"address": {
"id": 16794,
"location": "O TreviƱo de San Pedro"
},
"jobs": [
{
"id": 7562,
"name": "ut"
},
{
"id": 7565,
"name": "temporibus"
},
{
"id": 7603,
"name": "perspiciatis"
},
{
"id": 7622,
"name": "optio"
}
]
}
]
This is the angular code:
<select ng-model="industrialist.user" ng-options="user.id as user.username for user in users"></select>
<select ng-model="industrialist.job" ng-options="job.id as job.name for job in industrialist.user.jobs"></select>
If I do this code, then dependent select works but then i haven't de correct key in industrialist.user.
<select ng-model="industrialist.user" ng-options="user.username for user in users"></select>
What can I do?
Thanks
I believe what you need to do is save the whole user rather than the just the id. You can get the id out later if you need it.
<select ng-model="industrialist.user" ng-options="user.id as user.username for user in users"></select>
<select ng-model="industrialist.job" ng-options="job.id as job.name for job in industrialist.user.jobs"></select>
Here is a working fiddle. JSFiddle

Resources