ng-model with association on select box with ng-repeat on options - javascript

I have a Plunker here illustrating my issue. I have an object with an associated division. There is no division_id on the object, but in order to set or update the division I need to set the division_id field. Here's the sample object:
$scope.user = {
name: "John",
age: 32,
division: {
id: 3,
name: "Alpha"
}
};
And the example divisions:
$scope.divisions = [
{
name: "Gamma",
id: 1
},
{
name: "Alpha",
id: 3
},
{
name: "Beta",
id: 5
}
];
The way I'm building the select box is with ng-repeat, which I was hoping would bypass the need to track ng-model for the selected value.
<div class="form-group">
<label for="">Division</label>
<select type="text" ng-model="user.division_id">
<option ng-repeat="division in divisions"
ng-selected="user.division.id == division.id">{{ division.name }}</option>
</select>
</div>
As you can see in the demo, the selected attribute is being placed on the right option, but still the select box display is blank. Even if I add division_id: 3 to the object, it continues to be blank. How can I get this to work without having to do a conversion on the object when loading and updating?
Edit: To address this question being flagged as a duplicate, I think this is unique because I'm asking how to build the select box with ng-repeat, not ng-options. Though the answer is similar to the answer for the proposed duplicate, I think other people might get stuck on this method and find it helpful to see the answer requires a different technique.

If you update your select as follows it will display by default to the users division.id.
<select ng-model="user.division" ng-options="d as d.name for d in divisions track by d.id">
You seemed to be wanting to have a separate model division_id, the only reason I can think of for this is that you wanted to control the persistence of the user model when the selection is updated. If for some reason you want to intercept the end-users selection to the user model (or even just the in-memory user object) being updated then use a copy/there are many ways to do that, but it's not clear if that's what you're asking.
Updated plunkr
Note it would have worked to have kept the same option ng-repeat syntax, but this is the recommended angular way to deal with options.

As per your plunker, you need to remove the ng-model directive from the select tag for it to work.
if you need to set a division_id variable for your code, you can use ng-init.
<div class="form-group">
<label for="">Division</label>
<select type="text">
<option ng-repeat="division in divisions"
ng-selected="user.division.id == division.id"
ng-init="division_id=division.name">{{ division.name }}
</option>
</select>
</div>

Related

How do I set the default option for select with AngularJS?

