I have two objects, one of users and one of groups. The user object contains the ids of the groups the user is part of, and the groups object contains the id, name and type of group (i.e. hierarchy).
Examples below:
users = {
"user_id_1": {
id: "user_id_1",
name: "Steve Smith",
username: "ssmith1",
groups: ["group_id_1", "group_id_3",...]
},
...
}
groups = {
"group_id_1": {
id: "group_id_1",
name: "Group 1",
type: "level_1"
},
...
}
The goal is (at least initially) to have two dropdowns, one for groups and one for users. Selecting a group filters the user list to only show users part of that group.
I've been looking at ui-select to create the dropdowns for me (the input box as part of the dropdown is ideal) or just simple typeahead (but it does lack the dropdown options).
For now I have a simple example for the users dropdown:
<select id="user-dropdown">
<option ng-repeat="user in $ctrl.users" value="{{ user.id }}">{{ user.name }}</option>
</select>
The problem is that Angular filters only allow filtering of arrays and not objects.
I had the idea of creating two arrays from the objects:
userArray = [user_id_1, user_id_2, ...];
groupArray = [group_id_1, group_id_2, ...];
<option ng-repeat="user in $ctrl.userArray" value="{{ $ctrl.users[user].id }}">{{ $ctrl.users[user].name }}</option>
Even in this case I had problems filtering this list based on the group, as it no longer has the group available in the object.
Any help or thoughts would be appreciated please.
First, reduce your object to an Array and then on select of group dropdown, filter your users. sample code below:
JS:
$scope.groupArray = [];
for(var prop in $scope.groups){
$scope.groupArray.push($scope.groups[prop]);
}
var userArray = [];
for(var prop1 in $scope.users){
userArray.push($scope.users[prop1]);
}
$scope.onGroupSelect = function(){
$scope.userList = [];
$scope.userList = userArray.filter(function(user){
return user.groups.some(function(group){
return group === $scope.selectedGroup;
})
})
}
HTML:
<select ng-model="selectedGroup" ng-change="onGroupSelect()"
ng-options="group.id as group.name for group in groupArray">
</select>
<br/>
<select ng-model="selectedUser">
<option ng-repeat="user in userList" value="user.id">
{{user.name}}
</option>
</select>
here is the working plunkr for your reference
Related
<select
get-sport
name="sportId"
id="sportId"
ng-model="sm.sport_id"
ng-change="changeSport()"
ng-options="sport.sport_id as sport.name for sport in sports track by sport.sport_id"
ng-required="true">
<option value="" selected="selected">-- Select Sport--</option>
</select>
return {
scope : true,
link : function (scope) {
scope.spinning = true;
$http.get('v1/sport')
.success(success)
.error(error);
function success(data){
scope.sports = data.data;
scope.spinning = false;
}
function error(error) {
console.log(error);
}
}
};
In my console Array [ Object, Object, Object, Object, Object, Object, Object, Object, Object ]
Object having name : cricket, sport_id : '1'
Into my sm.sport_id getting value 3 it should be equal to name : football, sport_id : 3 but by default it is selecting blank value i don't understand why please guide thanks a ton in advance
your answer is here
"you just can't combine value as label for collection with track by. You have to pick the one or the other.".
<select ng-model="sport" ng-options="sport as sport.name for sport in sports track by sport.id">
an in this case you can only get the selected sport as your selected option not the id of that
$scope.sports = [{id: 1, name: 'Cricket'}, {id: 2, name: 'Hockey'}, {id: 3, name: 'Football'}]
$scope.sport = $scope.sports[0];
If you want remove blank in option and dont initialize value for it . Add ng-if in option .
<select
get-sport
name="sportId"
id="sportId"
ng-model="sm.sport_id"
ng-change="changeSport()"
ng-options="sport_id as sport.name for sport in sports track by sport_id"
ng-required="true">
<option value="" ng-if="hideOption" selected="selected">-- Select Sport--</option>
</select>
I overcome this point myself the sport_id need to convert fr4om integer to string i did so it work like a charm
I have option list of some types like car, bus in format like this: <option value="BUS" label="Bus">Bus</option> and when I want to count the length of the list I use angular.element(element[0].options).length in Chrome it returns the correct length, but on Internet Explorer it returns 1
Use element[0].options.length directly, instead of wrapping it in angular.element(). If your list is data driven (which I recommend) then you can also just check the length of your array that contains the data.
var list = document.getElementById('list');
console.log('list.options.length = ' + list.options.length);
<select id="list">
<option>A</option>
<option>B</option>
<option>C</option>
</select>
Regarding the data driven list, ideally you should have an array of vehicles/transports/anything (might be complex objects with properties or just unique strings). Once you expose that array to the view (via scope or this from controllerAs syntax) then you can generate the list of options using ngOptions. For example:
Controller JS:
$scope.items = [{
id: 1,
label: 'aLabel',
subItem: { name: 'aSubItem' }
}, {
id: 2,
label: 'bLabel',
subItem: { name: 'bSubItem' }
}];
Template HTML:
<select ng-options="item as item.label for item in items track by item.id" ng-model="selected"></select>
In html page i take one select box and put data in them by fetching records from databases like that..
<select id="category" ng-model="eventAdd.data.selCategory" ng-change="changeBg(eventAdd.data.selCategory)">
<option value="">-Select-</option>
<option ng-repeat="photo in photos"
value="{{photo.PhotoId}}">
{{photo.Category}}
</option>
<option value="other">Other</option>
</select>
In select box i add one option "Other" if user select that option i will show one input box there user can enter custom name and i will push it $scope.photos and it will display in selectbox but it can be not be selected.
Photo.allCategory().then(function(photos)
{
$timeout(function()
{
$scope.photos = photos;
},0);
});
$scope.changeBg = function(val)
{
if(val=="other")
{
$cordovaDialogs.prompt('Category name', 'Category', ['Ok','Cancel'], '')
.then(function(result)
{
console.log("call");
var input = result['input1'];
$scope.photos.push({photoId:9,Category:input});
$scope.eventAdd.data.selCategory = 8;
});
}
}
Using this line
$scope.eventAdd.data.selCategory = 3;
Third i item can be selected but when i am doing like
$scope.eventAdd.data.selCategory = $scope.photos.length;
It cannot be selected which last one added by in prompt.
Please check by codepan
http://codepen.io/pareshgami/pen/BooEap
Please help. Thanks for your time.
I am developing a mobile application where there is a view where there are two select tags first select tag consist of options of teams & in the second select tag there are forms associated with team Ids that user select in first select tag. I want to filter the data of second select tag as per the team Id of first select tag on ng-change event.
For the first select tag i have populated as follows:
<select ng-change="showForms(name.id)" ng-model="name" ng-options="f.name for f in devices track by f.id"></select>
my second select tag is this:
<select ><option ng-repeat="formEach in forms" id="{{formEach.Formid}}">{{formEach.Formname}}</option></select>
Here my concern is i dont want to show any forms that are present inside the forms array initially when user is about to select team. When user selects team, the forms with the selected teams id associated should be shown in the second select tag. How the filtering will be occur or is it on same page or through controller. I am familiar with PHP but task is in angular & am new to angularJS.
Thanks in advance for quick response.
Sample data is this:
devices = [
{id : X001, name :'Team 1', icon: 'ion-document-text', status : 'Owner', color : 'brown'},
{id : X002, name :'Team 2', icon: 'ion-document-text', status : 'Owner', color : 'yellow'},
{id : X003, name :'Team 3', icon: 'ion-document-text', status : 'Owner', color : 'black'}
];
forms data is this:
forms= [
{id : AS001, teamid: X001, formname :'Feam 1', icon: 'ion-document-text', status : 'Active'},
{id : AS002, teamid: X001, formname :'Feam 2', icon: 'ion-document-text', status : 'Draft'},
{id : AS003, teamid: X003, formname :'Feam 3', icon: 'ion-document-text', status : 'Draft'}
];
controller code is this: (controller logic is not written as am confused of populating the data as am filling the array at the time of navigation to this view)
$scope.showForms = function(teamId){
}
You can do this by simply following below trick. I've used the same in one of my project.
<select class="custom-select" ng-model="teamName" data-ng-options="f.id as f.name for f in devices" ng-change="updateTeamObject($index, teamName);">
<option value="">Select Team</option>
</select>
and in your second select, just use.
<select class="custom-select" ng-model="deviceForms" data-ng-options="o.id as o.formname for o in forms | filter:{teamid:teamName}">
<option value="">Your team data</option>
</select>
Fiddle
Try this:
<div ng-app>
<div ng-controller="TodoCtrl">
<select ng-change="showForms(name.id)" ng-model="name" ng-options="f.name for f in devices"></select>
<select ng-model="selected">
<option ng-repeat="formEach in forms| filter:{teamid:name.id }" id="{{formEach.id}}">{{formEach.formname}}</option>
</select>
</div>
</div>
Demo: http://jsfiddle.net/U3pVM/15890/
Explanation:
Important part is
ng-repeat="formEach in forms| filter:{teamid:name.id }"
Note how the filter is used. Specify the property (i.e. teamid in your case) where you want the filter to be applied. Since model name stores the selection, you can filter the next select dropdown by using name.id . For testing, just select the last option in the first select dropdown in the demo, the next dropdown will have the filtered results.
You can achieve it by pushing the items you want in the second select tag's array at the time of ng-change event of the first tag
In the ng-change function, push items into the array like this in the controller,
$scope.specifications = [];
angular.forEach($scope.allSpecifications, function(spec) {
if(spec.id == id) {
$scope.specifications.push(spec)
}
});
In Html use that array
<select ng-change="showSpec(car.id)" ng-init="car = carsList[0]" ng-model="car" ng-options="car.name for car in carsList"></select>
<select>
<option ng-repeat="primitive in specifications" id="{{primitive.id}}">{{primitive.name}}</option>
</select>
I have done one plunker with a sample JSON,
Working Plunker
Hope this helps!
I have an object as below. I have to display this as a drop-down:
var list = [{id:4,name:"abc"},{id:600,name:"def"},{id:200,name:"xyz"}]
In my controller I have a variable that carries a value. This value decided which of the above three items in the array will be selected by default in the drop-down:
$scope.object.setDefault = 600;
When I create a drop-down form item as below:
<select ng-model="object.setDefault" ng-options="r.name for r in list">
I face two problems:
the list is generated as
<option value="0">abc</option>
<option value="1">def</option>
<option value="2">xyz</option>
instead of
<option value="4">abc</option>
<option value="600">def</option>
<option value="200">xyz</option>
No option gets selected by default even though i have ng-model="object.setDefault"
Problem 1:
The generated HTML you're getting is normal. Apparently it's a feature of Angular to be able to use any kind of object as value for a select. Angular does the mapping between the HTML option-value and the value in the ng-model.
Also see Umur's comment in this question: How do I set the value property in AngularJS' ng-options?
Problem 2:
Make sure you're using the following ng-options:
<select ng-model="object.item" ng-options="item.id as item.name for item in list" />
And put this in your controller to select a default value:
object.item = 4
When you use ng-options to populate a select list, it uses the entire object as the selected value, not just the single value you see in the select list. So in your case, you'd need to set
$scope.object.setDefault = {
id:600,
name:"def"
};
or
$scope.object.setDefault = $scope.selectItems[1];
I also recommend just outputting the value of $scope.object.setDefault in your template to see what I'm talking about getting selected.
<pre>{{object.setDefault}}</pre>
In View
<select ng-model="boxmodel"><option ng-repeat="lst in list" value="{{lst.id}}">{{lst.name}}</option></select>
JS:
In side controller
$scope.boxModel = 600;
You can do it with following code(track by),
<select ng-model="modelName" ng-options="data.name for data in list track by data.id" ></select>
This is an old question and you might have got the answer already.
My plnkr explains on my approach to accomplish selecting a default dropdown value. Basically, I have a service which would return the dropdown values [hard coded to test]. I was not able to select the value by default and almost spend a day and finally figured out that I should have set $scope.proofGroupId = "47"; instead of $scope.proofGroupId = 47; in the script.js file. It was my bad and I did not notice that I was setting an integer 47 instead of the string "47". I retained the plnkr as it is just in case if some one would like to see. Hopefully, this would help some one.
<select ng-init="somethingHere = options[0]" ng-model="somethingHere" ng-options="option.name for option in options"></select>
This would get you desired result Dude :) Cheers
Some of the scenarios, object.item would not be loaded or will be undefined.
Use ng-init
<select ng-init="object.item=2" ng-model="object.item"
ng-options="item.id as item.name for item in list"
$scope.item = {
"id": "3",
"name": "ALL",
};
$scope.CategoryLst = [
{ id: '1', name: 'MD' },
{ id: '2', name: 'CRNA' },
{ id: '3', name: 'ALL' }];
<select ng-model="item.id" ng-selected="3" ng-options="i.id as i.name for i in CategoryLst"></select>
we should use name value pair binding values into dropdown.see the
code for more details
function myCtrl($scope) {
$scope.statusTaskList = [
{ name: 'Open', value: '1' },
{ name: 'In Progress', value: '2' },
{ name: 'Complete', value: '3' },
{ name: 'Deleted', value: '4' },
];
$scope.atcStatusTasks = $scope.statusTaskList[0]; // 0 -> Open
}
<select ng-model="atcStatusTasks" ng-options="s.name for s in statusTaskList"></select>
I could help you out with the html:
<option value="">abc</option>
instead of
<option value="4">abc</option>
to set abc as the default value.