how to pass select option value in angularjs - javascript

I have a below code snippet
HTML
<div ng-controller="MyCtrl">
<div ng-if="quan!=true">
<select ng-model="selectedItems" ng-init="selectedItems = selectedItems + ''">
<option ng-repeat="value in arr | limitTo:quantity">{{value}}</option>
</select>
</div>
<div>
Submit
</div>
</div>
JS
$scope.arr = [];
$scope.quan=false;
for(var a=1; a<=10; a++) {
$scope.arr.push(a);
}
$scope.selectedItems = $scope.arr[0];
$scope.quantity = 10; //just hardcoded
Here, when I click submit button, I didn't get the value whatever I have selected in the dropdown. I was getting undefined for selectedItems.
And also first option needs to be selected in the select box.
I think I'm missing something!

After changing to $scope.selectedItems = $scope.arr[0];, you need to initialize your option value ng-init="selectedItems = selectedItems + ''" because angular use strict comparison.
See this working fiddle.
also you don't need to pass selected item in click event, submit(selectedItems). because it is already in controller scope.
Also I would recommend changing your options structure to avoid ng-init.
Something like :
options = [{
name: 'key1',
value: 'value1'
}, {
name: 'key2',
value: 'value2'
}];

HTML:
<select ng-model="selectedItem" >
<option ng-repeat="value in arr | limitTo:quantity">{{value}}</option>
</select>
<div>
Submit
</div>
JS:
$scope.arr = [];
for(var a=1; a<=10; a++) {
$scope.arr.push(a);
}
$scope.selectedItem = $scope.arr[0];
$scope.quantity = 10; //just hardcoded
$scope.submit = function(){
console.log($scope.selectedItem); // you will get the selected value here, if you want it after button click.
};
Because of angular's 2 way binding, it would be available as soon as you select something. You do not have to pass it as function parameter from HTML

Related

How to add additional value to option in a drop down and how to get that value when option is selected in angular js 1.x

