md-select can't set selected value - angularjs

I have a md-select set up as follows:
<md-select placeholder="Category" ng-model="current.Category" flex >
<md-option ng-repeat="item in categories" ng-value="{{item}}">{{item.Name}}</md-option>
</md-select>
#scope.categories value is
[
{
"Name":"Commercial & Industrial",
"ParentId":null,
"Categories":[
{
"Name":"Deceptive Marketing",
"ParentId":19,
"Categories":[
],
"Id":24,
"ModifiedDate":"2015-08-06T07:49:53.0489545",
"CreatedDate":"2015-08-06T15:49:51.707"
},
{
"Name":"Aggressive Agents",
"ParentId":19,
"Categories":[
],
"Id":25,
"ModifiedDate":"2015-08-06T07:50:10.0026497",
"CreatedDate":"2015-08-06T15:50:08.63"
}
],
"Id":19,
"ModifiedDate":"08/06/2015 # 7:49AM",
"CreatedDate":"08/06/2015 # 3:49PM"
},
{
"Name":"Competitive Supply",
"ParentId":null,
"Categories":[
{
"Name":"Security Deposit",
"ParentId":20,
"Categories":[
],
"Id":21,
"ModifiedDate":"2015-08-06T07:49:30.3966895",
"CreatedDate":"2015-08-06T15:49:25.8"
},
{
"Name":"Meter",
"ParentId":20,
"Categories":[
],
"Id":22,
"ModifiedDate":"2015-08-06T07:49:34.6571155",
"CreatedDate":"2015-08-06T15:49:33.3"
},
{
"Name":"Bill",
"ParentId":20,
"Categories":[
],
"Id":23,
"ModifiedDate":"2015-08-06T07:49:41.7268224",
"CreatedDate":"2015-08-06T15:49:40.357"
}
],
"Id":20,
"ModifiedDate":"08/06/2015 # 7:49AM",
"CreatedDate":"08/06/2015 # 3:49PM"
}
]
The md-select works fine. But what I can't figure out is how to set select value. When I try setting the model current.Category to one of the values from the $scope.categories it doesn't get set.

The documentation isn't explicit, but you should use ng-selected. I've created a codepen to illustrate, but basically:
<md-option ng-repeat="(index,item) in categories" ng-value="{{item}}"
ng-selected="index == 1">
{{item.Name}}
</md-option>
This'll select the the second category (index 1 in your category array).

You need to use ng-model-options, trackBy and choose a unique model field as a selector:
<md-select placeholder="Category"
ng-model="current.Category"
ng-model-options="{trackBy: '$value.Id' }" // <-- unique field 'Id'
flex >
<md-option
ng-repeat="item in categories"
ng-value="{{item}}">{{item.Name}}</md-option>
</md-select>
This solution is described in Angular Material's official documentation.

in order to set the default value of select you can use ng-selected and ng-model
<md-select ng-model="vmIdPage.number">
<md-option ng-value="mod" ng-repeat="mod in vmIdPage.initObject.listeModaliteMisePlace" ng-selected="{{ mod.id === vmIdPage.number.id ? 'true' : 'false' }}">
{{mod.libelle}}
</md-option>
</md-select>

This solution is simple if you are wanting to default to the first value in the drop down.
Use the ng-select="$first". This will default the drop down to the first value.
<md-select placeholder="Categories" ng-model="current.category">
<md-option ng-repeat="(index, item) in categories" value="{{item}}"
ng-selected="$first">{{item.Name}}</md-option>
</md-select>
Here is a CodePen to demonstrate.

In my case adding ng-model-options="{trackBy: '$value.id'}" as described in the docs did not work, as no initial value was set. By explicitly setting the model to the wished default value in the controller properly set the value as desired. This approach might be easier if you do not know up front the index of the element you want to display as pre-selected (using ng-selected). Of course you can evaluate it in the controller, but to me it seems more immediate to set the target element directly to the model.
View:
<div class="input-style-border">
<md-select ng-model="vm.selectedGlobalFilter">
<md-option ng-value="item" ng-repeat="item in vm.globalFilterValues">
{{item.value}}
</md-option>
</md-select>
</div>
Controller:
function initialize() {
vm.globalFilterValues = globalFilterValues;
vm.selectedGlobalFilter = TransferGlobalFilter.Worldwide;
}
Where globalFilterValues are in the form:
[
{key:"All", value:"All values" },
{key:"Manager", value:"Manager"},
{key:"HR", value:"Human resources"},
]

