Issue pre-selecting list using ngOptions - javascript

I have a name-value collection which is used to populate a select element. I have a model that I want to link to the id of the selected value. It works when the select element is changed, but I'm having trouble having the initial model value populate the select element on page load. Here is a plunker.
Here is the corresponding code (controller and view):
$scope.items =
[
{id: "1", name: 'This'},
{id: "2", name: 'That'},
{id: "3", name: 'Another'}
];
$scope.itemId = "2";
<select ng-model="itemId">
<option value=""></option>
<option ng-repeat="item in items" value="{{item.id}}">{{item.name}}</option>
</select>
In this example, I expect the That option to be selected since my initial model is 2 (the id of the That item). If Another is selected from the select list, I would expect the model (itemId) to then be "3".
Also included in my Plunker is another way to specify a select list:
<select ng-model="itemId" ng-options="item.name for item in items track by item.id">
<option value=""></option>
</select>
I was able to get the model to pre-load the select successfully using this syntax, but it required my model to be the entire item object, not just the id.
Thanks in advance.

ng-options syntax:
If you want to match your ng-model value, you must select the id (but display the name):
ng-options="item.id as item.name for item in items"
See plunker
Repeated <option> syntax:
You could use ng-selected:
<option ng-repeat="item in items" value="{{item.id}}" ng-selected="item.id === itemId">

You have two options. Your pre-selected value doesn't match the value your selecting. If you added {{itemId}} you would see it change when you select an option.
It would be something like this: {"id":"2","name":"That"}
With your current ng-options you need to pre-select the entire object from your items array. That or change your expression to something like. item.id as item.name from item in items. However with the latter your itemId variable will change from the entir object to just the selected objects id.
Also you do not need your track by, it will track by the elements index by default.

Related

How to programmatically change the selected option in an html select tag

I have a select group in my html to select a price range with. The user can select a range, and then filter the results based on the selection. This works fine, however the user can also reset the results from a totally different place (a search box). I need to change the selection that is actually displayed in the select box so I can reset it to "show all" so that it doesn't look like it is still filtered by price range when the user has actually reset the results from the search box.
I'm able to change the actual value that is selected via the following:
document.getElementById("selectedPriceRange").setAttribute("value","0")
This does actually change the value held in the select box, but the box itself still displays whichever option was last selected.
How can I get the text that is shown in the select box to change without physically selecting another option?
Here's my select box:
<select #priceRangeOptions class="custom-select" id="inputGroupSelect01">
<option *ngFor="let priceRange of priceRangeOptions; let i=index"
id="selectedPriceRange" [value]="i">{{priceRange}}</option>
</select>
Don't use Javascript to query the DOM / set values
Also, from what you posted you don't need an index (although maybe you do)
Instead, you can do this:
<select #priceRangeOptions class="custom-select" id="inputGroupSelect01" [(ngModel)]="option">
<option *ngFor="let option of options;"
id="selectedOption" [value]="option">{{option}}</option>
</select>
<button type="button" (click)="setHotDog()">Choose the hotdog</button>
The [()] syntax denotes two way binding.
As a proof of concept, this typescript sets the model value:
export class AppComponent {
name = 'Angular';
option: string;
options: string[] = ['One', 'Another Choice','Wow, A Hotdog?'];
setHotDog(){
this.option = this.options[2];
}
}
This would be the Angular way, and the correct approach
on select all you have to do is to set ngModel attribute and then you can change variable value to set value.
<select #priceRangeOptions [(ngModel)]="selectedValue" class="custom-select" id="inputGroupSelect01">
<option *ngFor="let priceRange of priceRangeOptions; let i=index"
id="selectedPriceRange" [value]="i">{{priceRange}}</option>
</select>
selectedValue = 'my selected value.';
or you can use javascript to do that
document.getElementById('inputGroupSelect01').value = "value";

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>

How to "map" model values to select box when editing forms in AngularJS?