I have the below code in jQuery. I want to know what is the equivalent code of above in Angular Js 1.x Versions?
<select id="select">
<option value="1" data-foo="dogs">this</option>
<option value="2" data-foo="cats">that</option>
<option value="3" data-foo="gerbils">other</option>
</select>
// JavaScript using jQuery
$(function() {
$('select').change(function() {
var selected = $(this).find('option:selected');
var extra = selected.data('foo');
});
});
var sel = document.getElementById('select');
var selected = sel.options[sel.selectedIndex];
var extra = selected.getAttribute('data-foo');
You don't need to use jQuery when you are using angularjs.
To get the selected value in dropdown, you need to model select with ng-model and then the value will be there on the fly. That's the beauty of angularjs.
Moreover, if you are interested to add options on fly, better use ng-repeat to do that. And push in the array when you need to add another option. The option will be added to select. Another piece beauty of angularjs
Here
angular.module('app',[]).controller('ctrl', function($scope){
$scope.options = [{value : 1, attr: "dogs" },{value : 2, attr: "cats" },{value : 3, attr: "gerbils" }];
$scope.data = $scope.options[0]
$scope.select = 1;
$scope.add = function(){
$scope.options.push({value : $scope.options.length + 1, attr: 'option'})
};
$scope.getFoo = function(){
$scope.data = $scope.options.find(o=> o.value == $scope.select)
}
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app='app' ng-controller='ctrl'>
<select id="select" ng-model="select" ng-change="getFoo()">
<option ng-repeat="option in options" value="{{option.value}}" data-foo="{{option.attr}}">{{option.attr}}</option>
</select>
<button ng-click="add()">Add option</button>
{{data.value}}
{{data.attr}}
</div>
Add the value to the model that is provided as the data source for ng-repeat and set ng-model for dropdown .And get value of dropdown using ng-model.

angularjs - setting select element option value with JS object

I am new to AngularJS so please bear with me.
Following is the the JSON string I am trying to bind in the select element:
[
{"Name":"Value 1","ID":1},
{"Name":"Value 2","ID":2},
{"Name":"Value 3","ID":3},
{"Name":"Value 4","ID":4}
]
Following is the JS object for the same:
function NameValue(nameValue){
var self = this;
self.ID = nameValue.ID;
self.Name= nameValue.Name;
}
I am parsing the above JSON string, looping through the objects and pushing items into an array using the above JS object like:
angular.forEach(angular.fromJson(jsonString), function (value, key) {
$scope.Values.push(new NameValue(value));
});
Following is my select with agularjs bindings:
<select ng-model="SelectedName" ng-options="x.Name for x in Values">/select>
When I select a value in the select element, the entire NameValue object is getting set into the SelectedName property which is what I am trying to do.
Now when I try to set the SelectedName property dynamically, the value is not getting selected and an empty option element is getting added in the select element. I used the {{SelectedName}} to check the value when set dynamically and when I select the same value in the select element manually and both are {"ID":2,"Name":"DAO"} which are exactly same. What am I doing wrong here?
The syntax of ng-options is something like this.link
<select ng-options="item as item.label for item in items track by item.id" ng-model="selected"></select>
Suppose you have controller like this
app.controller('MainCtrl', function($scope) {
$scope.Values = [
{"Name":"Value 1","ID":1},
{"Name":"Value 2","ID":2},
{"Name":"Value 3","ID":3},
{"Name":"Value 4","ID":4}
];
$scope.SelectedByName='Value 2'; //Default setting drop down by Name property
$scope.SelectedById=4; //Default setting drop down by ID property
});
If you follow the below syntax then either name or Id property will be set to selected variable.
If you need default selection of drop down then you need to set the respective model in controller.(as above)
HTML :
<body ng-controller="MainCtrl">
By name :
<select ng-options="value.Name as value.Name for value in Values"
ng-model="SelectedByName" ng-change="Print()"></select>
Selected value is : {{SelectedByName}}
<br>
By ID :
<select ng-options="value.ID as value.Name for value in Values"
ng-model="SelectedById" ng-change="Print()"></select>
Selected id is : {{SelectedById}}
</body>
Demo plunker Click here
First of all - you should initialize SelectName in your $scope.
Next you can use:
ng-options="x.id as x.name for x in values"
Can you display {{values}} in your template and it's look good? Maybe you have a problem with redraw template when data is push into value. Check this way also.
here is a working snippet. i guess you didn't defined Values as an array, before pushing anything you have to define the variable as an array.
var app = angular.module('myApp', []);
function NameValue(nameValue) {
var self = this;
self.ID = nameValue.ID;
self.Name = nameValue.Name;
}
app.controller('myCtrl', function($scope) {
$scope.Values = [];
$scope.jsonString = [{
"Name": "Value 1",
"ID": 1
}, {
"Name": "Value 2",
"ID": 2
}, {
"Name": "Value 3",
"ID": 3
}, {
"Name": "Value 4",
"ID": 4
}];
angular.forEach(angular.fromJson( $scope.jsonString), function (value, key) {
$scope.Values.push(new NameValue(value));
});
console.log($scope.Values);
});
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body>
<div ng-app="myApp" ng-controller="myCtrl">
<select ng-model="SelectedName" ng-options="x.Name for x in Values">/select>
</div>
</body>
</html>
I had the same issue and i found a solution:
Don't use ng-options but <option> tag
<select ng-model="..."> <option ng-repeat="..."> {{ ... }} </option></select>

ng-change detect if ng-model is null or invalid in select box and select first valid option

I have hundreds of cases like this (so the fix would have to be global and not tied to just this particular example)
There is a lot of select boxes like this:
<select ng-model="selectedItem">
<option ng-repeat="item in items | filter:attributes" value="{{item.id}}">{{item.name}}</option>
</select>
The selectedItem variable is null (and it will always initialize as null, which can't be changed in the controller in this particular situation).
What I'm trying to figure out is a way to globally watch all <select> elements in a view, see if the ng-model variable for that <select> box is null and if it is null set it to the first valid option in that select box, anytime the scope changes it will need to check if the ng-model is null and auto-select the first valid option.
The key thing to realise with this is that you can define more than one Angular directive with the same name, and all of them will be run for matching elements.
This is very powerful, as it enables you to extend functionality of built-in directives, or third party ones, etc.
Using this, I was able to create a select directive that would select the first valid option in the list whenever the model value is null.
One thing it doesn't do, however, is cope if you remove the selected item from the list (it goes back to being blank). But hopefully it is enough to get you started.
var app = angular.module('stackoverflow', []);
app.controller('MainCtrl', function($scope) {
$scope.selectedItem = null;
$scope.items = [1, 2, 3, 4].map(function(id) {
return {
id: id,
visible: true,
text: 'Item ' + id
};
});
});
app.directive('select', function() {
return {
restrict: 'E',
require: '?ngModel',
link: function($scope, $elem, $attrs, ngModel) {
// don't do anything for selects without ng-model attribute
if (!ngModel) return;
// also allow specifying a special "no-default" attribute to opt out of this behaviour
if ($attrs.hasOwnProperty('noDefault')) return;
// watch the model value for null
var deregWatch = $scope.$watch(function() {
return ngModel.$modelValue;
}, function(modelValue) {
if (modelValue === null) {
// delay to allow the expressions to be interpolated correctly
setTimeout(function() {
// find the first option with valid text
var $options = $elem.find('option'),
$firstValidOption, optionText;
for (var i = 0, len = $options.length; i < len; i++) {
optionText = $options.eq(i).text();
if (optionText !== '' && !optionText.match(/^(\?|{)/)) {
$firstValidOption = $options.eq(i);
break;
}
}
if ($firstValidOption) {
$firstValidOption.prop('selected', true);
ngModel.$setViewValue($firstValidOption.attr('value'));
// trigger a digest so Angular sees the change
$scope.$evalAsync();
}
}, 0);
}
});
// clean up in destroy method to prevent any memory leaks
var deregDestroy = $scope.$on('$destroy', function() {
deregWatch();
deregDestroy();
});
}
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<div ng-app="stackoverflow">
<div ng-controller="MainCtrl">
<select ng-model="selectedItem">
<option ng-repeat="item in items | filter:{visible:true} track by item.id" value="{{item.id}}">{{item.text}}</option>
</select>
<p>Visible items:</p>
<ul>
<li ng-repeat="item in items track by item.id">
<label>
<input type="checkbox" ng-model="item.visible">{{item.text}}
</label>
</li>
</ul>
</div>
</div>

Angular: selected value not maintained in select generated with ng-options

I have a dropdown generated using ng-options
<select class="form-control" ng-options="item.value as item.label for item in filterFields track by item.value" ng-model="selectedFilterField">
</select>
The problem is that when I select an option from this dropwon, the selected item appears as empty and an extra blank element is added to the dropdown. What am I doing wrong?
Edit: added controller code:
$scope.columns = accountColumns;
$scope.filterFields = [];
$scope.filterFields.push(defaultSelectOption);
$scope.filterFieldValues.push(defaultSelectOption);
var idx = 1;
for(i=0; i < accountColumns.length; i++) {
var option = {label: accountColumns[i], value: accountColumns[i]};
$scope.filterFields.push(option);
}
$scope.selectedFilterField = $scope.filterFields[0];
Let's say your filterFields array has objects that look like this:
{
name: "",
value: 0
}
In your ng-options you tell angular that the possible values for the select is an array of these objects. But you also tell angular that when you select an option then the real value is the object.value; So now angular sees that this value is not present in the array of options and tries to add it or something.
Initially the dropdown works because you set the ng-model to a complete object present in the filterFields array.
Try it with this:
ng-options="item for item in filterFields track by item.value"

Angular dynamic select values

I've got some dynamically generated values in select:
<select ng-model="selectedValue" ng-options="o.id as o.name for o in values"></select>
And I have selectedValue that holds the selected value. I want it to be updated to null or undefined when the selectedValue is no longer present in values.
I can clear the selectedValue in $scope.$watch(values) but is there a better solution?
Basically this situation in this plunker is what I want to avoid:
I want it to be "Selected value: null" or something similar.
You can create a directive that will make the select behave in the way that you'd like. The HTML would then change to:
<select clearable ng-model="selectedValue" ng-options="o.id as o.name for o in values"></select>
The JS for the directive would be:
app.directive('clearable', ['$parse',function($parse){
return {
restrict : 'A',
scope : {
'ngModel' : '=',
'ngOptions' : '#'
},
require: ['select','?ngModel'],
link : function(scope, elem, attr,ctrl){
// Regex copied from the Angular Source
var NG_OPTIONS_REGEXP = /^\s*([\s\S]+?)(?:\s+as\s+([\s\S]+?))?(?:\s+group\s+by\s+([\s\S]+?))?\s+for\s+(?:([\$\w][\$\w]*)|(?:\(\s*([\$\w][\$\w]*)\s*,\s*([\$\w][\$\w]*)\s*\)))\s+in\s+([\s\S]+?)(?:\s+track\s+by\s+([\s\S]+?))?$/;
var match = scope.ngOptions.match(NG_OPTIONS_REGEXP);
var valuesFn = $parse(match[7]), //Options list
key = match[1].split('.')[1]; //Property in options list
scope.$watch(
function(){
// Watch for when the options list changes
return valuesFn(scope.$parent);
},
function(newList){
var isFound, i,
currentModelVal = scope.ngModel;
// Iterate through the new list to see if the current value is present
for(i=0;i<newList.length;i++){
if (newList[i][key] === currentModelVal){
isFound = true;
break;
}
}
// If not found, reset the ng-model value to null
if (!isFound){
ctrl[1].$setViewValue(null);
}
}
);
}
}
}]);
See the Plunker at http://plnkr.co/edit/yAk9YSoMf88rtTqLXTiI?p=preview
You can use an option with empty value, and model will be set to empty when no item is selected
check this
<option value="">--select--</option>
http://plnkr.co/edit/66KN7ae0q2v3IUnw47lx?p=preview

Categories

Resources