I have an object with property: value structure with should be used for the ng-options to create the select dropdown. I also have a ng-model variable which contains the property which should be currently selected. The problem is that I can't figure out how to fix the initial selection.
You can find the code here
<select ng-model="selectedCar" ng-options="id as value for (id, value) in cars track by id">
http://jsbin.com/wukanenozu/1/edit?html,js,output
Do not use "track by"
Do not use as and track by in the same expression. They are not
designed to work together.
<select ng-model="selectedCar" ng-options="id as value for (id, value) in cars ">
</select>
DEMO
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.cars = {
frd : "Ford",
ft1 : "Fiat",
vlv : "Volvo"
}
$scope.selectedCar = 'ft1';
});
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<body>
<div ng-app="myApp" ng-controller="myCtrl">
<p>Select a car:</p>
<select ng-model="selectedCar" ng-options="id as value for (id, value) in cars ">
</select>
<h1>You selected model: {{selectedCar}}</h1>
</div>
<p>This example demonstrates the use of an object as the data source when creating a dropdown list.</p>
</body>
</html>
Related
I would like to create a select element with ngOptions – so far so good:
<select ng-options="currency for (code, currency) in currencies track by code"
ng-model="something.currency"></select>
Now I want to track the options by the object key (so the value of the ng-model should be the key and not the value of the object). Is this possible in some simple way and how?
Is it what you're looking for ?
var myApp = angular.module('myApp',[]);
myApp.controller('GreetingController', ['$scope', function($scope) {
$scope.currencies_old = [
{code: "USD", curr: "$"},
{code: "IND", curr: "INR"}
];
$scope.currencies = {"USD": "USDollars", "EUR": "Euro"};
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="GreetingController">
<select ng-model="item" ng-options="key as value for (key , value) in currencies"></select>
Code: {{item}}
<br/> <br/>
<select ng-options="item as item.curr for item in currencies_old track by item.code" ng-model="item_old"></select>
Code: {{item_old.code}}
</div>
I have several select elements on the same page. Each select dropdown contains the same items. I would like to disable an item within the dropdown if it has already been selected in another select element. In other words, I don't want an item to be selected more than once across all of the select elements.
Any thoughts on how to accomplish this?
When I use the following code, nothing is disabled in the dropdown.
Code for controller:
var editProject = this;
editProject.addMore = function() {
editProject.project.fruit.push({});
};
editProject.fruitids = [
{code: 'GOODS', fruit: '1. Apple'},
{code: 'GOODS', fruit: '2. Orange'},
{code: 'GOODS', fruit: '3. Peach'},
];
HTML:
<div ng-repeat="item in editProject.project.fruits">
<select ng-model="editProject.project.fruits[$index]"
ng-options="fruitid.class group by fruitid.code disable when (editProject.project.fruits.indexOf((fruitid)) !== -1)
for fruitid in editProject.fruitids track by fruitid.class">
<option value="">--Select Class--</option>
</select>
</div>
<button ng-click="editProject.addMore()" class="btn btn-default btn-xs" role="button">Add More Classes
</button>
You need to use a function as the expression for the disable parameter in the ng-options directive.
Please see working example1
HTML
<div data-ng-repeat="item in items">
<select data-ng-options="fruitId.fruit disable when isDisabled(fruitId) for fruitId in fruitIds" data-ng-model="items[$index]"></select>
</div>
JS
$scope.isDisabled = function(fruitid) {
return ($scope.items.indexOf((fruitid)) !== -1);
};
This will disable the option in all the select's including the the select where the option was selected. The option will now not be selected any more as it is disabled.
You need to exclude the current fruitId so it is still enabled in the selected select
Please see example2 where the current fruitId is excluded and the selected option is disabled in the other selects
We make sure that the index found is not the index of the current item.
HTML
<div data-ng-repeat="item in items">
<select data-ng-options="fruitId.fruit disable when isDisabled(fruitId, item) for fruitId in fruitIds" data-ng-model="items[$index]"></select>
</div>
JS
$scope.isDisabled = function(fruitid, item) {
return ($scope.items.indexOf((fruitid)) !== -1 && $scope.items.indexOf((fruitid)) != $scope.items.indexOf(item));
};
This code can help to you?
index.html:
<html ng-app>
<head>
<title>Demo</title>
<script type="text/javascript" src="js/lib/angular.min.js"></script>
<script type="text/javascript" src="js/controllers/app.js"></script>
<link rel="stylesheet" type="text/css" href="css/bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="css/bootstrap-responsive.min.css">
</head>
<body>
<div class="container" ng-controller="AppCtrl">
<select ng-model="selectedOption" ng-change="change(selectedOption)">
<option ng-repeat="var in myObj.myArr" value={{var.id}}
ng-disabled="var.selectable">
{{var.fruit}}
</option>
</select>
</div>
</div>
</div>
</body>
</html>
app.js:
function AppCtrl ($scope) {
$scope.myObj = {
"myArr":[
{id:0, code: 'GOODS', fruit: '1. Apple', selectable:false},
{id:1, code: 'GOODS', fruit: '2. Orange', selectable:false},
{id:2, code: 'GOODS', fruit: '3. Peach', selectable:false}
]};
$scope.selectedOption = {};
$scope.change = function(id){
var name = $scope.myObj.myArr[id].selectable = true;
};
};
You can:
1- Create an angularjs directive that encapsulate every select/dropdown and assign a unique id to each of them.
2- Bind the array of elements to all directives
3- When the user selects an item you set an item's property (assignedTo) with the unique id of the directive as the value (and clean the property for all other items with this id as value)
4- The select disables elements based on the value of the property (assignedTo !== uniqueId)
View template:
<my-select-directive unique-select-id="1" items="theItems"><my-select-directive>
<my-select-directive unique-select-id="2" items="theItems"><my-select-directive>
<my-select-directive unique-select-id="3" items="theItems"><my-select-directive>
Directive template:
<select ng-model="selectedItem" ng-change="change()">
<option ng-repeat="item in myItems" value={{item.id}}
ng-disabled="item.assignedTo && item.assignedTo !== uniqueSelectId">
{{item.fruit}}
</option>
</select>
Directive code:
//here you can implement logic to remember previous selection, now it doesn't
scope.selectedItem= null;
scope.change = function(){
//needed to sync
//remove the mark of the previous selected item for this dropdown if any
myItems.forEach(function(item) {if (item.assignedTo === scope.uniqueSelectId) item.assignedTo = null;});
//now mark the item as selected in this dropdown
selectedItem.assignedTo = scope.uniqueSelectId;
}
This is not working code, it's only to guide you
I need to change the "selected value" of the drop down from the already saved value in db. How can I do that?
Controller
var app = angular.module('app', []);
app.controller('ctrl', function($scope) {
$scope.months = ['January','February','March','April','May','June','July','August','September','October','November','December'];
$scope.selected='August';//here it's not working ?
});
HTML
<html ng-app="app">
<body ng-controller="ctrl">
<div class="sample" align="center">
<h1>AngularJS Combobox</h1>
<select ng-model="selected" ng-options="opt as opt for opt in months" ng-init="selected='March'"></select>
<h3>You have selected : {{selected}}</h3>
</div>
</body>
</html>
My CODE PEN is here.
Any help would be highly appreciated.
Remove the:
ng-init="selected='March'"
So that your new view code is as follows:
<html ng-app="app">
<body ng-controller="ctrl">
<div class="sample" align="center">
<h1>AngularJS Combobox</h1>
<select ng-model="selected" ng-options="opt as opt for opt in months"></select>
<h3>You have selected : {{selected}}</h3>
</div>
</body>
</html>
To set the initial selected default: set via $scope.selected in the controller - don't use ng-init for this.
To reset the default after a database save, you'll want to use a promise for the save operation and reset the select field in the promise's return function.
I have in my .html page a dropdown list,
Dropdown:
<select ng-model="blisterPackTemplateSelected" data-ng-options="blisterPackTemplate as blisterPackTemplate.name for blisterPackTemplate in blisterPackTemplates">
<option value="">Select Account</option>
</select>
I want to execute an action when the user select a value. So In my controller I did:
Controller:
$scope.$watch('blisterPackTemplateSelected', function() {
alert('changed');
console.log($scope.blisterPackTemplateSelected);
});
But the changing the value in the dropdownlist doesn't trigger the code : $scope.$watch('blisterPackTemplateSelected', function()
As a result I tried another method with a : ng_change = 'changedValue()' on the select tag
and
Function:
$scope.changedValue = function() {
console.log($scope.blisterPackTemplateSelected);
}
But the blisterPackTemplateSelected is stored into a child scope. I read that the parent can't get access to the child scope.
What is the correct/best way to execute something when a selected value in a dropdown list changes? If it's method 1, what am I doing wrong with my code?
as Artyom said you need to use ngChange and pass ngModel object as argument to your ngChange function
Example:
<div ng-app="App" >
<div ng-controller="ctrl">
<select ng-model="blisterPackTemplateSelected" ng-change="changedValue(blisterPackTemplateSelected)"
data-ng-options="blisterPackTemplate as blisterPackTemplate.name for blisterPackTemplate in blisterPackTemplates">
<option value="">Select Account</option>
</select>
{{itemList}}
</div>
</div>
js:
function ctrl($scope) {
$scope.itemList = [];
$scope.blisterPackTemplates = [{id:1,name:"a"},{id:2,name:"b"},{id:3,name:"c"}];
$scope.changedValue = function(item) {
$scope.itemList.push(item.name);
}
}
Live example: http://jsfiddle.net/choroshin/9w5XT/4/
I may be late for this but I had somewhat the same problem.
I needed to pass both the id and the name into my model but all the orthodox solutions had me make code on the controller to handle the change.
I macgyvered my way out of it using a filter.
<select
ng-model="selected_id"
ng-options="o.id as o.name for o in options"
ng-change="selected_name=(options|filter:{id:selected_id})[0].name">
</select>
<script>
angular.module("app",[])
.controller("ctrl",['$scope',function($scope){
$scope.options = [
{id:1, name:'Starbuck'},
{id:2, name:'Appolo'},
{id:3, name:'Saul Tigh'},
{id:4, name:'Adama'}
]
}])
</script>
The "trick" is here:
ng-change="selected_name=(options|filter:{id:selected_id})[0].name"
I'm using the built-in filter to retrieve the correct name for the id
Here's a plunkr with a working demo.
Please, use for it ngChange directive.
For example:
<select ng-model="blisterPackTemplateSelected"
ng-options="blisterPackTemplate as blisterPackTemplate.name for blisterPackTemplate in blisterPackTemplates"
ng-change="changeValue(blisterPackTemplateSelected)"/>
And pass your new model value in controller as a parameter:
ng-change="changeValue(blisterPackTemplateSelected)"
Best practise is to create an object (always use a . in ng-model)
In your controller:
var myObj: {
ngModelValue: null
};
and in your template:
<select
ng-model="myObj.ngModelValue"
ng-options="o.id as o.name for o in options">
</select>
Now you can just watch
myObj.ngModelValue
or you can use the ng-change directive like so:
<select
ng-model="myObj.ngModelValue"
ng-options="o.id as o.name for o in options"
ng-change="myChangeCallback()">
</select>
The egghead.io video "The Dot" has a really good overview, as does this very popular stack overflow question: What are the nuances of scope prototypal / prototypical inheritance in AngularJS?
You can pass the ng-model value through the ng-change function as a parameter:
<select
ng-model="blisterPackTemplateSelected"
data-ng-options="blisterPackTemplate as blisterPackTemplate.name for blisterPackTemplate in blisterPackTemplates"
ng-change="changedValue(blisterPackTemplateSelected)">
<option value="">Select Account</option>
</select>
It's a bit difficult to know your scenario without seeing it, but this should work.
You can do something like this
<html ng-app="App" >
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
<script>
angular.module("App",[])
.controller("ctrl",['$scope',function($scope){
$scope.changedValue = function(item){
alert(item);
}
}]);
</script>
<div >
<div ng-controller="ctrl">
<select ng-model="blisterPackTemplateSelected" ng-change="changedValue(blisterPackTemplateSelected)" >
<option value="">Select Account</option>
<option value="Add">Add</option>
</select>
</div>
</div>
</html>
instead of add option you should use data-ng-options.I have used Add option for testing purpose
I am late here but I resolved same kind of problem in this way that is simple and easy.
<select ng-model="blisterPackTemplateSelected" ng-change="selectedBlisterPack(blisterPackTemplateSelected)">
<option value="">Select Account</option>
<option ng-repeat="blisterPacks in blisterPackTemplates" value="{{blisterPacks.id}}">{{blisterPacks.name}}</option>
and the function for ng-change is as follows;
$scope.selectedBlisterPack= function (value) {
console.log($scope.blisterPackTemplateSelected);
};
You will get selected option's value and text from list/array by using filter.
editobj.FlagName=(EmployeeStatus|filter:{Value:editobj.Flag})[0].KeyName
<select name="statusSelect"
id="statusSelect"
class="form-control"
ng-model="editobj.Flag"
ng-options="option.Value as option.KeyName for option in EmployeeStatus"
ng-change="editobj.FlagName=(EmployeeStatus|filter:{Value:editobj.Flag})[0].KeyName">
</select>
I had the same issue and found a unique solution. This is not best practice, but it may prove simple/helpful for someone. Just use jquery on the id or class or your select tag and you then have access to both the text and the value in the change function. In my case I'm passing in option values via sails/ejs:
<select id="projectSelector" class="form-control" ng-model="ticket.project.id" ng-change="projectChange(ticket)">
<% _.each(projects, function(project) { %>
<option value="<%= project.id %>"><%= project.title %></option>
<% }) %>
</select>
Then in my Angular controller my ng-change function looks like this:
$scope.projectChange = function($scope) {
$scope.project.title=$("#projectSelector option:selected").text();
};
I have tried some solutions,but here is basic production snippet. Please, pay attention to console output during quality assurance of this snippet.
Mark Up :
<!DOCTYPE html>
<html ng-app="appUp">
<head>
<title>
Angular Select snippet
</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" />
</head>
<body ng-controller="upController">
<div class="container">
<div class="row">
<div class="col-md-4">
</div>
<div class="col-md-3">
<div class="form-group">
<select name="slct" id="slct" class="form-control" ng-model="selBrand" ng-change="Changer(selBrand)" ng-options="brand as brand.name for brand in stock">
<option value="">
Select Brand
</option>
</select>
</div>
<div class="form-group">
<input type="hidden" name="delimiter" value=":" ng-model="delimiter" />
<input type="hidden" name="currency" value="$" ng-model="currency" />
<span>
{{selBrand.name}}{{delimiter}}{{selBrand.price}}{{currency}}
</span>
</div>
</div>
<div class="col-md-4">
</div>
</div>
</div>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js">
</script>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/tether/1.4.0/js/tether.min.js"></script>
<script src="//maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/js/bootstrap.min.js"></script>
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js">
</script>
<script src="js/ui-bootstrap-tpls-2.5.0.min.js"></script>
<script src="js/main.js"></script>
</body>
</html>
Code:
var c = console;
var d = document;
var app = angular.module('appUp',[]).controller('upController',function($scope){
$scope.stock = [{
name:"Adidas",
price:420
},
{
name:"Nike",
price:327
},
{
name:"Clark",
price:725
}
];//data
$scope.Changer = function(){
if($scope.selBrand){
c.log("brand:"+$scope.selBrand.name+",price:"+$scope.selBrand.price);
$scope.currency = "$";
$scope.delimiter = ":";
}
else{
$scope.currency = "";
$scope.delimiter = "";
c.clear();
}
}; // onchange handler
});
Explanation:
important point here is null check of the changed value, i.e. if value is 'undefined' or 'null' we should to handle this situation.
My code is set up to allow a user to select a sort direction:
<tr data-ng-repeat="row in gdata | orderBy:inverse">
Here's my HTML:
<div class="orderby">
<div class="arrow up"></div>
<div class="arrow down"></div>
<input type="checkbox" data-ng-model="inverse">
</div>
How can I replace this with a in Angular? So far I have coded this:
<select data-ng-model="inverse">
<option value="??">Sort Up</option>
<option value="??">Sort Down</option>
</select>
Can someone tell me am I doing it the right way and how can I set the values ?
Alot depends on the data you are using, and how you want the user to sort, but I created a basic example in this jsFiddle that you can play around with: http://jsfiddle.net/xRkhc/2/
HTML:
<div ng-controller="MyCtrl">
<div ng-repeat="row in gdata | orderBy:sort">
{{row.model}}
</div>
<select ng-model="sort">
<option value="model">Sort Up by Model</option>
<option value="-model">Sort Down by Model</option>
<option value="topSpeed">Sort Up by TopSpeed</option>
<option value="-topSpeed">Sort Down by TopSpeed</option>
</select>
</div>
Controller:
function MyCtrl($scope) {
$scope.sort = "model"; //just to set the default sort in the dropdown, not required
$scope.gdata = [{'model':'M3','topSpeed':'200'},{'model':'Type R','topSpeed':'150'}, {'model':'S2000','topSpeed':'160'},{'model':'NSX','topSpeed':'180'}];
}
When you hardcode the options (as in your code) the model only receives strings or numbers, you must use ng-options (or it's equivalent data-ng-options) instead of hardcoding the options. You specify the options as a member of your model.
Here's a complete example:
<!doctype html>
<html data-ng-app>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.min.js"></script>
<script>
var exampleCtrl = function ($scope) {
$scope.sortingDirection = {
'Sort Up' : true,
'Sort Down' : false
};
$scope.inverse = true;
}
</script>
</head>
<body>
<div data-ng-controller="exampleCtrl">
<select data-ng-model="inverse" data-ng-options="value as key for (key, value) in sortingDirection">
</select>
<pre data-ng-bind="inverse | json"></pre>
</div>
</body>
</html>