I have been working on trying to set the default pre-selected option for angularJS and for some reason I can't. Here is a link to the relevant Plunkr.
Here is the relevant code:
<select
ng-model="selectedOption"
ng-options="option.value as option.name for option in options">
</select>
I've tried ng-init and a bunch of different ways; I can't figure how to make the top option the preselected one.
The linked answer suggests using ng-init. I would go with assigning default option into selectedOption in controller or directive's link function:
$scope.selectedOption = options[0]
I don't see a need to use another directive for this simple task.
If what you want is to set one of the options pre-defined in options,
in your ng-init do something like this $scope.selectedOption = <value> where <value> is the value property of the object you want to be marked as selected by default. For example 1 if your first object in options would be, {value: 1, name: "Option Number 1}. See code below:
$scope.options = [{value:1, name: "Option 1"}, {value:2, name: "Options 2"}];
$scope.selectedOption = 1;
On the other hand, if you only want to show a predefined option indicating the user to select one option (and not one of the options in your options)...
This is a very simple (but effective way to achieve that). See code below:
<select
ng-model="selectedOption"
ng-options="option.value as option.name for option in options">
<option value="">--Default--</option>
</select>
just update model of the element i.e. selectedOption='yourDefaultValue'
What is the version of angular are you using?
if the latest one, then you can use below code::
<select
ng-model="selectedOption" [ng-value]='yourDefaultValue'`
ng-options="option.value as option.name for option in options">
</select>
Link to updated plunkr : http://plnkr.co/edit/SkS0NqyXpnMcddu80anf?p=preview
Updating model code moved in the function and also select as and track by should be avoided as mentioned in the angular doc
Be careful when using select as and track by in the same expression.

Want to add none as value in select multiple

I am using chosen.jquery.js for select field
<select chosen multiple data-placeholder="Select Body Part(s)"
ng-options="option.Name as option.Name for option in BodyPartList" ng-model="Body_Part">
<option value="" disabled>Select Body Part(s)</option>
</select>
But It shows only data-placeholder value in case of no data in model.
I want to show "Select Body Part(s)" as a option in list.
And user must not select this. Reason is that, I want to add dynamic "Unknown" value in list of Body_Parts. But it not reflect in list.
Same work for select having single selection.
I'm not seeing any problems with your code, as such. Like, I'm trying it and getting the visual behaviour I think you're wanting? Am I missing something?
Html just yours with ng-app etc, javascript is:
var myApp = angular.module('myApp', ['localytics.directives']);
myApp.controller('MyController', function($scope) {
$scope.BodyPartList = [
{ Name: "Arm" },
{ Name: "Leg" }
];
$scope.Body_Part = [];
});
Not sure if data-placeholder is actually doing anything.
Fiddle: http://jsfiddle.net/7187f6d9/
That said, it's not "working". In the fiddle I put a regular select box alongside the chosen one, and the chosen one doesn't seem to be writing to the ng-model correctly. I'm not sure what's up with that.
You can choose the below option
https://harvesthq.github.io/chosen/#optgroup-support
or push another item to the top of the array from server side as your custom label and disable it on client side with the help of ng-if and $index properties of ng-repeat and angularjs. If this make sense then its fine else i can give you a demo.
I hope your query is, you want show a place holder as current selected value but user shouldn't be able to select it.
Instead of making it disabled, make ithidden. Then display an error if a user doesn't select any other options, using the value of placeholder option.
A sample snippet is added below. If value of select is Error, write a case to throw a error back to user.
<select>
<option value="Error" hidden>Select any Company</option>
<option value="Toyota">Toyota</option>
<option value="Nissan">Nissan</option>
<option value="BMW">BMW</option>
</select>
Hope this helps! If not, ping me with your query. :)

How to set default selected value in Angular Chosen?

I have a select tag to which I am applying angular chosen.
This is my select tag
<select name="rname" id="rname" ng-model="rname" ng-init="rname='CustomReport'"
ng-options="key as value for (key , value) in reportsValuesOptions track by key" chosen>
<option value="">---Select---</option>
</select>
The above select tag is getting populated from below object
$scope.reportsValuesOptions = {'Cash Position Report':'Cash Position Report','Detail Report':'Detail Report','Reconciliation Report':'Reconciliation Report','Summary Report':'Summary Report','Sweep Report':'Sweep Report','FCCS/FBPS Detail Report':'FCCS/FBPS Detail Report','CustomReport':'Custom Report Name'};
The object is a pair of values and options for select tag where the key is options tags value and the value is the option tag text
Now I want to set the default value of the select tag to 'CustomReport' as its option value and 'Custom Report Name' as its option text from the above object, using ng-init.
I tried doing ng-init="rname='CustomReport'", but it doesn't work
How to set its value from object's key value pair?
FULL EXAMPLE
The problem with your solution is since you are giving an object and AngularJS is mostly designed for arrays it causes AngularJS not to be able to track them properly. You probably wanted to write a shorter object for reportsValueOptions but it should be an array of objects which has a form similar to the following:
[
{label: 'First Label', value:'first-option'},
{label: 'Second Label', value:'second-option'}
]
Here is the modified version of your jsfiddle with modified object that also shows which one is selected.
You can also learn more about problems with objects here: https://docs.angularjs.org/api/ng/directive/ngOptions#complex-models-objects-or-collections-
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>

Meteor Select Box - mark option as selected depending on data context

I have been trying to figure out how to set the 'selected' attribute on an option within a select box and have fallen short today. Any help would be appreciated.
What I'm trying to accomplish:
When a user chooses an option and hits submit, the data saves to a new mongo document and the new entry is shown on the screen (this part works). Upon browser refresh, the state is lost (due to no selected attribute being set) and the select box goes back to the first option. I need to figure out how to set the selected state depending on the value the user has saved on that particular document. On this page there are many of the same select boxes allowing the user to choose different options for other entries.
References (tried to implement with no luck):
Check for equality in Spacebars?
https://github.com/meteor/meteor/wiki/Using-Blaze#conditional-attributes-with-no-value-eg-checked-selected
How do I indicate 'checked' or 'selected' state for input controls in Meteor (with spacebars templates)?
select box template:
<template name="tEdit">
<div class="form-group">
<div class="controls">
{{> fFEdit}}
</div>
</div>
</template>
select box option template:
<template name="fFEdit">
<select class="form-control" name="fFSelect">
{{#each fFSelect}}
<option value="{{fId}}">{{fF}}</option>
{{/each}}
</select>
</template>
setting data context
Template.fFEdit.helpers({
fFSelect: function() {
var fFArray = [
{ fF: "foo", fId: 0 },
{ fF: "bar", fId: 1 },
{ fF: "buzz", fId: 2 }
];
return fFArray;
}
});
If you want state to be persisted across browser refreshes, you should be able to either fetch it from the server or from something like the Meteor Session.
The second thing you'd need is a helper to get the selected state. Conveniently, Meteor makes the data context available under this (for an each loop, this context is an individual item).
Template.userEdit.helpers({
userSelected: function() {
if(this.id === Session.get("selectedUserId")) {
return "selected";
}
}
});
This assumes you've set the Session variable previously with something like Session.set("selectedUserId", user._id).
Then in your template:
<template name="userEdit">
<select class="form-control" name="userSelect">
{{#each users}}
<option {{userSelected}}>{{username}}</option>
{{/each}}
</select>
</template>
(Note: The selected state can not actually be seen by inspecting the DOM with an element inspector.)
I'm not sure if this is the best answer to my problem, though this is what I came up with to add the selected attribute to the saved option. I welcome anyone else with a better/Meteor solution for this.
When the user clicks the edit link, I find the inputs that need to be updated and assign the values onClick. Ideally I'd rather have this already done on pageLoad, though feel that that solution may impact the initial pageLoad time.
Template.tItem.events({
'click .edit-t-item': function(e) {
e.preventDefault();
var $editTWrapper = $(e.currentTarget).next('.edit-t-wrapper');
$editTWrapper.find('[name=tNEdit]').val(this.tName);
$editTWrapper.find('[name=fFSelect]').val(this.fFId);
}
});

Selected value for angular select not be set on page refresh

The selected value of my angularjs select is not being set on page refresh.
It is set if I navigate to a different view and then navigate back again.
The model for the select is saved to local storage and is initialized into the scope onload.
I have checked that the data in the scope is the same in the two situations of navigating away and back again, and refreshing the page. The data is exactly the same.
After a lot of investigation, I see that when the select is pristine, or when the page is refreshed, the select list will have an extra blank option, like first one below with value ?:
<select ng-model="question.answer" class="form-control" ng-options="opt as opt.value for opt in question.options" >
<option value="?" selected="selected"></option>
<option value="0">1</option>
<option value="1">2</option>
</select>
Note The above HTML is the output. My Angular view just has:
<select ng-model="question.answer" class="form-control" ng-options="opt as opt.value for opt in question.options" />
I'm not sure why this would be preventing the correct option from being selected as the correct object is still present at question.answer. See a simplified version of the model below:
var question = {
options: [
{
id: 1,
value: "1"
},
{
id: 2,
value: "2"
}
],
answer: {
id: 2,
value: "2"
}
};
My understanding is that in ng-options, the first opt specifies that this is the value that should be assigned to the variable specified in ng-model. In other words, I will be assigning an object in the options array to question.answer, rather than just the value. I can see by looking at the model that this is the case.
But I'm not sure how Angular will use the value in question.model to determine which option is set as selected.
I wonder if the problem is something to do with the fact that the values of the options are set as indices of question.options and it can't work out from question.answer which index that answer is.
So, I guess my questions are:
- Why is the correct option not being set when this extra <option value="?" selected="selected"></option> is present?
- How does Angular determine how to use the model to set the selected option (aka - what are those funny indices in the option values?)
Sorry this post is so long. Thank for reading.
Update:
Using the Chrome AngularJS Batarang extension, that the value being set to question.answer for a picklist is e.g.:
{
$ref: $["options"][1]
}
which will means the value of the picklist is "2".
So that is how it is using the indices of the options are being used, but is that how I have to set my model? i.e. using the $ref etc?
I edited the answer after I looked at what you were doing.
The ng-options attribute has a track by expression to do just what you're talking about:
ng-options="opt as opt.Value for opt in question.options track by opt.id"
See the updated fiddle: http://jsfiddle.net/CkLEu/6/

Categories

Resources