How to set a default value to ng-options (multiple select) - angularjs

I wanted to set a default value to my ng-options by using ng-init, ng-model, etc. They didn't work at all. My code is following:
Angular
var app = angular.module('role', []);
app.controller('fooController', function($scope){
$scope.roles = [{id:1, name:"Administrator"}, {id:2, name: "Student"}];
$scope.user.roles = $scope.roles[0];
});
HTML
<body data-ng-app="role" data-ng-controller="fooController">
<select multiple class="form-control" data-ng-model="user.roles" data-ng-options="role.name for role in roles" required=""></select>
</body>
Here is my Plunkr.
Any help would be appreciated.

Update:
If you want to get directly to the reference used in this answer, here it is:
Reference:
Initial Selection In AngularJS ng-options with track by
Here's what worked for me:
app.controller('fooController', function($scope){
$scope.roles = [{id:1, name:"Administrator"}, {id:2, name: "Student"}];
$scope.user = {};
$scope.user.roles = [ $scope.roles[0] ];
});
There was an error in the plunk that user wasn't initialized, apart from this, Angular would compare every object in the ng-options array to every element in the ng-model array. JavaScript comparison not Angular comparison, comparing 2 objects even with same properties in JavaScript returns false (different objects).
Plunk: http://plnkr.co/edit/ccsAVvPACnN6Qzje7HcB?p=preview
.
Now, this is not ideal. Typically you want to correlate these based on ID or so, here's another way:
In HTML, use track by to tell AngularJS to compare IDs instead of entire objects:
<select multiple class="form-control"
data-ng-model="user.roles"
data-ng-options="role.name for role in roles track by role.id"
required=""></select>
Then in your controller, you can use any object without actually being in the array:
app.controller('fooController', function($scope){
$scope.roles = [{id:1, name:"Administrator"}, {id:2, name: "Student"}];
$scope.user = {};
$scope.user.roles = [ {id:1, name:"Administrator"} ];
});
Plunk: http://plnkr.co/edit/NKLXrwqwk36YfhBSXILN?p=preview
Note that I didn't even need the name property. It's just for making a proper object later, but it really isn't needed for matching now, try without it!
.
I wrote a detailed tutorial with an accompanying video on this initial selection problem and its variations. It's focused on single-select but multi-select is just using an array of objects instead of one object directly.
Check it out for more understanding -- highly recommended:
Initial Selection In AngularJS ng-options with track by
.
Let me know in comments if you are still struggling with this.

if your model is like $scope.user.roles = [1]; then your ng-options should be like this,
data-ng-options="role.id as role.name for role in roles"
this will select only the ID
if you do like data-ng-options="role.name for role in roles" then your model should be like
$scope.user.roles = [{id:1, name:"Administrator"}];
because this will select the whole object
and in your controller
$scope.user = {}; //this line should be add
because your trying to access a roles property of user but there is no user object defined, this will also occur a error
here is the Updated Plunker
here is the updated plunker1 plunker2 for your case of ng-options
you can use ng-init here. please check.

like this
<body ng-init="role.name = roles[0].name" data-ng-app="role" data-ng-controller="fooController">
<select multiple class="form-control" data-ng-model="user.roles" data-ng-options="role.name for role in roles" required=""></select>
</body>

Your Plunkr has errors. You have to define $scope.user = {}; before you use it. Then it will work.
Note: This will only set an initial value to model. If you want to make Administrator highlighted by default, you'll have to figure out some other way.

Related

ng-init does not initialize my selected model

