convert ng-repeat to ng-option error - javascript

I have this following html code for select tags.
<option ng-repeat="option in AllData" value="{{item.Id}}" ng-selected="data.Symbol==item.Id">{{item.Symbol}}</option>
I want to convert this to ng-options. can someone please shed some light on this.
the value of AllData is as follows. It is an array of objects.
0:Object
Id: 1
Symbol: "GR"
1:Object
Id: 2
Symbol: "DR"
I tried something like this but was not successful.
ng-options="item as item .Symbol for item in AllData track by item.Id">

Try this
<select ng-options="option as option.Symbol for option in AllData">
</select>

when using ngOptions, you have to also bind ng-model with the initial value of select.
mention that since you used track by item.Id, the default value should at least contains property Id and meets the one of the items Id property.
refer the below sample:
angular.module("app", [])
.controller("myCtrl", function($scope) {
$scope.AllData = [{
0: Object,
Id: 1,
Symbol: "GR"
}, {
1: Object,
Id: 2,
Symbol: "DR"
}];
//$scope.data = $scope.AllData[0];
$scope.data = {
0: Object,
Id: 1,
Symbol: "GR"
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<div ng-app="app" ng-controller="myCtrl">
<select ng-model="data" ng-options="item as item.Symbol for item in AllData track by item.Id"></select> {{selectedItem}}
</div>

Related

AngularJS How to initialize a select using ng-options with an object value

I would like to initialize a selection of a select field with ng-options.
Lets assume we've got the following items:
$scope.items = [{
id: 1,
label: 'aLabel',
subItem: { name: 'aSubItem' }
}, {
id: 2,
label: 'bLabel',
subItem: { name: 'bSubItem' }
}];
The following html:
<select ng-options="item as item.label for item in items track by item.id" ng-model="selected"></select>
But now instead of selecting the option by the following command:
$scope.selected = $scope.items[0];
I do not have the object, I have only the information of the id so I like to initialize the select by something like that:
$scope.selected = $scope.otherRandomObject.id
My thought was that using track by item.id is somehow creating the relation between object and the id.
If you want to have a pre-selected value, then you can use ng-selected
<select ng-options="item as item.label for item in items" ng-selected="$first"></select>
In this case, the first item in your item array would be selected
Hope i answered your question

How to convert id as order number in ng-options group by..?

This is my code
Fiddle Link
HTML
<div ng-app ng-controller="MyCtrl">
<input type="text" ng-model = "data.name" ><br>
<input type="text" ng-model = "data.value" ><br>
<input type="text" ng-model = "data.id" ><br>
<input type="button" value="ADD" ng-click = "addIntoArr(data.name,
data.value, data.id)" ng-disabled= !data.name>
<select ng-model="selectItem" ng-options="currOption as 'order' +
(data.indexOf(currOption)+1) group by currOption.name for currOption
in data"></select>
Data : {{selectItem.name}}
</div>
Here is my Js code
function MyCtrl($scope) {
$scope.data = [{
name: "AM",
value: "11",
id: "2"
}, {
name: "PM",
value: "12",
id: "3"
}, {
name: "PM",
value: "12",
id: "23"
}, {
name: "PM",
value: "12",
id: "33"
}, {
name: "AMT",
value: "13",
id: "33"
}, {
name: "WAT",
value: "14",
id: "21"
}];
$scope.addIntoArr = function (name, value, id) {
$scope.data.push({
name: name,
value: value,
id: id
});
}
$scope.selectItem = $scope.data[0];
}
Here is my array I was using label AM, PM, AWT, WAT. and each has a order (Please check fiddle link). I want each label order show with number like order1 in AM, order1, order2, order3 in PM and so on. and if I add new entry in array then recently added entry should be shown in drop down with order number and Related label shown in Data.
You cannot use $index inside ng-options. However you can get the current index by using indexOf on the data item passing the current option.
<select
ng-model="selectItem"
ng-options="currOption as 'order' + (data.indexOf(currOption)+1) group by currOption.name for currOption in data"></select>
Demo http://jsfiddle.net/6cf3h54x/3/
I'd suggest you include some external library like lodash and format your data into more convenient structure. Then, instead of banging your head against the wall with ng-options, you could use ng-repeat.
Consider the following:
// group existing data by object's name using lodash _.groupBy
$scope.groupedData = _.groupBy($scope.data, 'name');
This gives your following data structure for groupedData, so there's key and value where key is e.g. AM and value is array of objects all having same name.
Then you could have following template for your select.
<select ng-model="selectItem">
<optgroup ng-repeat="(key, items) in groupedData" label="{{ key }}">
<option ng-repeat="item in items"
value="{{ item }}"
ng-bind="'order' + (items.indexOf(item) + 1)"></option>
</optgroup>
</select>
Which gives you what you are after, no?
You can't use $index with ng-options. Make use of indexOf instead. You can do something like this:
<select ng-model="selectItem" ng-options="currOption.id as 'order'+data.indexOf(currOption) group by currOption.name for currOption in data"></select>

AngularJs - ng-model in a SELECT

JSfiddle
Problem:
I have a SELECT-element in my page, which is filled in with an ng-repeat. It also has a ng-model which has a default value.
When I change the value, the ng-model adapts, that's ok. But the dropdown-list shows an empty slot at launch, where it should have the item with the default value selected instead.
Code
<div ng-app ng-controller="myCtrl">
<select class="form-control" ng-change="unitChanged()" ng-model="data.unit">
<option ng-repeat="item in units" ng-value="item.id">{{item.label}}</option>
</select>
</div>
With JS:
function myCtrl ($scope) {
$scope.units = [
{'id': 10, 'label': 'test1'},
{'id': 27, 'label': 'test2'},
{'id': 39, 'label': 'test3'},
]
$scope.data = {
'id': 1,
'unit': 27
}
};
You can use the ng-selected directive on the option elements. It takes expression that if truthy will set the selected property.
In this case:
<option ng-selected="data.unit == item.id"
ng-repeat="item in units"
ng-value="item.id">{{item.label}}</option>
Demo
angular.module("app",[]).controller("myCtrl",function($scope) {
$scope.units = [
{'id': 10, 'label': 'test1'},
{'id': 27, 'label': 'test2'},
{'id': 39, 'label': 'test3'},
]
$scope.data = {
'id': 1,
'unit': 27
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="myCtrl">
<select class="form-control" ng-change="unitChanged()" ng-model="data.unit">
<option ng-selected="data.unit == item.id" ng-repeat="item in units" ng-value="item.id">{{item.label}}</option>
</select>
</div>
try the following code :
In your controller :
function myCtrl ($scope) {
$scope.units = [
{'id': 10, 'label': 'test1'},
{'id': 27, 'label': 'test2'},
{'id': 39, 'label': 'test3'},
];
$scope.data= $scope.units[0]; // Set by default the value "test1"
};
In your page :
<select ng-model="data" ng-options="opt as opt.label for opt in units ">
</select>
Working Fiddle
You dont need to define option tags, you can do this using the ngOptions directive: https://docs.angularjs.org/api/ng/directive/ngOptions
<select class="form-control" ng-change="unitChanged()" ng-model="data.unit" ng-options="unit.id as unit.label for unit in units"></select>
However, ngOptions provides some benefits such as reducing memory and increasing speed by not creating a new scope for each repeated instance. angular docs
Alternative solution is use ng-init directive. You can specify function that will be initialize your default data.
$scope.init = function(){
angular.forEach($scope.units, function(item){
if(item.id === $scope.data.unit){
$scope.data.unit = item;
}
});
}
See jsfiddle
You can also put the item with the default value selected out of the ng-repeat like follow :
<div ng-app="app" ng-controller="myCtrl">
<select class="form-control" ng-change="unitChanged()" ng-model="data.unit">
<option value="yourDefaultValue">Default one</option>
<option ng-selected="data.unit == item.id" ng-repeat="item in units" ng-value="item.id">{{item.label}}</option>
</select>
</div>
and don't forget the value atribute if you leave it blank you will have the same issue.
Select's default value should be one of its value in the list. In order to load the select with default value you can use ng-options. A scope variable need to be set in the controller and that variable is assigned as ng-model in HTML's select tag.
View this plunker for any references:
http://embed.plnkr.co/hQiYqaQXrtpxQ96gcZhq/preview

How to set a value in a drop-down list

I'm facing a problem with setting a value in a drop-down list. The following is the code for my drop-down:
<select class="price-dropdown" ng-model="createCampaign.currency" ng-options="obj.id as obj.symbol for obj in config.currencies"></select>
Here is the object:
[Object, Object]
0: Object
id: "GBP"
name: "GBP"
symbol: "GBP"
__proto__: Object
1: Object
id: "dollar"
name: "Dollar"
symbol: "$"
__proto__: Object
length: 2
__proto__: Array[0]
It's setting 0, 1, 2 as the value instead of id.
I've looked at other questions but haven't been able to make any of the solutions work.
What am I doing wrong?
Its setting the object Ordinal it seems. can you debug and edit in {obj.id} inside ng-options="obj.id as obj.symbol for obj in config.currencies"> to get it right.
I have created a Fiddle for your problem. Over here it is having id as value.
Code Snippet:
<div ng-app="myapp">
<fieldset ng-controller="FirstCtrl">
<select
ng-options="p.name as p.name for p in symbol"
ng-model="selectedPerson"></select>
{{ selectedPerson }}
</fieldset>
</div>
I Think a dropdown list must have a unique identifier among the list.. to identify the correct selection..look in this sample fiddle link it may help you..
<select class="span2" name="SelectedState" ng-model="selectedState" ng-options="state.id as state.name for state in states">
</select>
Controller code:
$scope.states = [{
id: 1, name: 'France'
}, {
id: 2, name: 'UK'
}, {
id: 3, name: 'Germany'
}];
$scope.selectedState = $scope.states[2];
This code will help to solve your problem please check it once
$scope.colors = [
{name:'black', shade:'dark'},
{name:'white', shade:'light'},
{name:'red', shade:'dark'},
{name:'blue', shade:'dark'},
{name:'yellow', shade:'light'}
];
<select name="value">
<option ng-repeat="color in colors" value="{{color.name}}">
{{color.name}}
</option>
</select>
It's not bug, it's a feature. angularjs handles ngOptions and ngModel internally, this way it allows you to use any type of object as value in option rather than only strings. This link should help you :) Watch this tutorial this is shortcut for your problem.

ngOptions two level object display

I have this structure:
model = [
{
name: 'name1',
items: [
{
name: 'subobj1'
},
{
name: 'subobj2'
}]
},
{
name: 'name2',
items: [
{
name: 'subobj1'
},
{
name: 'subobj2'
}]
},
....
]
Question is: How do I write ngOptions attrbiute to output this object like this?:
<select>
<optgroup label="name1">
<label>subobj1</label>
<label>subobj2></label>
</optgroup>
....
</group>
Also - ngRepeat is not an option. I have to do this ngOptions alone for plugin being used to work.
ngOptions doesn't support multi-dimensional arrays. You must flatten your array first.
Read more in this answer.
I used a filter:
app.filter('flatten' , function(){
return function(array){
return array.reduce(function(flatten, group){
group.items.forEach(function(item){
flatten.push({ group: group.name , name: item.name})
})
return flatten;
},[]);
}
})
And the markup:
<select ng-model="select"
ng-options="item.name
group by item.group
for item in model | flatten"></select>
<select>
<option ng-repeat-start="m in model" ng-bind="m.name"></option>
<option ng-repeat-end ng-repeat="item in m.items" ng-bind="item.name"></option>
</select>
You might add something like style="font-weight: bold;" on the first option (which is the group label, by the way) and something like style="padding-left: 15px;" on the second option line, which is another repeat for all the first option line.
So basically by doing this you just add 2 levels (without optgroup tag, mind you) to your select.

Categories

Resources