Use value in ng-option insted of ng-value

Like specified in the doc of md-select directive , you can use ng-model-options.
See this post

Related

angularjs filter ng-options by options already selected

So, I have a md-select based on a JSON I receive. These options have a "type" property that I can filter by as seen below:
$scope.data = [
{name:"1-1",Id:1,type:1},
{name:"2-2",Id:2,type:2},
{name:"3-2",Id:3,type:2},
{name:"4-2",Id:4,type:2},
{name:"5-3",Id:5,type:3},
{name:"6-3",Id:6,type:3}
];
<md-select multiple class="form-control" ng-model="selectedIds">
<md-option ng-value="item.Id" ng-repeat=""item as (item.Name) for item in data">
{{item.Name}}">
</md-option>
</select>
But what I need is to filter the options showed in the select using the options already selected in the same dropdown. So if I select the option "3-2", the dropdown would show only "2-2, 3-2 and 4-2". How can I do that?
Could find a solution for this using this other question:
On change, I get the selected type using a filter by the selected Id, and then use the type as filter to the options. Also, if no option selected, the "selectedType" should be set to nothing, otherwise it filtered by the first option's type.
<md-select multiple class="form-control" ng-model="selectedIds"
ng-change="selectedType=(selectedIds.length=0)?'':(data|filter:{Id:selectedIds})[0].type">
<md-option ng-value="item.Id" ng-repeat="item in data | filter : selectedType">
{{item.Name}}">
</md-option>
</select>

How to add title for selected value in md-select?

I am having md-select like :
<md-select ng-model="someModel" title={{someModel}}>
<md-option ng-value="opt.id" ng-repeat="opt in neighborhoods2">{{ opt.name }}</md-option>
It shows opt.id value in title.But I have to show opt.name in title.How to add a title attribute for the selected value's name?
for that you have to select object in ng-value like
<md-select ng-model="someModel" title={{someModel.name}}>
<md-option ng-value="opt" ng-repeat="opt in neighborhoods2">{{ opt.name }}</md-option>
</md-select>
but make sure in your controller you will get an object so you have to get id as
if(angular.isString(someModel)){
var myValue= JSON.parse(someModel).id;
}
Instead of setting the value to opt.name, you could use the opt object itself as the value. That way, your md-select model will have the name and id of whatever item is selected.
Here's a codepen: https://codepen.io/standard/pen/JKKeEy

check for changes in md-select in angular

I'm trying to check for changes in the md-select, but I'm not able to achieve it with $dirty
<div class="resourceForm" ng-form="resForm{{$index}}">
<md-select name="resourceAllocForm" id="id{{resourceContent.activityId}}-{{x}}" ng-model="selRes[$parent.$index][x]" placeholder="Select Resource" class="md-no-underline" ng-keyup="resourceCheck($parent.$index)">
<md-option ng-value="resource.id" ng-repeat="resource in resourceList track by resource.id">{{resource.roleProLabel}}</md-option>
</md-select>
</div>
and I have tried something like this
$timeout(function(parentIndex){
$scope.resourceAllocForm['resForm' + parentIndex].$dirty;
console.log('Form Edited');
}
You need something like this,
<md-select ng-change="show(resource)" ng-model="selectedresource">
<md-option ng-repeat="resource in resourceList track by resource.id" value="{{resource.id"}}">{{resource.roleProLabel}}
</md-option>
<md-select>
and in controller
$scope.show = function(resource){
console.log(show);
}

pre select option using ng-model-options