I am fetching data with a query in my AngularJS controller:
$scope.customers = xAccount.query();
and I am using a select box to show a dropdown item with customer data:
<select type="text"
data-ng-model="mymodel.customer_id"
data-ng-options="customer.id as customer.name for customer in customers track by customer.id">
</select>
The data that the $scope.customers shows are like this:
[
{"id":"12345678","name":"first customer"},
{"id":"23456789","name":"second customer"},
{"id":"34567890","name":"third customer"}
]
The $scope model I am using is:
mymodel.customer_id
Right now I am able to get all the customers by API call, show their names as select labels and ids as select values and then save the selected one to the database as select.value = mymodel.customer_id. This works fine.
What doesn't work is the "edit" view/form. When the edit form (which is the same as the "new" form) is displayed, the select box fetched value is empty. This means that the mymodel.customer_id is set (I can view it as a string like "12345678" in the firebug's JSON display) but it isn't "attached" to the select.value of the form. How can I achieve that?
I tried to use data-ng-init="mymodel.customer_id = (customers | filter:{id: mymodel.customer_id})[0].name" but of course it fails.
I've faced the similar issue before and what I had done to fix is to populate the $scope.customers first and then populate the value in mymodel.customer_id.
So basically, you have to first pull all your customers via $scope.customers = xAccount.query(); when you open your edit form and then you can use the promise success callback of that to pull your customer detail.
I didn't get time to dig into the problem, but that worked for me.
Considering xAccount is an instance of $resource with GET request:
$scope.editCustomer = function() { // Or whatever is your function when your edit form opens
// First get all the customers
$scope.customers = xAccount.query(null, function() {
// When you successfully get your customer data (success callback)
// Now here you have to make another call to get your customer
$scope.mymodel = MyModel.get({id: $routeParams.id});
});
};
Now, what I'm trying to say is that, when you open your edit form (I'm considering editCustomer() method is invoked which is first getting all customers data. After customer data received from the server (and binded to the select in the HTML), then only we are getting the data for the customer being edited using the MyModel.
From the angular docs about ng-options
This will work:
<select ng-options="item as item.label for item in items track by item.id" ng-model="selected"></select>
$scope.selected = $scope.items[0];
but this will not work:
<select ng-options="item.subItem as item.label for item in items track by item.id" ng-model="selected"></select>
$scope.selected = $scope.items[0].subItem;
In both examples, the track by expression is
applied successfully to each item in the items array. Because the
selected option has been set programmatically in the controller, the
track by expression is also applied to the ngModel value. In the first
example, the ngModel value is items[0] and the track by expression
evaluates to items[0].id with no issue. In the second example, the
ngModel value is items[0].subItem and the track by expression
evaluates to items[0].subItem.id (which is undefined). As a result,
the model value is not matched against any <option> and the <select>
appears as having no selected value.
See this plunker.
I cannot however recreate your duplicate scenario.
Actually I spent several hours to figure this out. The ng-options hit me hard. I generated the values by customer.id as.... track by customer.id", so by trying everything out, I saw in the value field of select something strange, like value="string:32445454". At first sight something seemed wrong to me but not enough to stay and fix it. Finally, I tried to remove "track by" section in ng-options and something happened. The right select option was auto-selected but when PUT to the API, I got a message that a field cannot be repeated ...
I checked the value again and saw that the same value was outputting to this field. So I tried to take it manually and set <option ng-repeat="customer in customers" value="{{ customer.id }}">{{ customer.name }}</option> ...guess what? It worked fine.
<select type="text" data-ng-model="mymodel.customer_name">
<option ng-repeat="customer in customers"
value="{{ customer.id }}">
{{ customer.name }}
</option>
</select>
Below is the Options
$scope.statusTypeOption=['Activate','Inactivate'];
Now on UI
<select id="status" class="form-control" ng-init="status" ng-model="status" ng-options="option for option in statusTypeOption"></select>
And in Controller
$scope.status=(response.lCode.status=='A'?'Activate':'Inactivate');

Dropdown doesn't select value from model in Angularjs

