Im currently doing a dropdown and getting the data via angular JS, but whenever i add ng-model="email_mobile" it adds an empty field
and I cant remove it, i tried doing the correct answers here but I dont think that its applicable because I am getting 2 values in 1 array:
JS
$scope.configs = [
{'email': 'email#gmail.com',
'phone': '123',
'value': 'config1'},
];
$scope.getValue = function(){
$scope.value =$scope.email_mobile;
console.log($scope.value )
}
blade
<select class="form-control" name="email_mobile" id="email_mobile" ng-model="email_mobile" ng-change="getValue()" required>
<option data-ng-repeat="x in configs" ng-if="x.email" value="#{{x.email}}" selected>#{{x.email}}</option>
<option data-ng-repeat="x in configs" ng-if="x.phone" value="#{{x.phone}}" selected>#{{x.phone}}</option>
</select>
another thing is, the reason why my code is like that, because I also need to get the value of ng-model="email_mobile" on change. I only need to remove the empty value while still getting the value of the dropdown on change
You can achieve this by setting the default value of select in the format of your options' value:
$scope.email_mobile = "#" + $scope.configs[0].email;
Check code below:
angular.module("myApp", [])
.controller("myCtrl", function($scope) {
$scope.configs = [{
'email': 'email#gmail.com',
'phone': '123',
'value': 'config1'
}];
$scope.email_mobile = $scope.configs[0].email;
$scope.getValue = function() {
$scope.value = $scope.email_mobile;
console.log($scope.value)
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myCtrl">
<select class="form-control" name="email_mobile" id="email_mobile" ng-model="email_mobile" ng-change="getValue()" required>
<option data-ng-repeat="x in configs" ng-if="x.email" value="{{x.email}}" selected>{{x.email}}</option>
<option data-ng-repeat="x in configs" ng-if="x.phone" value="{{x.phone}}" selected>{{x.phone}}</option>
</select>
</div>
How can I get the Broken example (below) to work without changing it from an array (as I have a lot of code that depends on it being an array in other parts of the application)?
I'd like to continue using an array but I'd like the correct select option to show when the model changes. The model changes correctly when the button is clicked but the option isn't being found in the select (ng-model and ng-options just aren't matching up when it's an array).
angular.module('app', [])
.controller('MainCtrl', ['$scope', function($scope) {
$scope.valueWorking = 'value1';
$scope.selectFilterWorking = [{name: 'name1', value: 'value1'},{name: 'name2', value: 'value2'}];
$scope.valueBroken = ['value1'];
$scope.selectFilterBroken = [{name: 'name1', value: ['value1']},{name: 'name2', value: ['value2', 'value3']}];
}]);
<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.1/angular.min.js"></script>
<div ng-app="app" ng-controller="MainCtrl">
<strong>Working</strong> (SELECT <i>is</i> updated when ng-model is a string):<br>
<select ng-model="valueWorking"
ng-options="select.value as select.name for select in selectFilterWorking">
<option value="">Select an Option</option>
</select>
<button ng-click="valueWorking='value2'">Assign to String of 'value2'</button> {{valueWorking}}<br><br>
<strong>Broken</strong> (SELECT <i>not</i> updated when ng-model is an array):<br>
<select ng-model="valueBroken"
ng-options="select.value as select.name for select in selectFilterBroken">
<option value="">Select an Option</option>
</select>
<button ng-click="valueBroken=['value2','value3']">Assign to Array of ["value2","value3"]</button> {{valueBroken}}
</div>
Upon clicking 'Run code snippet' above, notice that the initial option is not selected (on the Broken select, when it's an array), but is initially selected on the Working select when it's a string. The correct option is also not shown when 'Assign to Array of ["value2"]' is clicked.
UPDATE: I'm trying to get the OPTIONS ($scope.selectFilterBroken) to match the MODEL, rather than the other way around - hence my need to keep the model as an array. The button click is merely to simulate the other parts of the application that manipulate the array.
Any help would be great. Thanks and please.
Objects in Javascript are not equal even though they look identical but strings or other primitive types are. For example, var a = [1]; var b = [1]; a === b returns false. However, if you do JSON.stringify(a) === JSON.stringify(b), it will return true.
When you assign ['value2'] to valueBroken, valueBroken is redeclared as a new array so it doesn't match with the one in the selectFilterBroken.
To fix this, we wanna find a way to assign the reference of ['value2'] to valueBroken. I wrote a function to find which array in selectFilterBroken matches the one we want by comparing their stringified versions. Once found, assign the reference of the one in the selectFilterBroken to valueBroken.
Without knowing what exactly is going on in your app, it is hard to guess if the solution fits you, but you can go from there.
angular.module('app', [])
.controller('MainCtrl', ['$scope', function($scope) {
$scope.valueWorking = 'value1';
$scope.selectFilterWorking = [{name: 'name1', value: 'value1'},{name: 'name2', value: 'value2'}];
$scope.valueBroken = ['value1'];
$scope.selectFilterBroken = [{name: 'name1', value: ['value1']},{name: 'name2', value: ['value2']}];
$scope.selectBroken = function(valueAry){
for(var i = 0, m = $scope.selectFilterBroken.length; i < m; i++){
if(JSON.stringify($scope.selectFilterBroken[i].value) === JSON.stringify(valueAry)){
$scope.valueBroken = $scope.selectFilterBroken[i].value;
break;
}
}
}
}]);
<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.1/angular.min.js"></script>
<div ng-app="app" ng-controller="MainCtrl">
<strong>Working</strong> (SELECT <i>is</i> updated when ng-model is a string):<br>
<select ng-model="valueWorking"
ng-options="select.value as select.name for select in selectFilterWorking">
<option value="">Select an Option</option>
</select>
<button ng-click="valueWorking='value2'">Assign to String of 'value2'</button> {{valueWorking}}<br><br>
<strong>Broken</strong> (SELECT <i>not</i> updated when ng-model is an array):<br>
<select ng-model="valueBroken"
ng-options="select.value as select.name for select in selectFilterBroken">
<option value="">Select an Option</option>
</select>
<button ng-click="selectBroken(['value2'])">Assign to Array of ["value2"]</button> {{valueBroken}}
</div>
The reason its not binding is because the array value on $scope.valueBroken is different from the arrays in the $scope.selectFilterBroken. For them to match they have to be in the same array. For example, I have edited your code and assigned the value of an item in $scope.selectFilterBroken to $scope.valueBroken. And it is working fine now.
angular.module('app', [])
.controller('MainCtrl', ['$scope', function($scope) {
$scope.valueWorking = 'value1';
$scope.selectFilterWorking = [{name: 'name1', value: 'value1'},{name: 'name2', value: 'value2'}];
$scope.selectFilterBroken = [{name: 'name1', value: ['value1']},{name: 'name2', value: ['value2']}];
$scope.valueBroken = $scope.selectFilterBroken[0].value;
}]);
<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.1/angular.min.js"></script>
<div ng-app="app" ng-controller="MainCtrl">
<strong>Working</strong> (SELECT <i>is</i> updated when ng-model is a string):<br>
<select ng-model="valueWorking"
ng-options="select.value as select.name for select in selectFilterWorking">
<option value="">Select an Option</option>
</select>
<button ng-click="valueWorking='value2'">Assign to String of 'value2'</button> {{valueWorking}}<br><br>
<strong>Broken</strong> (SELECT <i>not</i> updated when ng-model is an array):<br>
<select ng-model="valueBroken"
ng-options="select.value as select.name for select in selectFilterBroken">
<option value="">Select an Option</option>
</select>
<button ng-click="valueBroken=['value2']">Assign to Array of ["value2"]</button> {{valueBroken}}
</div>
I'm trying to get a select box working in Angular. The problem I'm experiencing is to do with ng-init and setting it's default value from an object which is created during runtime. Heres my code:
<select
ng-model="settings.editing.panel.data.production_company"
ng-change="settings.editing.panel.data.production_company = selectValue"
ng-init="selectValue = settings.editing.panel.data.production_company"
>
<option
ng-repeat="(key, value) in lists.production_companies"
value="{{key}}"
ng-selected="{{selectValue}}"
>
{{value}}
</option>
</select>
"lists.production_companies" is a simple key-value array of names, populated during initial page render, updated by ajax.
The object "settings.editing.panel.data" starts its life as NULL, but later is loaded with a correctly formatted object which contains the property "production_company".
I have found setting ng-init to something like "ng-init="selectValue = 3" works fine. Setting a $scope.test = 3, then setting "ng-init="selectValue = test" works fine too.
However, my dynamic value does not work. How can I use my dynamically created object to set the value of this select box during runtime with the set-up I have?
<select
ng-model="settings.editing.panel.data.production_company"
ng-options = "option as option.keyName for option in list.production_companies"
> <!--set keyName equal to your object's key-->
</select>
Then in your controller
$scope.settings.editing.panel.data.production_company = list.production_companies[0] // Or which value you want to assign
You question confused me somehow. The following snippet is a working one, is that what you want?
'use strict';
angular.module('DemoApp', []);
angular.module('DemoApp').controller('DemoCtrl', ['$scope', function($scope){
$scope.lists={
production_companies: { "0": "prod 1", "1":"prod_2" },
};
$scope.settings={
editing: {
panel: {
data: null
}
}
};
$scope.setData=function(data){
$scope.settings.editing.panel.data={
production_company: data
};
};
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="DemoApp" ng-controller="DemoCtrl">
<select ng-model = "settings.editing.panel.data.production_company">
<option ng-repeat = "(key, value) in lists.production_companies" value = "{{key}}">{{value}}</option>
</select>
<div>You select: {{settings.editing.panel.data.production_company}}</div>
<button ng-click="setData('0')">Set Data to Prod1</button>
<button ng-click="setData('1')">Set Data to Prod2</button>
</div>
In my circumstances I was able to change my backends data format to set an object like:
{"id": 1, "name":"prod comp 1"}
and then change my select model accordingly. In hindsight I needed this for the ID anyway.
<select
ng-model="settings.editing.panel.data.production_company"
>
<option
ng-repeat="option in settings.lists.production_companies"
value="{{option.id}}"
ng-selected="{{option.id}} == settings.editing.panel.data.production_company"
>
{{option.name}}
</option>
</select>
I have searched Google and can't find anything on this.
I have this code.
<select ng-model="somethingHere"
ng-options="option.value as option.name for option in options"
></select>
With some data like this
options = [{
name: 'Something Cool',
value: 'something-cool-value'
}, {
name: 'Something Else',
value: 'something-else-value'
}];
And the output is something like this.
<select ng-model="somethingHere"
ng-options="option.value as option.name for option in options"
class="ng-pristine ng-valid">
<option value="?" selected="selected"></option>
<option value="0">Something Cool</option>
<option value="1">Something Else</option>
</select>
How is it possible to set the first option in the data as the default value so you would get a result like this.
<select ng-model="somethingHere" ....>
<option value="0" selected="selected">Something Cool</option>
<option value="1">Something Else</option>
</select>
You can simply use ng-init like this
<select ng-init="somethingHere = options[0]"
ng-model="somethingHere"
ng-options="option.name for option in options">
</select>
If you want to make sure your $scope.somethingHere value doesn't get overwritten when your view initializes, you'll want to coalesce (somethingHere = somethingHere || options[0].value) the value in your ng-init like so:
<select ng-model="somethingHere"
ng-init="somethingHere = somethingHere || options[0].value"
ng-options="option.value as option.name for option in options">
</select>
Try this:
HTML
<select
ng-model="selectedOption"
ng-options="option.name for option in options">
</select>
Javascript
function Ctrl($scope) {
$scope.options = [
{
name: 'Something Cool',
value: 'something-cool-value'
},
{
name: 'Something Else',
value: 'something-else-value'
}
];
$scope.selectedOption = $scope.options[0];
}
Plunker here.
If you really want to set the value that will be bound to the model, then change the ng-options attribute to
ng-options="option.value as option.name for option in options"
and the Javascript to
...
$scope.selectedOption = $scope.options[0].value;
Another Plunker here considering the above.
Only one answer by Srivathsa Harish Venkataramana mentioned track by which is indeed a solution for this!
Here is an example along with Plunker (link below) of how to use track by in select ng-options:
<select ng-model="selectedCity"
ng-options="city as city.name for city in cities track by city.id">
<option value="">-- Select City --</option>
</select>
If selectedCity is defined on angular scope, and it has id property with the same value as any id of any city on the cities list, it'll be auto selected on load.
Here is Plunker for this:
http://plnkr.co/edit/1EVs7R20pCffewrG0EmI?p=preview
See source documentation for more details:
https://code.angularjs.org/1.3.15/docs/api/ng/directive/select
I think, after the inclusion of 'track by', you can use it in ng-options to get what you wanted, like the following
<select ng-model="somethingHere" ng-options="option.name for option in options track by option.value" ></select>
This way of doing it is better because when you want to replace the list of strings with list of objects you will just change this to
<select ng-model="somethingHere" ng-options="object.name for option in options track by object.id" ></select>
where somethingHere is an object with the properties name and id, of course. Please note, 'as' is not used in this way of expressing the ng-options, because it will only set the value and you will not be able to change it when you are using track by
The accepted answer use ng-init, but document says to avoid ng-init if possible.
The only appropriate use of ngInit is for aliasing special properties
of ngRepeat, as seen in the demo below. Besides this case, you should
use controllers rather than ngInit to initialize values on a scope.
You also can use ng-repeat instead of ng-options for your options. With ng-repeat, you can use ng-selected with ng-repeat special properties. i.e. $index, $odd, $even to make this work without any coding.
$first is one of the ng-repeat special properties.
<select ng-model="foo">
<option ng-selected="$first" ng-repeat="(id,value) in myOptions" value="{{id}}">
{{value}}
</option>
</select>
---------------------- EDIT ----------------
Although this works, I would prefer #mik-t's answer when you know what value to select, https://stackoverflow.com/a/29564802/454252, which uses track-by and ng-options without using ng-init or ng-repeat.
This answer should only be used when you must select the first item without knowing what value to choose. e.g., I am using this for auto completion which requires to choose the FIRST item all the time.
My solution to this was use html to hardcode my default option. Like so:
In HAML:
%select{'ng-model' => 'province', 'ng-options' => "province as province for province in summary.provinces", 'chosen' => "chosen-select", 'data-placeholder' => "BC & ON"}
%option{:value => "", :selected => "selected"}
BC & ON
In HTML:
<select ng-model="province" ng-options="province as province for province in summary.provinces" chosen="chosen-select" data-placeholder="BC & ON">
<option value="" selected="selected">BC & ON</option>
</select>
I want my default option to return all values from my api, that's why I have a blank value. Also excuse my haml. I know this isn't directly an answer to the OP's question, but people find this on Google. Hope this helps someone else.
Use below code to populate selected option from your model.
<select id="roomForListing" ng-model="selectedRoom.roomName" >
<option ng-repeat="room in roomList" title="{{room.roomName}}" ng-selected="{{room.roomName == selectedRoom.roomName}}" value="{{room.roomName}}">{{room.roomName}}</option>
</select>
Depending on how many options you have, you could put your values in an array and auto-populate your options like this
<select ng-model="somethingHere.values" ng-options="values for values in [5,4,3,2,1]">
<option value="">Pick a Number</option>
</select>
In my case, I was need to insert a initial value only to tell to user to select an option, so, I do like the code below:
<select ...
<option value="" ng-selected="selected">Select one option</option>
</select>
When I tryed an option with the value != of an empty string (null) the option was substituted by angular, but, when put an option like that (with null value), the select apear with this option.
Sorry by my bad english and I hope that I help in something with this.
Using select with ngOptions and setting a default value:
See the ngOptions documentation for more ngOptions usage examples.
angular.module('defaultValueSelect', [])
.controller('ExampleController', ['$scope', function($scope) {
$scope.data = {
availableOptions: [
{id: '1', name: 'Option A'},
{id: '2', name: 'Option B'},
{id: '3', name: 'Option C'}
],
selectedOption: {id: '2', name: 'Option B'} //This sets the default value of the select in the ui
};
}]);
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.0-rc.0/angular.min.js"></script>
<body ng-app="defaultValueSelect">
<div ng-controller="ExampleController">
<form name="myForm">
<label for="mySelect">Make a choice:</label>
<select name="mySelect" id="mySelect"
ng-options="option.name for option in data.availableOptions track by option.id"
ng-model="data.selectedOption"></select>
</form>
<hr>
<tt>option = {{data.selectedOption}}</tt><br/>
</div>
plnkr.co
Official documentation about HTML SELECT element with angular data-binding.
Binding select to a non-string value via ngModel parsing / formatting:
(function(angular) {
'use strict';
angular.module('nonStringSelect', [])
.run(function($rootScope) {
$rootScope.model = { id: 2 };
})
.directive('convertToNumber', function() {
return {
require: 'ngModel',
link: function(scope, element, attrs, ngModel) {
ngModel.$parsers.push(function(val) {
return parseInt(val, 10);
});
ngModel.$formatters.push(function(val) {
return '' + val;
});
}
};
});
})(window.angular);
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.0-rc.1/angular.min.js"></script>
<body ng-app="nonStringSelect">
<select ng-model="model.id" convert-to-number>
<option value="1">One</option>
<option value="2">Two</option>
<option value="3">Three</option>
</select>
{{ model }}
</body>
plnkr.co
Other example:
angular.module('defaultValueSelect', [])
.controller('ExampleController', ['$scope', function($scope) {
$scope.availableOptions = [
{ name: 'Apple', value: 'apple' },
{ name: 'Banana', value: 'banana' },
{ name: 'Kiwi', value: 'kiwi' }
];
$scope.data = {selectedOption : $scope.availableOptions[1].value};
}]);
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.0-rc.0/angular.min.js"></script>
<body ng-app="defaultValueSelect">
<div ng-controller="ExampleController">
<form name="myForm">
<select ng-model="data.selectedOption" required ng-options="option.value as option.name for option in availableOptions"></select>
</form>
</div>
</body>
jsfiddle
This worked for me.
<select ng-model="somethingHere" ng-init="somethingHere='Cool'">
<option value="Cool">Something Cool</option>
<option value="Else">Something Else</option>
</select>
In response to Ben Lesh's answer, there should be this line
ng-init="somethingHere = somethingHere || options[0]"
instead of
ng-init="somethingHere = somethingHere || options[0].value"
That is,
<select ng-model="somethingHere"
ng-init="somethingHere = somethingHere || options[0]"
ng-options="option.name for option in options track by option.value">
</select>
In my case since the default varies from case to case in the form.
I add a custom attribute in the select tag.
<select setSeletected="{{data.value}}">
<option value="value1"> value1....
<option value="value2"> value2....
......
in the directives I created a script that checks the value and when angular fills it in sets the option with that value to selected.
.directive('setSelected', function(){
restrict: 'A',
link: (scope, element, attrs){
function setSel=(){
//test if the value is defined if not try again if so run the command
if (typeof attrs.setSelected=='undefined'){
window.setTimeout( function(){setSel()},300)
}else{
element.find('[value="'+attrs.setSelected+'"]').prop('selected',true);
}
}
}
setSel()
})
just translated this from coffescript on the fly at least the jist of it is correct if not the hole thing.
It's not the simplest way but get it done when the value varies
Simply use ng-selected="true" as follows:
<select ng-model="myModel">
<option value="a" ng-selected="true">A</option>
<option value="b">B</option>
</select>
This working for me
ng-selected="true"
I would set the model in the controller. Then the select will default to that value. Ex:
html:
<select ng-options="..." ng-model="selectedItem">
Angular controller (using resource):
myResource.items(function(items){
$scope.items=items;
if(items.length>0){
$scope.selectedItem= items[0];
//if you want the first. Could be from config whatever
}
});
If you are using ng-options to render you drop down than option having same value as of ng-modal is default selected.
Consider the example:
<select ng-options="list.key as list.name for list in lists track by list.id" ng-model="selectedItem">
So option having same value of list.key and selectedItem, is default selected.
I needed the default “Please Select” to be unselectable. I also needed to be able to conditionally set a default selected option.
I achieved this the following simplistic way:
JS code:
// Flip these 2 to test selected default or no default with default “Please Select” text
//$scope.defaultOption = 0;
$scope.defaultOption = { key: '3', value: 'Option 3' };
$scope.options = [
{ key: '1', value: 'Option 1' },
{ key: '2', value: 'Option 2' },
{ key: '3', value: 'Option 3' },
{ key: '4', value: 'Option 4' }
];
getOptions();
function getOptions(){
if ($scope.defaultOption != 0)
{ $scope.options.selectedOption = $scope.defaultOption; }
}
HTML:
<select name="OptionSelect" id="OptionSelect" ng-model="options.selectedOption" ng-options="item.value for item in options track by item.key">
<option value="" disabled selected style="display: none;"> -- Please Select -- </option>
</select>
<h1>You selected: {{options.selectedOption.key}}</h1>
I hope this helps someone else that has similar requirements.
The "Please Select" was accomplished through Joffrey Outtier's answer here.
If you have some thing instead of just init the date part, you can use ng-init() by declare it in your controller, and use it in the top of your HTML.
This function will work like a constructor for your controller, and you can initiate your variables there.
angular.module('myApp', [])
.controller('myController', ['$scope', ($scope) => {
$scope.allOptions = [
{ name: 'Apple', value: 'apple' },
{ name: 'Banana', value: 'banana' }
];
$scope.myInit = () => {
$scope.userSelected = 'apple'
// Other initiations can goes here..
}
}]);
<body ng-app="myApp">
<div ng-controller="myController" ng-init="init()">
<select ng-model="userSelected" ng-options="option.value as option.name for option in allOptions"></select>
</div>
</body>
<!--
Using following solution you can set initial
default value at controller as well as after change option selected value shown as default.
-->
<script type="text/javascript">
function myCtrl($scope)
{
//...
$scope.myModel=Initial Default Value; //set default value as required
//..
}
</script>
<select ng-model="myModel"
ng-init="myModel= myModel"
ng-options="option.value as option.name for option in options">
</select>
try this in your angular controller...
$somethingHere = {name: 'Something Cool'};
You can set a value, but you are using a complex type and the angular will search key/value to set in your view.
And, if does not work, try this :
ng-options="option.value as option.name for option in options track by option.name"
I think the easiest way is
ng-selected="$first"
In Angular.JS, is there a way to bind two different ng-models when a select drop down option is selected?
Angular code:
<select ng-model="vm.data.styleId" ng-options="item.id as item.name for item in vm.getStylesData.styles">
<option value="">Select a Style</option>
</select>
Results in:
<option value="{{item.id}}">{{item.name}}</option>
With the Angular code I have so far, when an option is selected, it will save the option's value to the ng-model. In this case item.id is bound to vm.data.styleId.
However in addition to this, I also need to bind the 'item.name' of the selected option. Basically, when an option is selected, I need to bind both the item.id to vm.data.styleId, and the item.name to vm.data.name.
Is there an easy way to do this using Angular.JS?
Solution (using the answer from lisa p.):
In the View:
<select ng-model="vm.styleItem" ng-change="vm.getDetails()" ng-options="item as item.name for item in vm.getStylesData.styles">
<option value="">Select a Style</option>
</select>
Inside the controller:
vm.getDetails = function () {
// set the values of the select drop down
vm.data.styleId = vm.styleItem.id;
vm.data.style = vm.styleItem.name;
}
You can bind to an object containing both values like
item = { styleId: 23, name: "the name" }
vm.data = {{ styleId: ..., name: ... }}
then you bind to vm.data with
<option value="{{item}}">{{item.name}}</option>
Controller
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.vm.data.styleId = "";
$scope.item = {id : '1', name : 'name'};
});
html
<div ng-controller="myCtrl">
<select ng-model="vm.data.styleId" ng-options="item.id as item.name for item in vm.getStylesData.styles">
<option value="{{item}}">{{item.name}}</option>
</select>
</div>
Make an object which holds both id and name and pass that object as value to option