Different value of selected option in AngularJS select ng-repeat - javascript

I have a drop-down list that I'm trying to create where the value displayed in the drop-down is different to the options available - I'm using angularjs for this purpose. For example, if I had the following text, I'd want to display the full value when the user opens the drop-down:
A - A is for Apple
B - B is for Banana
But on the page I only want to display A or B, not the full description, as in this picture:
This is the closest I've got so far (where my list of objects are just objects with a Value and Description property) but I can't seem to show the short value in the dropdown, although I know I've seen this kind of set up online on various sites.
<select>
<option ng-repeat="item in myObject.Options" value="{{item.Value}}" title="{{item.Description}}">{{item.Description}}</option>
</select>
Where the object would look something like
var myObject = { "Options" : [
{ "Value":"A" , "Description":"A is for Apple" },
{ "Value":"B" , "Description":"B is for Banana" },
{ "Value":"C" , "Description":"C is for Cherry" } ]};

This is not possible, because you have uses the HTML select component that is not able to distinguish between the displayed text in the dropdown and the shown value.
However you could build an own directive for implementing a similar behaviour, for example with a bootstrap dropdown menu or md-select.
For example :
<md-select md-selected-text="selectedItem.Value" ng-model="selectedItem">
<md-option ng-repeat="item in items" ng-value="item">
{{ item.Description }}
</md-option>
</md-select>
Hope this will help you !

