Migrating from angularjs select to selectize empty value - angularjs

Currently I use angularjs select directive, I have a choice to reset to None value
<select ng-model="myModel" ng-options="selectOptions">
<option value="">None</option>
</select>
When I select the None option myModel is null
{{ myModel === null }} // true
I want to have the same behaviour with angularjs selectize so I am adding an option with "" value.
onInitialize: function(selectize) {
selectize.addOption({id: '', name: 'None'});
}
So when I choose none with selectize my model is an empty string and not null
{{ myModel === null }} // false
How can I change this to null ?
Is it possible to do it without writing a new directive ?

You can assign to id value null, 0 (zero) or let it undefined like this:
onInitialize: function(selectize) {
selectize.addOption({id: null, name: 'None'});
// selectize.addOption({id: 0, name: 'None'});
// selectize.addOption({name: 'None'});
}
and check it like this:
{{ !myModel }}
As an alternate solution you could just check against the '' (empty value) like this:
{{ myModel === '' }}

I have found a way by extending the plugin on
scope.$watch('ngModel', setSelectizeValue);
var setSelectizeValue = function() {
if(scope.ngModel === '') {
scope.ngModel=null;
}
Still looking for a way without extending the plugin.

Related

Update Angular dropdown after insert and select new value

I'm fairly new to Angular and was wondering how I can update a dropdown after doing an insert and have the new value selected?
I tried the following:
<select class="form-control" ng-model="selectedCompany" ng-change="GetCompany()"
ng-options="company.key as company.value for company in CompanyList">
<option value="">Select a Company</option>
</select>
This populates a list of companies when the page 1st loads and the inserted data is returned to scope + it's id.
To add the new value without refreshing the page, I'm trying the following non-working (almost) code:
var key = $scope.company.id;
var value = $scope.company.name;
$scope.CompanyList.push({ key: value });
$scope.selectedCompany = $scope.company.id;
This seems to add a value to the dropdown, but it's showing up blank. It's also not selecting the blank value (which should be the new company name), any help would be appreciated.
It seems that when you create the new company object, you need to assign the value property which is the display name.
Here's a code snippet:
angular.module("myApp", [])
.controller("testCtrl", function() {
this.companyList = [{
key: 1,
value: "Company A"
}];
var ctrl = this;
this.addCompany = function() {
ctrl.companyList.push({key:2, value:"Company B"});
ctrl.selectedCompany = 2;
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="testCtrl as ctrl">
<select class="form-control"
ng-model="ctrl.selectedCompany"
ng-options="company.key as company.value for company in ctrl.companyList">
<option value="" disabled>Select a Company</option>
</select>
<button ng-click="ctrl.addCompany()">
Add company B and select it
</button>
</div>
Ok, so what do we have here?
You're creating your options with the ngOptions directive like this: ng-options="company.key as company.value for company in CompanyList"
That mean that the array $scope.CompanyList must have objects with a key property that will be set to the option value attribute, and a value that will be the option display value (Or label, if you prefer to call it that way).
What you were doing wrong: You added an object with only one property named key and set its value with the value variable: $scope.CompanyList.push({ key: value });
How should you fix it: You need to append object(s) with a key and a value like so: $scope.CompanyList.push({ key: key, value: value });
The following line push an object, which has a property name "key" set to value:
$scope.CompanyList.push({ key: value });
The result will be:
{'key': $scope.company.name}
You may change it to:
$scope.CompanyList.push({key: key, value: value});
Which will result in:
{ 'key': $scope.company.id, 'value': $scope.company.name }

ng change and ng select not working

So first the ng change is not triggering the search function. And the ng selected also no selecting the id = 0 option, is putting a blank option instead of selecting option 1. This is all contain the same in app and same controller.
Any ideas?
Code here
<select ng-model="OrderBy" ng-change="Search(true)">
<option ng-repeat="x in OrderByList" value="{{x.ID}}"
ng-selected="{{ x.ID == 0 }}">{{x.Name}}</option>
</select>
$scope.OrderByList = [
{ Name: "option1", ID: 0 },
{ Name: "option2", ID: 2 }
];
$scope.Search = function (x) {
// Code
};
Thanks.
You should look into ng-options, it'll probably work better for you.
<select
ng-model="OrderBy"
ng-change="Search(true)"
ng-options="x.ID as x.Name for x in OrderByList">
</select>
This will probably fix both issues.
In your controller do this:
$scope.OrderBy = 0;

How do I change the titles of the select options, but keep the values the same?

So I have an simple array values = [0, 1] and it will be supplied to
<select ng-model="myValue" ng-options="v for v in values "></select>
After this, i will have a dropdown list having two options: 0 and 1.
But what I want are:
In the web page, I don't want to show 0 or 1, but false and true.
Once a user select an option (either false or true), the real model myValue should be 0 or 1, not false or true.
How can I do this?
Flat array initialisation won't let you do this with standard ng-options as the label is the first part of the ng-options initialisation.
ng-options="label for v in values"
To do this properly, your options would be better formatted like so:
$scope.values = [
{ label : 'true', value: 1 },
{ label : 'false', value: 0 }
];
This would allow you to define the option label from the object in the for loop
<select ng-model="myValue" ng-options="v as v.label for v in values"></select>
If you want/have to stick with your current setup you could do something along the lines of:
var initialValues = [0,1];
$scope.values = [];
// Assuming ES5
initialValues.forEach(function(value, index)
{
$scope.values.push({
label : (!!value).toString(),
value : value
});
});
And modify the HTML to be as above.
According to the documentation for ngOptions, you can use an expression of the form select as label for value in array, in which label can be any correct AngularJS expression. You can use, for instance:
<select
ng-model="myValue"
ng-options="value as (value ? 'true' : 'false') for value in values"
></select>
Fiddle
This can be acceptable when you have just a few number of possible values, but it becomes quickly unreadable if your array grows larger:
<select
ng-model="myValue"
ng-options="value as (value === 1 ? 'true' : value === 0 ? 'false' : value === -1 ? 'undefined') for value in values"
></select>
In such a case, I strongly advise you to use an object, as suggested by David Barker.

Setting default value in select drop-down using Angularjs

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.

Strange binding/validation behaviour when binding select list to booleans

Can anybody explain me the following strange binding/validation behaviour when binding a select list to boolean values?
Selecting "Yes" (true) works as expected. Selecting "No" (false) obviously does not:
JSFIDDLE:
http://jsfiddle.net/mhu23/ATRQG/14/
$scope.trueFalseOptions = [{
value: true,
label: 'Yes'
}, {
value: false,
label: 'No'
}];
<select name="parameter" required ng-model="myModel" ng-options="x.value as x.label for x in trueFalseOptions"></select>
Am I doing something wrong? I would like to be able to select "Yes" or "No" from a dropdown list. The values of the option items should be true or false (boolean, not string).
Thanks for your help!
It looks like the required directive does not consider a value of false to be valid and sets your model value to undefined:
Github source link:
var validator = function(value) {
if (attr.required && (isEmpty(value) || value === false)) {
ctrl.$setValidity('required', false);
return;
} else {
ctrl.$setValidity('required', true);
return value;
}
};
Here are some options:
Use ngRequired instead of required. This lets you choose a custom required expression like: ng-required="!(myModel == true || myModel == false)". Here is a fiddle with an example.
You can create your own modified required directive that will allow false
Bind to something else (1 and 0 or "true" and "false" like you mentioned)
Also note you may want to add an empty option value so the first item doesn't say "Yes" after you select it:
<select name="parameter" ng-model="myModel" ng-options="x.value as x.label for x in trueFalseOptions">
<option value=""></option>
</select>

Resources