Angular select populate dropdown? - angularjs

This is my JSON data:
[{
"table":"mCity",
"drpdownItems":[
{
"Display":"ab",
"Value":1
},
{
"Display":"a",
"Value":10
},
{
"Display":"Delhi",
"Value":7
},
{
"Display":"Devgad",
"Value":4
},
{
"Display":"Kalyan",
"Value":5
},
{
"Display":"Mumbai",
"Value":2
},
{
"Display":"Nashik",
"Value":9
},
{
"Display":"New Mumbais",
"Value":6
},
{
"Display":"Panji ",
"Value":8
},
{
"Display":"Pune",
"Value":3
}
]
}]
I want the following output:
<select>
<option value="1">ab</option>
<option value="10">a</option>
<option value="7">Delhi</option>
</select>
I tried following:
ng-options="City.Display as City.Value for drpdownItems in CmbsData.table['mCity']"

ng-options="City.Display as City.Value for drpdownItems in CmbsData[0].drpdownItems"
Cmbs is an array, and drpdownItems is a property of the object which is the first element of that array
Edit based on comment: generalized form
ng-options="City.Display as City.Value for drpdownItems in (CmbsData | filter:{table:'mCity'}).drpdownItems"

Update based on comment below:
<select
ng-options="City.Value as City.Display for City in (CmbsData | filter:{table:'mCity'}:true|limitTo:1)[0].drpdownItems"
ng-model="selectedCity">
</select>
In order to make a strict match, please use true in your filter. It is better to uselimitTo:1because there may be multiple matches.filterandlimitToalways result in an array. Since we are limiting by 1, we can use[0]` index to get the city we want.
Original answer:
You need to use like this
<select name="" id="" ng-options="City.Value as City.Display for City in CmbsData[0].drpdownItems" ng-model="selectedCity"></select>
The syntax of ng-options is _select_ (as _label_)? for (_key_,)?_value_ in _collection_

Related

can not map array inside of object

I am lost here, can not find a way how to map through an array that is inside of object. I have received an object from API that includes an array wit values like this:
{
"shelters": [
{
"id": 1,
"name": "Útulok pre psov - TEZAS"
},
{
"id": 2,
"name": "OZ Tuláčik Brezno"
}
]
}
now I need to iterate through the array that is inside and take action on every item to populate the DOM.
my code is:
render() {
// const { isPending, shelters} = this.props;
if (this.props.isPending === false) {
var listOfShelters = this.props.shelters;
console.log('loaded', typeof(listOfShelters), listOfShelters)
return (
<div>
<select style={this.selector} name="útulky" onChange={this.sendId}>
{ listOfShelters.shelters.map(function(shelter, i) {
<option id={shelter.id}>{shelter.name}</option>
})}
</select>
</div>
)
} else if (this.props.isPending === true) {
console.log('fetching')
return (
<select style={this.selector} name="útulky" onChange={this.sendId}>
<option id='0'> Nahravam Data... </option>
</select>
)}
}
I get typeof always an object even if I do this.props.shelters.shelters which should be direct access to that array. if I do this.props.shelters.shelters.map nothing happens, my list of shelters does not get populated. it stays empty. Where do I make the mistake here?
I have found what the problem was. I had different set of parentheses in the .map function, I was using {} instead of (). Now it works like a dream.

angular ui-select2 not set value in edit mode

<select id="e1" style="width:100%" ui-select2 tabindex="-1" ng-init="GetAllAgent()" ng-model="Agent" ng-options="ctr as ctr.AgentName for ctr in ListAgent track by ctr.AgentId" ng-change="GetSubAgentList(Agent.AgentId)">
<option value=""> </option></select>
when it is in edit mode,could not set the default value using the below code
angular.forEach($scope.ListAgent, function (value, index) {
if (value.AgentId == HR.AgentId) {
$scope.Agent = $scope.ListAgent[index];
}
})
$scope.ListAgent= [{ AgentId: "0", AgentName:"Ann" }, { AgentId: "1", AgentName:"Muh" }];
and
HR.AgentId=1
First off, ui-select2 does not support ng-options: https://github.com/angular-ui/ui-select2/issues/252
Further, ui-select2 does not work with ng-repeat: https://github.com/angular-ui/ui-select2/issues/162
The solution is to use input:
<input ui-select2="select2Options" ng-model="Agent"/>
where select2Options is:
$scope.select2Options = {
data:$scope.ListAgent
}
The list should have structure: [{id,text}] so $scope.ListAgent will be
$scope.ListAgent= [{ id:0, text:"Ann" }, { id:1, text:"Muh" }];
Demo Plunker
For place holder add data-placeholder="----"

AngularJS nested filter hiding elements without destined property

I'm using AngularJS on a project and I need to implement a select box with a filter to a nested property. My object (I have an array of those and I'm iterating through them via ng-repeat) has a structure similar to this:
{
id: 1,
name: 'Example',
groups: [
{ id: 1, name: 'Group 1' },
{ id: 2, name: 'Group 2' }
]
}
I need to filter the group ID of the elements, and after searching I've come up with two ways to do it:
1.
| filter: { $: { id: search.item_id } }
Which has these problems:
Apparently it searches for any nested properties named ID, so if I have more than one object inside my main object, with a property called ID too, it would add it to the filter. Example:
{
id: 2,
name: 'Example 2',
groups: [
{ id: 1, name: 'Group 1' },
{ id: 2, name: 'Group 2' }
],
categories: [
{ id: 1, name: 'Cat 1' },
{ id: 2, name: 'Cat 2' }
]
}
Filtering for ID 1 would select not only group with ID 1, but category with ID 1 too.
Also, with this method, even before setting the filter (search.item_id model is null), objects without groups are being filtered and not appearing in the list. These objects are like this:
{
id: 3,
name: 'Example 3',
groups: []
}
and the other way is:
2.
| filter: { groups: [{ id: search.item_id }] }
In this case, the problem is that it simply doesn't work, it filters everything, leaving the list blank, no matter if it's set or which option is selected.
How can I make it work? I've been searching and couldn't find anything about this. Filtering nested properties is (or should be) a very basic thing.
Update:
So, xtx first solution kinda did it, but only if I use input text or number, but I need to use a select box (more specifically uib-dropdown, but working in a regular select is the next step). My select box is looking like this:
<select name="filter_classes_groups_test" ng-model="search.group_id">
<option val="group.id" ng-repeat="group in classesGroups">{{ group.name }}</option>
</select>
When I interact with it, nothing happens.
If creating a custom filter works for you, here is how you can do that:
app.filter('groupsFilter', function() {
return function(input, groupId) {
var out = [];
if (!groupId || isNaN(parseInt(groupId))) {
return input;
}
angular.forEach(input, function(item) {
if (item.groups && angular.isArray(item.groups)) {
angular.forEach(item.groups, function (group) {
if (group.id === parseInt(groupId)) {
out.push(item);
}
});
}
});
return out;
}
});
As you can see, the custom filter has name groupsFilter, and takes group id to search for as a parameter. The filter can be applied like this:
<div ng-repeat="item in data | groupsFilter:search.item_id">
...
</div>
UPDATE:
Instead of creating a custom filter, you can just create a function that implements filtering logic, in scope like this:
$scope.groupsFilterLocal = function(value) {
if (!$scope.search.item_id || isNaN(parseInt($scope.search.item_id))) {
return true;
}
if (!value || !value.groups || !angular.isArray(value.groups)) {
return false;
}
for (var i = 0; i < value.groups.length; i++) {
if (value.groups[i].id === parseInt($scope.search.item_id)) {
return true;
}
}
return false;
};
and then apply it using build-in filter like this:
<div ng-repeat="item in data | filter:groupsFilterLocal ">
...
</div>
Notice that in this case you can't pass the value to search for (search.item_id) into your function groupsFilterLocal like it is done for the custom filter groupsFilter above. So groupsFilterLocal has to access search.item_id directly
UPDATE 2: How to create a select properly
The reason why the filter is not applied when you pick a group in your dropdown, is in the way how you defined the select. Instead of the id of the selected group, search.group_id gets assigned group's name.
Try defining the select like shown below:
<select name="filter_classes_groups_test" ng-model="search.item_id" ng-options="group.id as group.name for group in classesGroups">
<option value="">-- Choose Group --</option>
</select>
To ensure that search.item_id gets id of the group that is selected (and not its name), try temporarily adding {{ search.item_id }} somewhere in your template.

How can I set the initial value of a <select> with AngularJS?

I am using this code in my controller:
$scope.$watch('option.selectedPageType', function () {
if ($scope.isNumber($scope.option.selectedPageType)) {
localStorageService.add('selectedPageType', $scope.option.selectedPageType);
}
})
getPageTypes: function ($scope) {
$scope.option.pageTypes = [
{ id: 0, type: 'Edit Basic' },
{ id: 1, type: 'Edit Standard' },
{ id: 2, type: 'Report' }
];
$scope.option.selectedPageType = parseInt(localStorageService.get('selectedPageType'));
},
and in my HTML:
<select data-ng-model="option.selectedPageType"
data-ng-options="item.id as item.type for item in option.pageTypes">
<option style="display: none" value="">Select Page Type</option>
</select>
Instead of using the "Select Page Type" option. How can I make it so my code defaults to the value in local storage or if there is nothing there then to one of the values I have in my option.pageTypes list ?
Have your localStorageService return null if there is nothing stored. If it does exist, have the service return the integer
Then in controller:
/* assume want first item in array */
$scope.option.selectedPageType = localStorageService.get('selectedPageType') || $scope.option.pageTypes[0].id
Try using ng-init on the <select ...>:
<select data-ng-model="option.selectedPageType"
data-ng-options="item.id as item.type for item in option.pageTypes"
data-ng-init="option.selectedPageType=DEFAULT_VALUE">
See this fiddle: http://jsfiddle.net/CaeUs/5/

How do I set a selected option for select in Angular

I have an object
$scope.colleges = [{"CollegeCode":"40","CollegeName":"College1"},
{"CollegeCode":"35","CollegeName":"College2"},
{"CollegeCode":"32","CollegeName":"College3"},
{"CollegeCode":"15","CollegeName":"College4"}]
I'm populating a select element with it's contents
<select ng-model="collegeSelection" ng-options="c as c.CollegeName for c in colleges" name="selectCollege"></select>
It renders on the page like so
<select class="ng-pristine ng-valid" name="selectCollege" ng-options="c as c.CollegeName for c in colleges" ng-model="collegeSelection" style="" selected="selected">
<option value="?" selected="selected"></option>
<option value="0">College1</option>
<option value="1">College2</option>
<option value="2">College3</option>
<option value="3">College4</option>
etc....
I'm also binding this select to collegeSelection and when an item is selected the object look like this
$scope.collegeSelection = {"CollegeCode":"32","CollegeName":"College"}
When someone clicks edit on the page, the college I want selected by default comes from the userToUpdate object.
$scope.userToUpdate = {
Id: 1,
FirstName: 'John',
LastName: 'Doe',
CollegeCode: '35,
CollegeName: 'College2',
Active: true
};
When an edit button and the userToUpdate object is populated, I would like the college in the select element to be set to the college in the user object. How could one make this happen? FYI, the value in the rendered select does not match the CollegeCode. It seems angular uses the index from the colleges object. Thanks
Try this one
<select ng-model="collegeSelection" ng-options="c.CollegeCode as c.CollegeName for c in colleges" name="selectCollege"></select>
<span>{{collegeSelection}}</span>
<input type="button" ng-click="switch()" name="switch" value="switch" />
<script>
var app = angular.module('plunker', []);
app.controller('MainCtrl', function ($scope, $filter) {
$scope.colleges = [{ "CollegeCode": "40", "CollegeName": "College1" },
{ "CollegeCode": "35", "CollegeName": "College2" },
{ "CollegeCode": "32", "CollegeName": "College3" },
{ "CollegeCode": "15", "CollegeName": "College4" }
]
$scope.switch = function () {
$scope.collegeSelection = "32";
};
});

Resources