I have a select element, which renders a list of objects, nothing spectacular.
<select ng-model="defaultObject" ng-options="obj.description for obj in allObjects">
</select>
which generates:
<select ng-model="defaultObject" ng-options="obj.description for obj in allObjects">
<option value="?" selected="selected" label=""></option>
<option value="0" label="Value 1">Value1</option>
</select>
and it looks fine. It generates first empty option because at the time of rendering allObjects isn't created yet, so that's expected.
However, the problem is that when defaultObject model is set to an object that represents second option inside the select element(Value1), select element doesn't update selected option, everything looks the same. It's like a 1-way binding, defaultObject model can be set from a dropdown, but updating defaultObject doesn't update the dropdown to select that element. Could this be fixed ?
The problem is that angular appears to use == to check what item in the array has been selected. In JavaScript, two objects that contain the same data are still not the same objects, they're references to different objects:
{a: 1} == {a: 1} // false
The easiest solution is to set your model to an item from the array manually, in your controller:
$scope.defaultObject = $scope.allObjects[0];
// (Or some other index that exists in the array)
Another option would be to bind the <select> to a specific value in the objects, instead of to the object itself:
<select
ng-model="defaultObject"
ng-options="obj.id as obj.description for obj in allObjects">
</select> <!-- ^ bound value, ^ display value -->
This will result in the selected obj's id being stored in $scope.defaultObject, and on page load, the obj with the id that's set in $scope.defaultObject will be selected.
The disadvantage here is that your model doesn't contain the complete selected object, only it's id property.
Your code is wrong , please try this code instead of your code (change obj to object in the ng-option )
<select ng-model="defaultObject" ng-options="object.description for object
in allObjects">
<option ng-if="!defaultObject" value="">Select Object</option>
</select>
You need add only one option for default select.

Angular blank option selected

I'm banging my head against the wall on this one.
I have an array of objects that will be used to populate a select drop down:
CardCount = [{"ClientId": "0010", "Description": "0010 (206 Members)"}, {"ClientId": "0051", "Description": "0051 (1 Member)"}, ........]
When I attempt to use ng-options, the value of the option is set to the index, not to the ClientId as desired. To get the value in each option to be the ClientId, I have to use a ng-repeat in the options. Here is my html:
<select ng-model="CurrentClient">
<option ng-repeat="item in CardCount" value="{{item.ClientId}}">{{item.Description}}</option>
</select>
Initially, all is well, the select and options are generated correctly, and the first option is correct. Now, when a certain button is clicked somewhere else on the page, it becomes necessary to recreate this select and options with a smaller array of similar objects. However, doing so creates a blank option with a value of "? string:0010 ?". This is the option that is selected. Again, I cannot use ng-options to correct this problem because doing so doesn't set the value attribute in the option tags correctly. So, I added this to the option tag:
<option ng-repeat="item in CardCount" value="{{item.ClientId}}" ng-selected="CurrentClient == item.ClientId">{{item.Description}}</option>
Now, that does mark the correct option as selected. However, the drop down still shows the blank option. Here's the rendered html:
<select ng-model="CurrentClient">
<option value="? string:0010 ?"></option>
<option value="0010" selected="selected">0010 (206 Members)</option>
</select>
As you can see, it sets the correct option to selected. However, it sets it to selected="selected", and not just selected. When I inspect element and change selected="selected" to selected (remove the equals and everything after it), the drop down then correctly displays the correctly selected option.
Again, initially the select and options work great. The problem seems to happen only after the array that the select is created with is changed. How can I get this select and options working correctly after I change the array, and not show that first blank option?
Thanks!
Changed you option element to set value by default.
<option ng-repeat="item in CardCount track by item.ClientId"
value="{{item.ClientId}}">{{item.Description}}</option>
Hope this could help you. Thanks.
ng-options is definitely the way to go:
<select ng-model="selected.ClientId" ng-options="it.ClientId as it.Description for it in clientList">
<option value="">-</option>
</select>

Categories

Resources