I am having an issue with using ng-repeat and select.
Here is my code, first of all
<select>
<optgoup ng-repeat="(key, value) in Widget.ids" label="{{ value.label }}">
<option ng-repeat="id in Widget.ids[key].ids">{{ id }}</option>
</optgroup>
</select>
My data looks something like this
[
{ label: "My Label", ids: [ "one id", "another id" ] },
{ label: "My Other Label", ids: [ "one id", "another id" ] }
]
However, this returns a completely empty <select>.
What's frustrating, is if I change my HTML to look like this:
<div ng-repeat="(key, value) in Widget.ids">{{ value.label }}
<div ng-repeat="id in Widget.ids[key].ids">{{ id }}</div>
</div>
Then it lists..
My label
one id
another id
My Other Label
one id
another id
In fact if I remove the <select> tag and leave the optgroup etc tags then it will actually generate the correct DOM elements.
Also, I can't use simply use ng-model as I will be reserving that for a different model. (Widget.my.path.widget_id)
What's going on here then?
This plunker should work:
<select>
<optgroup ng-repeat="(key,value) in data" label="{{value.label}}">
<option ng-repeat="id in value.ids">{{id}}</option>
</optgroup>
</select>
Related
I have the following select input in my html which is populated using ng-options. I want to show the selected NAME down below in whereas I want to send the selected ID back to the controller. I get the required id from ng-model="user.category". How can I show the selected name? I also show the names in options.
<select ng-model="user.category" ng-options="category.id as category.name for category in categories" class="form-control" class="select" required>
<option value="{{category.name}}">Select a Category</option>
</select>
<p>Available On : {{user.retailerBranchId}}</p>
<select ng-model="user.category" ng-options="category for category in categories" class="form-control" class="select" required>
<option value="{{category.name}}">Select a Category</option>
</select>
<p>Available On : {{user.category.id}}</p>
If you make retailerBranchId a method you can do it with something like lodash' _.find() (or even native find). You have user.category updating according to your selection, which you say has the id in it, which you can use:
function retailerBranchId() {
return _.get(_.find(this.categories, { id: user.category }), 'name', '');
}
This also fails gracefully; if it can't find any name, or any item that matches the id, it'll return an empty string.
Edit: You would call it in a similar fashion like so:
<p>Available on: {{ user.retailerBranchId() }}</p>
Although really, it's better to use it like this:
<p data-ng-bind="'Available on: ' + user.retailerBranchId()"></p>
Can you try like a below method,
Controller to get selected Category Name:
$scope.getSelectedCategoryDetail=function(selectedCat){
angular.forEach($scope.categories, function(cat){
if(selectedCat===cat.id){
$scope.user.name=cat.name;
}
});
};
Template to have ng-change event:
<select ng-model="user.category" ng-options="category.id as category.name for category in categories" class="form-control" class="select" required>
<option value="{{category.name}}" ng-change="getSelectedCategoryDetail(user.category)">Select a Category</option>
</select>
<p>Category Id : {{user.category}}</p>
<p>Category Name : {{user.name}}</p>
I use a filter at my ng-repeat and it works fine when I navigate to page (everything is shown - nothing is filtered) and when I filter also all is fine.
I only have problems when I will "deselect" the filter in that way that I select < option>< /option> in the select input. Than nothing is shown instead of all.
Does anyone know what I can do that when I select < option>< /option> that all is shown like at the beginning - when I navigate to the page?
somethingToIterate | filter: {institutionUserRole: {value: roleFilter}}
My select looks like this:
<select class="form-control roleSelect" ng-model="roleFilter" ng-options="role as role | translate for role in vm.roles">
<option></option>
</select>
If you are using an object in ng-model, I think you will need to add the default option to the list you loop thru in the ng-repeat.
Like this:
$scope.options = [
//add the default value in the options list.
{'value':'', 'label':''},
{'value':'1', 'label':'Option 1'},
{'value':'2', 'label':'Option 2'},
{'value':'3', 'label':'Option 3'},
{'value':'4', 'label':'Option 4'},
{'value':'5', 'label':'Option 5'},
{'value':'6', 'label':'Option 6'}
];
<div class="jumbotron">
<select ng-model="option" ng-options="item as item.label for item in options track by item.value">
</select>
<ul>
<li ng-repeat="item in data | filter: {name: option.value}">{{item.name}}
</li>
</ul>
</div>
or you can try it like this,
<select ng-model="selected.option">
<option value='' >select</option>
<option ng-repeat="option in options" value="option.value">{{option.label}}
</option>
</select>
Here is a working example. http://codepen.io/mkl/full/qZjwJG/
For example I would like to do something like this:
<select ng-model="persons">
<option value="person1">Anna Smith</option>
<option value="person2">Karl Pettersson</option>
<option value="person3">Ylvis Russo</option>
</select>
<p ng-view="persons"><p>
And having the view display each name when selected in the dropdown rather than it's value. Is it possible?
I tried watching the model and assigning a new model the text value with jQuery. However it ended up being complicated so if that's the best way to do it, I small example would be awesome!
You just need to define your persons object and then you can do whatever you want with it. There are many ways to do it... Here's an example:
HTML
<select ng-model="persons"
ng-options="p as p.label for p in persons">
</select>
<p ng-repeat="p in persons">
{{p.value}}: {{p.label}}
</p>
JS
$scope.persons = [
{ value: 'person1', label: 'Anna Smith' },
{ value: 'person2', label: 'Karl Pettersson' },
{ value: 'person3', label: 'Ylvis Russo' }
];
Here is a jsfiddle: http://jsfiddle.net/bKHh8/
UPDATE
Here it is with option tags which don't use angular indices for values (this is exactly what answers your question): http://jsfiddle.net/bKHh8/1/
<select>
<option ng-repeat="p in persons" value="{{p.value}}">{{p.name}}</option>
</select>
My question is quiet similar to set-dropdown-selected-value-with-backbone, with minor difference that I don't want to manipulate the DOM thru jQuery.
For this what I have done is:-
Assuming my DropDown is of type UserType
var userType = backbone.Model.extend({
idAttribute: "TypeId",
defaults: {
TypeId: null,
TypeName: null,
Selected: false
}
});
Here, I have created an extra attribute as Selected, which I am using as below in my Handlebar template.
<select id="userType" name="UserTypeId" class="input-medium form-control">
{{#each MasterUserType}}
<option id="{{TypeId}}" selected="{{Selected}}">{{TypeName}}</option>
{{/each}}
</select>
Okay, now when I get my Data thru api- say(example)
[
{
"TypeId":1,
"TypeName":"Admin"
},
{
"TypeId":2,
"TypeName":"User"
},
{
"TypeId":3,
"TypeName":"Super Admin"
}
]
Now, I manipulate my variable MasterUserType to become something like below:-
[
{
"TypeId":1,
"TypeName":"Admin",
"Selected":""
},
{
"TypeId":2,
"TypeName":"User",
"Selected":"selected"
},
{
"TypeId":3,
"TypeName":"Super Admin",
"Selected":""
}
]
So my HTML which renders is :-
<div class="controls">
<select id="userType" name="TypeId" class="input-medium form-control">
<option id="" selected="">Admin</option>
<option id="" selected="selected">User</option>
<option id="" selected="">Super Admin</option>
</select>
</div>
But still it reflects the first Item....
Can anyone tell me what is wrong? Or any other alternative?
Lastly, can we achieve this requirement from some other better way?
I have tried replacing "selected with true" but it doesn't work.
Try updating your template as below:
<select id="userType" name="UserTypeId" class="input-medium form-control">
{{#each MasterUserType}}
{{#if Selected}}
<option id="{{TypeId}}" selected="{{Selected}}">{{TypeName}}</option>
{{else}}
<option id="{{TypeId}}">{{TypeName}}</option>
{{/if}}
{{/each}}
</select>
I need to bind complex objects via a select box.
I'm aware of ng-options, but I cannot use template expression in ng-options. I would need to add field with the displaytext to every object in my controller like in this fiddle. That would mean I would need to change logic/code for the presentation. This is a bad seperation of concerns.
Is there any way to bind complex objects with a select box not using ng-options? I need to write the displaytext declarative in the template like there:
<select name="myObject" ng-model="myObject.sub">
<option ng-selected="!myObject.sub.id"></option>
<option value="" translate="myObject.sub.self" ng-selected="myObject.sub.id == -1">
<option ng-repeat="option in subselect.data" value="{{option}}" ng-selected="option.id == myObject.sub.id">
{{option.id}} {{option.shortName}} {{ option.comment }}
</option>
</select>
currently this is binding the string [object Object], because of the interpolation in the value attribute.
Using a small helper function with ng-change you can capture the index of the selected item to obtain the full object.
HTML
<label ng-controller="CompanyController" for="ci-company_sid">
Company:
<select ng-model="selectedCompanyIndex" ng-change="update(companysData.companys)">
<option ng-repeat="c in companysData.companys" value="{{$index}}" ng-selected="c.company.sid == selectedCompany.company.sid">{{c.company.company_name}} - {{c.company.link}}</option>
</select>
<hr>
{{selectedCompany.company.link}}
</label>
Controller:
function CompanyController($scope, $http) {
$scope.companysData = {
"companys": [{
"company": {
"link": "\/company\/8256606980000143017",
"sid": "8256606980000143017",
"company_name": "Company 29"
}},
{
"company": {
"link": "\/company\/8256603960000178016",
"sid": "8256603960000178016",
"company_name": "Company 1"
}}]
}
$scope.update = function(dataSet){
$scope.selectedCompany = dataSet[$scope.selectedCompanyIndex];
}
$scope.selectedCompany = $scope.companysData.companys[0];
}
http://jsfiddle.net/XzfVZ/3/