AngularJS select option initialize - angularjs

I have this select tag:
<select class="form-control" data-ng-model="contact.title" data-ng-options="title.title as title.title for title in titles track by title.title">
<option></option>
</select>
and when I will edit the title nothing is selected but contact.title is Mag.. Therefore Mag. should be selected. Does anyone know what I have to do in order that Mag. is selected?

From what I found tinkering around in a jsfiddle, the 'track by' was unnecessary.
Please try removing it.
<select class="form-control" data-ng-model="contact.title"
data-ng-options="title.title as title.title for title in titles">
<option></option>
</select>
Changing the 'track by' portion to $index or another value changes the selection. It's best to not use it if you are sure all titles will be unique.

Working code for me:
<select class="form-control" data-ng-model="contact" data-ng-options="title.title for title in titles track by title.title">
<option></option>
</select>
In controller:
$scope.titles = [{title: "abc"}, {title: "pqr"}, {title: "xyz"}];
$scope.contact = $scope.titles[0];
Try this.

Try this:
$scope.titles = [{title: "abc"}, {title: "pqr"}, {title: "xyz"}];
$scope.contact = {};
And:
<select name="repeatSelect" id="repeatSelect" ng-model="contact.title">
<option ng-repeat="title in titles" value="{{title.title}}">{{title.title}} </option>
</select>

Use the ng-init directive to have a default option in a select. You can use something like:
html:
<select ng-init="contact.title = titles[0]"
ng-model="contact.title"
ng-options="title.title for title in titles">
</select>
js:
$scope.titles = [{title: "Title A"}, {title: "Title B"}, {title: "Title C"}];