This is my scope.projectArr array
scope.projectArr = [
{
"proName":"fffff",
"proId":"12"
},
{
"proName":"project 0001",
"proId":"13"
},
{
"proName":"ABC website",
"proId":"7"
}
];
Again i have a another object that has a property called project and contain a string value
$scope.timesheet = {};
$scope.timesheet.project = "ABC website";
my question is i want all the array element as options and pre select an option based on $scope.timesheet.project value. I tried this using ng-model-options="{trackBy: $value.proName}" But unable to do so
here is the html
<md-select placeholder="Project" ng-model="timesheet.project"
flex ng-model-options="{trackBy: $value.proName}">
<md-optgroup label="Project">
<md-option ng-repeat="item in projectArr" ng-value="item">{{item.proName}} </md-option>
</md-select>
i tried using curly brackets inside ng-value but the same result.
i look up the inspect element to check whether values assign to options but it show as [object object]
`
Please note that i'm using angular material and as far for my knowledge ng-option is not available in the material.
don't get confuse by the vm.projectArr in the image. i'm using controllerAs in my app but for simplicity sake i post this question as scope variables.
Update
You can make use of ng-model-options like below:
You missed quotes around trackBy expression
<md-select placeholder="Project" ng-model="timesheet.project" flex ng-model-options="{trackBy: '$value.proName'}">
<md-optgroup label="Project">
<md-option ng-repeat="item in projectArr" ng-value="item">{{item.proName}} </md-option>
</md-select>
In your controller use below:
$scope.timesheet = {
'project': {
'proName': "ABC website"
}
};
Updated Plunker
I was able to get it working by using
$scope.timesheet = {
'project': arrFilter($scope.projectArr, 'proName', 'ABC website')[0]
};
arrFilter method: this method takes an array, property name, property value and returns the array from array of objects.
function arrFilter(arr, prop, val) {
return arr.filter(function(v) {
debugger;
return v[prop].indexOf(val) > -1
}) || [];
}
Working demo
Plunker
Explanation:
Since your options getting objects, you should provide the same object reference which arrFilter is doing.
The reason for doing so is, in javascript object comparison is done by reference not value.
Example:
{} never equals to {}
but a={}, b=a and a equals b
Try this,
ng-value ="item.proId"
<md-select placeholder="Project" ng-model="timesheet.project"
flex ng-model-options="{trackBy: $value.proName}">
<md-optgroup label="Project">
<md-option ng-repeat="item in projectArr" ng-value="item.proId">{{item.proName}} </md-option>
</md-select>
Initialize your model in the controller as
$scope.timesheet.project = $scope.projectArr[2]
Or in your view as
<div ng-init="timesheet.project = projectArr[2]">
<md-select placeholder="Project" ng-model="timesheet.project" flex>
<md-optgroup label="Project">
<md-option ng-repeat="item in projectArr">{{item.proName}}</md-option>
</md-select>
</div>
This will initialize it to 3rd object and show 'ABC website'
It should be like to this
$scope.timesheet = {};
$scope.timesheet.project = $scope.projectArr[0];
Edit:
<md-select placeholder="Project" ng-model="timesheet.project" >
<md-option ng-repeat="item in projectArr"
ng-value="item.proName"> {{item.proName}} </md-option>
</md-select>
and init like this
$scope.timesheet.project = $scope.theStringValue; //ABC website
or similar to this
<md-select placeholder="Project" ng-model="timesheet.project" >
<md-option ng-repeat="item in projectArr"
ng-value="item.proId"> {{item.proName}} </md-option>
</md-select>
and for default selected value
angular.forEach($scope.projectArr,function(proj){
if(proj.proName == $scope.theStringValue)
$scope.timesheet.project = proj.proId;
})

Get data from md-select

I am using Angular Material to make my new web app, I want to get the selected value from an <md-select> and the problem is that I am new to angularjs and how it works. If anyone could help me, it would be really appreciated.
HTML :
<md-input-container>
<label>Rating</label>
<md-select ng-model="userRating">
<md-option><em>None</em>
</md-option>
<md-option ng-repeat="rate in ratings" ng-value="rate.abbrev">
{{rate.abbrev}}
</md-option>
</md-select>
</md-input-container>
You can just get the value by using the $scope variable
In controller
console.log($scope.userRating);
Inorder to get the selected value on change , you can pass the selected to a function and display,
<md-select ng-change="Print()" class="inline-flex md-select-down" placeholder="Select" ng-model="model">
<md-option ng-repeat="item in ratings" value="{{item.value}}">
{{item.abbrev}}
</md-option>
</md-select>
Controller:
$scope.Print = function(){
alert($scope.model);
}
DEMO

Resources