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.
Related
I am working on a web page of an application on which there are two select elements (among other). Initially, both select elements will have values. Note specially that second select element will have full set of values to begin with. The requirement is for the content of second select to reduce to a subset based on what user has select in the first select element. Since I need to retain the initial content of the second select, I first clone it in document.ready().
Let us say following is the initial second select element
<select id="sid">
<option value="0" selected="">Unknown</option>
<option value="1">Unit</option>
<option value="2">House</option>
<option value="3">Apartment</option>
</select>
How could I create a clone and remove 'Unknown' and 'Apartment' from the object and append it back to the select having run empty() to clear the options first.
So far I have come with following. Looking for some information what could go in the function passed to filter (see comment //need logic to filter option with value Unknown and Apartment)
var toRetain = $('#sid').clone();
$('#sid').empty();
var secondClone = toRetain .clone()
$('option', secondClone).each(function(i){console.log(i));}); // able to print all options
$('option', secondClone).filter(function(i){
//need logic to filter option with value Unknown and Apartment
}).remove()
$('#sid').append(b.html())
Assuming the options you want to remove are always in the same positions you could use :eq() to select and remove them, no need to empty() the entire set:
var $toRetain = $('#sid').clone().removeAttr('id').appendTo('body');
$toRetain.find('option:eq(0), option:eq(3)').remove();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<select id="sid">
<option value="0" selected="">Unknown</option>
<option value="1">Unit</option>
<option value="2">House</option>
<option value="3">Apartment</option>
</select>
Alternatively you could use :first and :last, or even add a specific class on them to select by. In any case the pattern would be the same; identify the option to be removed and call remove() on them.
If you need to select them by their text content then you can do that using filter():
let toRemove = ['Unknown', 'Apartment'];
var $toRetain = $('#sid').clone().removeAttr('id').appendTo('body');
$toRetain.find('option').filter((i, el) => toRemove.indexOf(el.textContent.trim()) != -1).remove();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<select id="sid">
<option value="0" selected="">Unknown</option>
<option value="1">Unit</option>
<option value="2">House</option>
<option value="3">Apartment</option>
</select>
Also note that I used removeAttr() to remove the id from the cloned content, as id attributes must always be unique within the DOM.
Following code too achieves the desired
var toRetain = $('#sid').clone();
$('#sid').empty();
var secondClone = toRetain .clone()
$('option', secondClone).each(function(i){console.log(i));}); // able to print all options
$('option', secondClone).filter(function(i){
return ['Unknown', 'Apartment'].indexOf($(this).html()) != -1;
}).remove()
$('#sid').append(b.html())
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>
I'm using JavaScript (Google Apps Script to be precise) and I'm having some trouble with objects.
I have a var, formData, which is full of data passed back from an HTML form. I can happily access the values like this; exhibitions is the name of a select element;
formData.exhibitions.value
But I want to change the value from "*" to "ALL". I have tried all the following;
formData.exhibitions.value = "ALL"
formData["exhibitions"] = "ALL"
formData.element["exhibitons"] = "ALL"
and a few other versions of the above but nothing alters the value.
edit- cut down code, HTML form
<form>
Exhibition search <select id="exhibitionList" name ="exhibition">
<option value="*">All</option>
<option value="shoes">shoes</option>
</select>
<input type = "button" value ="Item Search" onclick="printSearch(this.form)"/>
</form>
and the function is
printSearch(formData){
if(formData.exhibition.value != "*"){
whereData.push(exhibition+"='"+formData.exhibition.value+"'");
}else{formData.set('exhibition','ALL');}
}
everything works fine I just can't seem to change the value past the ELSE statement.
What you're trying to do can't work. The value of a <select> has to be the value of one of its <option> elements. This is because the value is actually stored in the select's selectedIndex property. When you assign to formData.exhibition.value, it searches the options for one whose value matches this, and then sets formData.exhibition.selectedIndex to its position. If there's no match, it fails and doesn't change the value.
Since you have no <option value="ALL"> element, trying to set the value to that must fail.
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.
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>