tl;dr
Set the initial value the model for contact in the controller, change the ng-model attribute of the select list to just contact and update the ng-options to data-ng-options="title as title.title for title in titles".
Selecting "Mag."
Does anyone know what I have to do in order that Mag. is selected?
In order to select Mag. (the first item in the list of titles, ensure that there is a property contact setup in the controller to the first element in the array of titles (i.e. $scope.contact = $scope.titles[0];). Also, change the ng-model attribute of the select from contact.title to contact.
ngOptions expression syntax
Also, review the syntax for comprehension_expression under the Arguments section of ngOptions.
The titles data sources is an array, so under array data sources, we have an expression like this format:
select as label for value in array
The value of select should not be the same as label. So update the ng-options attribute like this:
data-ng-options="title as title.title for title in titles track by title.title"
And as has already been mentioned, the track by clause is unnecessary. It would be useful if there was a different property we needed to account for (e.g. an integer named id). Thus the ng-options attribute can be simplified to:
data-ng-options="title as title.title for title in titles"
Example
See it demonstrated in the snippet below:
angular.module('app', [])
.controller('ctrl', function($scope) {
$scope.titles = [{
title: "Mag."
}, {
title: "Mag.(FH)"
}, {
title: "Mag. Dr."
}, {
title: "Dr."
}];
$scope.contact = $scope.titles[0];
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="ctrl">
<select class="form-control" data-ng-model="contact" data-ng-options="title as title.title for title in titles">
</select>
<div>Contact.title: <span ng-bind="contact.title"></span></div>
</div>
Avoid ngInit
It has been suggested that ng-init be used to set the initial value, however, there is a note about this on the documentation for ngInit:
This directive can be abused to add unnecessary amounts of logic into your templates. There are only a few appropriate uses of ngInit, such as for aliasing special properties of ngRepeat, as seen in the demo below; and for injecting data via server side scripting. Besides these few cases, you should use controllers rather than ngInit to initialize values on a scope.1
This is because (one of) the uses of controllers is to:
Set up the initial state of the $scope object.2
Business logic like that should not be added the template.

Related

Select default option with ng-options using a flat array

I'm generating <option>'s with ng-options using a flat array. The problem I'm having is selecting the default option element I already have defined. Seems to be a very simple task and there's tons and tons of similar questions using objects or array of objects, but everything I have found and tried for my situation does not work.
<div ng-app="MyApp">
<div ng-controller="MyCtrl">
<select ng-options="opt as opt for opt in testOpt" data-ng-model="resultOpt">
<option value="">Choose Category</option>
</select>
</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.7.8/angular.min.js"></script>
angular.module('MyApp', []).controller('MyCtrl', ['$scope', function ($scope) {
$scope.testOpt = [
'ID',
'Name',
'Email',
'Address'
];
$scope.resultOpt = '';
}]);
What I'm trying to do is select the "Choose Category" option by default. As plenty of others have already suggested in other questions, I have tried to use $scope.resultOpt = '' in my controller and even tried ng-init="resultOpt = ''", but does that not work at all. This works great for an array of objects, or objects but not with simple arrays. I also do not want to go outside of the AngularJS framework, I don't like mixing and matching vanilla and AngularJS code, things become messy.
I found an existing jsFiddle that is working for AngularJS 1.4.8, but at least for AngularJS 1.7.8, this is not working when used with a flat array. Not sure if it was functionality that was removed in later versions, or it's simply a bug.
Full example:
https://jsfiddle.net/v4uesg02/4/
How can I select the "Choose Category" option by default using a flat array without going outside of AngularJS framework?
How to select the hard-coded null option with ng-options and ng-model
To select the single hard-coded <option>, assign null to the model:
angular.module('MyApp', []).controller('MyCtrl', ['$scope', function ($scope) {
$scope.testOpt = [
'ID',
'Name',
'Email',
'Address'
];
̶$̶s̶c̶o̶p̶e̶.̶r̶e̶s̶u̶l̶t̶O̶p̶t̶ ̶=̶ ̶'̶'̶;̶
$scope.resultOpt = null;
}]);
From the Docs:
Optionally, a single hard-coded <option> element, with the value set to an empty string, can be nested into the <select> element. This element will then represent the null or "not selected" option.
For more information, see
AngularJS <select> Directive API Reference
The DEMO
angular.module('MyApp', [])
.controller('MyCtrl', ['$scope', function ($scope) {
$scope.testOpt = [
'ID',
'Name',
'Email',
'Address'
];
$scope.resultOpt = null;
}]);
<script src="//unpkg.com/angular/angular.js"></script>
<body ng-app="MyApp" ng-controller="MyCtrl">
<select ng-options="opt as opt for opt in testOpt"
data-ng-model="resultOpt">
<option value="">Choose Category</option>
</select>
<br><br>
<button ng-click="resultOpt=null">Reset</button>
</body>
One thing i would like to add to #georgeawg's answer is to put disabled as an attribute to the option so that it is not reselect-able in the future
<option value="" disabled>Choose Category</option>

How do I populate a multiple select dropdown with JSON data using Materialize and Angularjs?

I've seen numerous examples of angularjs using JSON data to populate options in a select dropdown, but after numerous attempts and variations I still end up with a blank dropdown menu. I'm sure there's something wrong with my object naming convention, as all the angular examples are pretty confusing (what's plural? what isn't? etc.) Any help you can offer would be greatly appreciated.
JSON example:
{"fields":[
{"state": "OH",
"gender": "male"},
{"state": "OH",
"gender": "female"},
{"state": "IN",
"gender": "male"}
]};
html:
<div class="input-field col s12 m4" ng-app="totalQuery" ng-controller="queryCtrl">
<select multiple>
<option ng-repeat="fields in myData">{{fields.state}}</option>
</select>
<label>First Category</label>
</div>
<div class="input-field col s12 m4" ng-app="totalQuery" ng-controller="queryCtrl">
<select multiple>
<option ng-repeat="fields in myData">{{fields.gender}}</option>
</select>
<label>Second Category</label>
</div>
angularjs:
<script>
var app = angular.module('totalQuery', []);
app.controller('queryCtrl', function($scope, $http){
$http.get("file.json").then(function(response){
$scope.myData = response.data.fields;
});
});
</script>
You just need to add .fields into your ng-repeat.
Change:
<option ng-repeat="fields in myData">{{fields.state}}</option>
To:
<option ng-repeat="fields in myData.fields">{{fields.state}}</option>
Here is a jsFiddle of the solution: http://jsfiddle.net/eLnfgnc9/4/
It is worth noting, that it is better to use ng-options instead of ng-repeat. I find it more confusing than ng-repeat but it just seems to work better. Here is a link to the angular doc for ng-options: https://docs.angularjs.org/api/ng/directive/ngOptions
First of all you don't need to define ng-app and ng-controller twice.
Secondly what I don't understand is why are you using two drop down menu's or jump menu to change the state and according to that you will bring the gender ? right ?
If that's the case usually when you you are working with drop down menu you need an id for each option which will be sent back to bring changed item on the basis of id.
I've made a working plunker Populate Drop Down with Json please take a look if that's what you need. I'm sure you will get the idea how to do it.

Why does Angular add an empty <option> if the value exist in the provided options?

I have read on many occasions that Angular tends to add an empty option at the beginning of the select element if the value of the model does not exist among the offered options.
However, I have a model whose value is set to 0 from the start, and 0 is provided as one of the options in the select element as well, yet there is still one empty option above my own options. It disappears after the actual option whose value is 0 gets selected.
Why is this and how do I get rid of it?
A very simple example of the problem I am experiencing is displayed here: http://jsfiddle.net/yuvnz7wr/
The javascript code:
var app = angular.module('Module', []);
app.controller('Test', function ($scope) {
$scope.model = 0;
$scope.options = [{
id: 0,
name: 'Zero'
}, {
id: 1,
name: 'One'
}];
});
The HTML code:
<div ng-app="Module">
<div ng-controller="Test as test">{{model}}
<select ng-model="model">
<option ng-repeat="option in options" ng-value="option.id">{{option.name}}</option>
</select>
</div>
</div>
You better use ng-options and ng-init directives for <select> with angular:
<div ng-app="Module">
<div ng-controller="Test as test">{{model}}
<select ng-model="model" ng-init="model = options[0].id" ng-options="option.id as option.name for option in options"></select>
</div>
</div>

Angularjs ng-selected populate

I am trying to populate the currently selected item in angular js.
The currently selected item is that with the id in event.email.chases[0].id
and I am trying to match it to a select box populated from case.activeChases
This does what I want so far, which updates whenever the select box changes.
<select
class="form-control"
name="chase"
id="chase"
ng-model="customer.chase"
ng-change="addEmailToChase(customer.chase.id, event.email.id)"
ng-options="cor as cor.emails[0].subject for cor in case.activeChases">
<option value="">None</option>
</select>
I need to find the chase in activeChases with activeChases[x].id = event.email.chases[0].id, so the correct value is selected upon the page load.
Could I possibly do this all within a ng-selected attribute?
Something wrong with your model and your ng-options, the object should be the same if you want an "auto-selected"
without a jsfiddle it's hard to reproduce your situation but I tryed something like that
var app = angular.module('App', []);
app.controller('Ctrl', function($scope) {
$scope.case = {
activeChases: [{
emails: [{
subject: 'toto'
}]
}, {
emails: [{
subject: 'tata'
}]
}]
};
// set "default value"
$scope.customer = {
chase: $scope.case.activeChases[1]
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<section ng-app="App" ng-controller="Ctrl">
<select class="form-control" name="chase" id="chase" ng-model="customer.chase" ng-change="addEmailToChase(customer.chase.id, event.email.id)" ng-options="cor as cor.emails[0].subject for cor in case.activeChases">
<option value="">None</option>
</select>
</section>
So this was my answer:
<select
class="form-control"
name="chase"
id="chase"
ng-model="event.email.chases[0].id"
ng-change="addEmailToChase(event.email.chases[0].id, event.email.id)"
ng-options="cor.id[0] as cor.emails[0].subject for cor in case.activeChases">
</select>
I wanted the default value to be event.email.chases[0].id in the select, so I just set ng-model to that, and changed the first option to cor.id[0] to use id in index.
I chose a random name for ng-model which was customer.chase which made no sense. event represents an ajax loaded form element so its safe for me to do this in my scope.
Also worth noting that the id in cor.id[0] is actually in a size one array due to incorrect design in the app.

Show HTML element if the Array provided has a nested Array using Angular.js

I want to populate a dropdown with an array, and if the user chooses an option that has a nested array, Then and only then I want to show another dropdown and populate it with that child array, and so on.
And then populate a hidden field with the last value of the chain.
How would I approach this with Angular.js?
You can use ng-show to conditionally show/hide the second drop-down
The code can be seen/tested here
Controller:
app.controller('MainCtrl', function($scope) {
$scope.items = [
{name:'item1'},
{name:'item2', subItems: [
{name:'sub item 1'},
{name:'sub item 2'}]}];
});
Markup:
<p>
<select ng-model="selectedItem" ng-options="i.name for i in items"></select>
</p>
<p ng-show="selectedItem.subItems">
<select ng-model="selectedSubItem" ng-options="i.name for i in selectedItem.subItems"></select>
</p>
Use ng-change directive in your select tag and in ng-change call a function that checks your scenario.
If you provide your array data, the answer can be given more accurately.
I know this approach is a long run. But it helps you to keep your code clean.
MARKUP
<select ng-model="selectedItem" ng-options="item.name for item in items" ng-change="doesItemHaveSubArray(selectedItem)"></select>
<div ng-if="subItem">
<select ng-model="selectedSubItem" ng-options="item.name for item in subItem"></select>
</div>
In JS
$scope.doesItemHaveSubArray=function(item){
if(item!==undefined){
$scope.subItem=item.subItems;
}
}

Resources