I have a select option where I get a list of titles i.e. Mr, Mrs, Dr etc. from an API, the code looks like this in the front end:
<select class="form-control" name="titleSelect" id="titleSelect" ng-options="option.value for option in titleData.availableOptions track by option.key" ng-model="adult[$index].selectedTitle" ng-init="adult[$index].selectedTitle = titleData.availableOptions[0]"></select>
And this in the controller:
var getPassengerTitle = PassengerDetailsAndCardDetailsService.getPassengerTitle();
PassengerDetailsAndCardDetailsService is service, where I get the API data i.e. the title data. Furthermore this service returns a promise.
This is where I set the title Data:
getPassengerTitle.then(function(result){
$scope.availableTitles = angular.fromJson(result.titleList);
$scope.tempListOfTitles = [];
for(var key in $scope.availableTitles){
$scope.tempListOfTitles.push({key : key, value : $scope.availableTitles[key]});
};
$scope.titleData = {
availableOptions: $scope.tempListOfTitles,
};
});
When I try to ng-init to the first option (that is Mr.) it does not work as in a blank option is shown. However when I tried statically defining the titleData in an object it works, could you please help me?
UPDATE:
I failed to mention that the title data is inside an ng-repeat to support input for multiple people/passengers in this case. Therefore I'm using adult[$index] where it creates an ng-model for each person/passenger.
I am not sure if this is the required behavior you want, but if you want to initialise the title on selecting an option you can either use the value from ng-model or use the event handler ng-change. Here is an example jsbin which handles the change and assigns the new value to ng-model. Let me know if this is what you were looking for
try like this.
var myapp = angular.module('app', []);
myapp.controller('Main', function ($scope) {
var vm = this;
vm.adult = {
'selectedTitle':'1'
};
vm.titleData = [
{'key':'0','value':'Mr'},
{'key':'1','value':'Ms'},
{'key':'2','value':'Dr'}
];
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app = "app">
<div ng-controller="Main as ctrl">
<div class="select-style">
<select ng-options="option.key as option.value for option in ctrl.titleData" ng-model="ctrl.adult.selectedTitle"></select>
</div>
</div>
</div>

Using Angular.js with multiple html select fields, ng-repeat (and ng-model)

I'm trying to use angularjs with multiple html select fields and I want to store all the selected elements in an array.
May code would look like this:
<body ng-app="" ng-controller="myController">
{{selectedElements}}
<div ng-repeat="elem in selectedElements">
<select
ng-model="elem.someThing" <-- I do not want the someThing here
ng-options="obj.name for obj in objects">
</select>
{{elem}}
</div>
<script>
var myController = function ($scope) {
$scope.selectedElements = [{},{}]
$scope.objects = [
{"id": "1234","name": "a"},
{"id": "12345","name": "b"},
{"id": "123456","name": "b"},
{"id": "123458","name": "c"}
];
};
</script>
You can also find a fiddle here: http://jsfiddle.net/dg76hetu/12/
The issue is, that I do not really want to use:
ng-model="elem.someThing"
because my selectedElements Array then includes "someThing" as a key. (see in fiddle)
Intuitively I would want to do something like:
ng-model="elem"
However, this does not work and I am also aware that I should not bind to the model without the dot notation.
So my question is, how can I use angular to store all the selected objects from the multiple select fields inside the "selectedElements" Array? I feel like I am missing something basic, however I just can't get it to work.
Any help is highly appreciated.
You can link ng-model to actual value using $index and passing array[$index] in to ng-model directly.

Cannot bind ngResource to ngOptions

I have a select element, and I want it populated with the result of a call to a resource via ngResource.
<select chosen=""
required
data-ng-model="coolStuffSelected"
data-ng-options="stuff for stuff in coolStuff"
class="chosen-select input-md"></select>
In my Controller I have
CoolStuffResource.query(function(result){
$scope.coolStuff = result;
console.log(JSON.stringify($scope.coolStuff));
// prints ["foo","bar","gaz","waka"]
});
I see the result logged, but the select is empty. What am I doing wrong?
Update: I tried this albeit hacky workaround, which is to access the ng-model :
MyCoolService.query(function(result){
$scope.coolStuff = result;
$scope.coolStuffSelected = null;
});
This works in Chrome, but does not work in Safari. Simply hardcoding the values works fine in both browsers:
$scope.coolStuff = ["foo", "bar", "gaz", "waka"];
Here's a working JsFiddle from your other question, demonstrating the returned data from there.
<select ng-model="selected" ng-options="d for d in data"></select>
JS:
function MyCtrl($scope) {
MyCoolResource.query(function(result){
$scope.data = result;
});
}
What does the JSON look like in your response? Your ng-options expression is most likely wrong. You need to tell it what you want displayed in your select.
Change your ng-options: so it looks something like this:
ng-options="stuff as stuff.label for coolstuff"
Change stuff.label to whatever property you want displayed in your select.
Take a look at this documentation: https://docs.angularjs.org/api/ng/directive/ngOptions

How can I use Variable expressions in AngularJS

In PHP I can use a double dollar sign to use a variable to represent another variable. If like to do the same in AngularJS expressions.
For example if I had an object with property1, property2 etc each with different values I would reference them directly as {{$scope.property1}}
What I would like to do is something like string propertyToDisplay = 'property1' and then use {{$scope.propertyToDisplay}} show the value stored in property1.
Does AngularJS support this?
This appears to be an XY problem. In general, the $scope variable shouldn't be appearing in your views at all, let alone that you seem to be trying to go outside the boundaries of what should be put in the markup for an AngularJS view.
In general, the parts of your controller that should appear in your view are (1) properties of the scope (or properties of properties, etc.) (2) functions that are part of the scope (with scope properties passed in as arguments). For anything involving dynamic functionality, you should generally be using the latter. So you could have your controller defined like this:
angular.module('myModule', [])
.controller('myController', ['$scope', function ($scope) {
$scope.properties = {
property1: "Hey!",
property2: "Hi"
};
$scope.selectedProperty = '';
$scope.getProperty = function (propertyName) {
return $scope.properties[propertyName];
};
}]);
And then your view could have something like this:
<select ng-model="selectedProperty">
<option value="property1">Property 1</option>
<option value="property2">Property 2</option>
</select>
<p>The value of the property you selected is: {{getProperty(selectedProperty)}}</p>
You can access variable object attribute using square brackets:
attrname ='attribute_name';
obj[attrname] = something;
How about using another object to store the visibility of each object property (DEMO).
$scope.visible = {};
$scope.person = {
first_name: 'John',
last_name: 'Rambo',
city: 'Hollywood'
};
Create a list with checkboxes for each property:
<div ng-repeat="(key, value) in person">
<input id="{{key}}Check" type="checkbox" ng-model="visible[key]">
<label for="{{key}}Check">{{key}}</label>
</div>
And check the visibility of each property in the form:
<input type="text" ng-model="person.first_name" ng-show="visible['first_name']">
If you want the form to be dynamic too (only input fields in this case) you can of course put this in a ng-repeat too:
<input ng-repeat="(key, value) in person" type="text" ng-model="person[key]" ng-show="visible[key]">
Hope this is at least close to what you want.

angularjs create dynamic dropdowns

i want to create a form dynamically from a json string that is coming from a database. I am new to angularjs and I would like to know how to create a dropdown control dynamically within a repeater. Below is an example of my code
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.fields = [
{"reference_id":209,"form_id":1,"name":"firstname","label":"First Name","type":"text"},
{"reference_id":210,"form_id":1,"name":"lastname","label":"Last Name","type":"text"},
{"reference_id":211,"form_id":1,"name":"email","label":"Email","type":"text"},
{"reference_id":212,"form_id":1,"name":"picture","label":"Picture","type":"file"},
{"reference_id":213,"form_id":1,"name":"address","label":"Address","type":"file"},
{"reference_id":214,"form_id":1,"name":"select","label":"values","select ng-model":"select"}, ];
As was mentioned in a comment, you'll want to use ngOptions.
Plunk example
You'll want to structure your html similar to this:
<select ng-model="currentField" ng-options="field.reference_id as field.label for field in fields"></select>
currentField will always result in a reference_id being selected. You can change it to name or any of the other properties of $scope.fields.

Resources