If you only want to display the Value part, you can use this:
<select>
<option ng-repeat="item in myObject.Options" value="{{item.Value}}" title="{{item.Description}}">
{{item.Value}} - {{item.Description}}
</option>
</select>
Example:
var app = angular.module('app', []);
app.controller('TestController', function($scope) {
$scope.myObject = {
"Options": [{
"Value": "A",
"Description": "A is for Apple"
}, {
"Value": "B",
"Description": "B is for Banana"
}, {
"Value": "C",
"Description": "C is for Cherry"
}]
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller='TestController'>
<select>
<option ng-repeat="item in myObject.Options" value="{{item.Value}}" title="{{item.Description}}">{{item.Value}} - {{item.Description}} </option>
</select>
</div>

Related

set object as selected in ngoptions

Im using ngOptions for select directive like
<select class="form-control" ng-model="users.jobTitle" name="jobTitle" data-ng-options="job as job.value for job in ds.jobTitle" required>
im setting default in controller like
$scope.users.jobTitle = $scope.ds.jobTitle[0];
ds is a json with array jobtitle:
"jobTitle":[
{"id":1,"value":"Service1"},
{"id":2,"value":"Service2"},
{"id":3,"value":"Service3"}
],
now i'm saving and getting result(console) like
jobTitle:Object
$$hashKey:"object:173"
id:1
value:"Service1"
now when i'm editing, feeding the service call data like
$scope.useredit.jobTitle = data.jobTitle;
for
<select class="form-control input-sm" ng-model="useredit.jobTitle" name="jobTitle" data-ng-options="job as job.value for job in ds.jobTitle" required>
</select>
its not setting the object as selected , instead sets the null value in first option..
what i have to do ?
By default, ngModel watches the model by reference, not value. This is
important to know when binding the select to a model that is an object
or a collection.
One issue occurs if you want to preselect an option. For example, if
you set the model to an object that is equal to an object in your
collection, ngOptions won't be able to set the selection, because the
objects are not identical. So by default, you should always reference
the item in your collection for preselections, e.g.: $scope.selected =
$scope.collection[3].
Another solution is to use a track by clause, because then ngOptions
will track the identity of the item not by reference, but by the
result of the track by expression. For example, if your collection
items have an id property, you would track by item.id.
~ Taken from the official docs regarding ngOptions
I tested it out by using ng-options in separate select boxes and it works.
See demo below.
angular.module('app', [])
.controller('TestController', ['$scope',
function($scope) {
$scope.ds = {};
$scope.ds.jobTitle = [{
"id": 1,
"value": "Service1"
}, {
"id": 2,
"value": "Service2"
}, {
"id": 3,
"value": "Service3"
}];
var data = {
jobTitle: {
"id": 1,
"value": "Service1"
}
};
$scope.useredit = {
jobTitle: data.jobTitle
};
}
]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app">
<div ng-controller="TestController">
<br />Without using track by in ngOptions
<select class="form-control" ng-model="useredit.jobTitle" name="jobTitle" data-ng-options="job as job.value for job in ds.jobTitle" required>
</select>
<br />
<br />
<br />Using track by in ngOptions
<select class="form-control" ng-model="useredit.jobTitle" name="jobTitle" data-ng-options="job as job.value for job in ds.jobTitle track by job.id" required>
</select>
</div>
</div>

angularjs - ng-options with nested json based on previous select option

i'm kind of new in Angular, and I facing a problem, I didn't find an answer that could help me, if some one could, thank you. :)
I have a json like this:
"items": [
{
"post_type": "release",
"label": "Releases"
},
{
"post_type": "news",
"label": "Notícias",
"options": [
{
"id": 1,
"name": "Galeria de Fotos"
},
{
"id": 2,
"name": "Agência de Notícias"
},
{
"id": 3,
"name": "Rádio"
},
{
"id": 4,
"name": "TV"
}
]
},....
And I m getting data like:
var _preparingPostTypes = function ($scope) {
$scope.post_types = [];
PostTypeService.getPostTypes().then(function (data) {
$scope.post_types = data.data;
});
};
What I want to do is create 2 selects, 1st - with the post_type ('release', 'news') and a second one with the 'options' array from a post_type, that is only visible when select an option with the 'options' in the array like 'news'. I did something like this, where I can get the post_type like a charm, but I don't know how to proceed:
<div class=form-group>
<label>Pesquisar em:</label>
<select title="Pesquisar em:" class="form-control select-post-type"
ng-model="widget.post_type"
ng-options="item.post_type as item.label for item in post_types.items"></select>
</div>
EDIT:
In my request I need to pass the post_type string to server, from the first select, so the ng-options is:
ng-options="item.post_type as item.label for item in post_types.items
Not:
ng-options="item as item.label for item in post_types.items
Thanks everybody!
You can add an ng-change to the first select that calls a function that loads the options
<select title="Pesquisar em:" class="form-control select-post-type"
ng-model="widget.post_type"
ng-options="item as item.label for item in post_types.items" ng-change="typeChanged()"></select>
And the function would load inside $scope.options the selected type options. Then you iterate over $scope.options in the second select
UPDATE:
I haven't tested the code, but it may guide you
Select:
<select title="Options:" class="form-control select-post-type"
ng-model="widget.option"
ng-options="option as option.name for option in options">
Change function (triggered when the value of the first select changes, so it will have the responsibility of loading the options of the post_type selected):
$scope.typeChanged = function() {
for (var i = 0; i < $scope.post_types.items.length; ++i) {
if ($scope.post_types.items[i].label == $scope.widget.post_type) $scope.options = $scope.post_types.items[i].options || [];
}
}
widget.post_type should contain the selected item. So the other select can have options like option as option.name in widget.post_type.options. Note that you should probably have an options collection on each item if you want this to work.
You can do this very easily using following technique. You just need to use the ng-model from the first select. See my approach:
<label>Pesquisar em:</label>
<select title="Pesquisar em:" class="form-control select-post-type"
ng-model="firstSelect"
ng-options="item as item.label for item in post_types.items"></select>
<select title="Second one" class="form-control select-post-type"
ng-model="secondSelect" ng-show="firstSelect.options"
ng-options="option as option.name for option in firstSelect.options"></select>

How can I show items specific to a selected dropdown option?

I have a dropdown list of games, and depending on which game you select, it should show a list of things I need to do for that game. My problem is getting the list to show the steps for only the currently selected game. Can this be done with ng-model, will I need to use functions, or is there an even simpler way to do this?
Also, is there any information I've included in my sample that would become redundant after utilizing provided suggestions?
HTML
<select>
<option ng-repeat="game in things.toBeat">{{ game.title }}</option>
</select>
<ul>
<li ng-repeat="step in things.toDo">{{ step.todo }}</li>
</ul>
JS
var games = [
{ "id" : "0", "title" : "Super Mario Bros." },
{ "id" : "1", "title" : "Pac-man" }
];
var todos = [
{ "gameID" : "0", "todo" : "Collect coins" },
{ "gameID" : "0", "todo" : "Rescue princess" },
{ "gameID" : "1", "todo" : "Eat dots" },
{ "gameID" : "1", "todo" : "Eat fruit" }
];
$scope.things = { "toBeat" : games, "toDo" : todos };
First you need to give the games select an ng-model so the second 'todo' ng-repeat can be aware of what game is selected:
<select ng-model="selectedGame">
Then you need to give the options of the selectedGame select the id value of the games so "selectedGame" will have the value of that id.
<option ng-repeat="game in things.toBeat" value="{{game.id}}">{{ game.title }}</option>
finally, you tell to the 'todo' ng-repeat to apply the filter according to the selectedGame value, matching it with the gameID field of each 'step'.
<li ng-repeat="step in things.toDo | filter: {gameID:selectedGame}">{{ step.todo }}</li>
The final code should look like this:
<select ng-model="selectedGame">
<option ng-repeat="game in things.toBeat" value="{{game.id}}">{{ game.title }}</option>
</select>
<ul>
<li ng-repeat="step in things.toDo | filter: {gameID:selectedGame}">{{ step.todo }}</li>
</ul>
I hope it helps
Edit:
If you want to set the default selectedGame you can use ng-init:
<select ng-model="selectedGame" ng-init="selectedGame='0'">

Nested ng-option inside angular ng-repeat

Im currently trying to nest a <select> inside a div with a ng-repeat
something like this:
<li ng-repeat="item in items >
<div class="row">
<div class="col-xs-7">
<span ng-bind="item.Name"></span>
</div>
<div class="col-xs-4 modal-body--ul--li__dropdown_container">
<select ng-model="typemodel" >
<option ng-repeat="usertype in item.userGroups"></option>
</select>
</div>
<div class="col-xs-1">
<a ng-click="add(item)"></a>
</div>
</div>
</li>
In the controller im adding the item to a new list with selected items. I also want to add the value from the dropdown as a new value to the list in the controller.
$scope.add = function (item) {
//New value with the value from the dropdown
item.recipientType = typemodel;
$scope.selected.push(item);
};
The list :
$scope.items = [
{
"Name":"Name1",
"userGroups":[
{ "type": "gruop1" },
{ "type": "gruop2" },
{ "type": "group3" }
]
},
{
"Name":"Name2",
"userGroups":[
{ "type": "gruop1" },
{ "type": "gruop2" },
{ "type": "group3" }
]
}
]
In short i need the selected value from the dropdown when i hit the "add", the value of the current typemodel.
This is how it looks now, but it dont work. I know i have to get the correct model and maybe track the items list by $index, but after searching the web the whole day for a solution, im still stuck!
All help is appreciated.
-Thanks!
ps. please comment if something is missing from the question, or something more is needed to solve this.
First, change your dropdown list to
<select ng-options="usertype in item.userGroups" ng-model="item.recipientType">
Then when you trigger the add function, item's property recipientType is already set.
$scope.add = function (item) {
console.log(item.recipientType);
$scope.selected.push(item);
};

angularjs: cascade dropdown

I'm trying to achieve a cascade dropdown in Angular. I thought it would just work naturally thanks to binding. See below:
<select name="client" ng-model="selectedRequest.client" ng-options="c.name for c in clients track by c.id" required></select>
<select id="department" ng-model="selectedRequest.department" ng-options="d.defaultLabel for d in selectedRequest.client.departments track by d.id"></select>
When the view is loaded, it works, I can see the departments matching those bound to the client. However, whenever the selectedRequest.client changes, the source for the department dropdown should change too, but instead it becomes empty.
EDIT
I've changed the child dropdown to :
<select id="department" ng-model="selectedRequest.department" ng-options="d.defaultLabel for d in departments track by d.id | filter:{clientId: selectedRequest.client.id}"></select>
but this time it loads all the departments in the dropdown, ignoring the filter.
** EDIT 2 **
Changing to :
<select name="client" ng-model="requestService.selectedRequest.client" ng-options="c as c.name for c in clients track by c.id" required></select>
<select id="department" ng-model="requestService.selectedRequest.department" ng-options="d.defaultLabel for d in departments | filter:{clientId: requestService.selectedRequest.client.id}"></select>
Now the source changes correctly when a client is selected. However the initial selection, i.e setting the right department at startup, does not work. That's because I've removed the 'track by id' bit.
the correct way was
<select id="department" ng-model="selectedRequest.department" ng-options="d.defaultLabel for d in departments | filter:{clientId: selectedRequest.client.id} track by d.id "></select>
it's just that I hadn't put the filter at the right place... silly mistake.
It could be that your selectedRequest.client does not refer to the same object in clients array. Try this:
JS:
function testController($scope) {
$scope.clients = [
{ id: 1, name: "client1", departments: [{ id: 1, defaultLabel: 'department1' }, { id: 2, defaultLabel: 'department2'}] },
{ id: 2, name: "client2", departments: [{ id: 3, defaultLabel: 'department3' }, { id: 4, defaultLabel: 'department4'}] }
];
$scope.selectedRequest = {};
$scope.selectedRequest.client = $scope.clients[0];//Assign by object reference.
}
HTML:
<div ng-controller="testController">
<select name="client" ng-model="selectedRequest.client" ng-options="c.name for c in clients" required></select>
<select id="department" ng-model="selectedRequest.department" ng-options="d.defaultLabel for d in selectedRequest.client.departments"></select>
</div>
DEMO
I removed track by to use the default (track by object reference) and ensure that selectedRequest.client refers to objects inside clients

Categories

Resources