I know there's been a lot of questions for this but I am having the most annoying time figuring out how AngularJS handles select option values and which one is selected. I have a simple item which I pass onto a modal window. This item contains template_id. I also have templates which have a name and an id and I wish to create a simple select where the option which has the value of the item's template_id gets selected:
<select name="templateId">
<option value="8000">name</option>
<option value="8001" selected>name 2</option>
</select>
Now with AngularJS I do this:
<select name="templateId"
ng-model="domain.templateId"
ng-options="t.template_id as t.name for t
in templates track by t.template_id">
<option value="">Choose template</option>
</select>
In the controller I set the 'selected' value with:
Data.get('templates').then(function(result) {
$scope.templates = result;
});
$scope.domain = {
template_id: item.template_id,
templateId: { template_id: item.template_id }
};
I have actually gotten to a point where I can send the template_id to the REST API and the response there reads
template_id: 8000
However, there is some minor annoying behaviour in the select element. I get the item I want selected, but when I attempt to select another option it switches the selected to the pre-set 'Choose template' option but the value or rather the 'real selected item' is still the original "selected" value I set in the controller. I can see it in the REST API response. This is not however what I selected. After this initial bug it continues to work as it's supposed to but how can I get rid of this?
Here a example to solve your issue.
angular.module('app.select', [])
.controller('SelecetCtrl', function($scope) {
$scope.templates = [{
template_id: 1,
name: 'tst1'
}, {
template_id: 2,
name: 'tst2'
}, {
template_id: 3,
name: 'tst3'
}];
$scope.selected = {
template: {
template_id: 2
}
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app='app.select'>
<div ng-controller='SelecetCtrl'>
<select name="templateId" ng-model="selected.template"
ng-options="t as t.name for t
in templates track by t.template_id">
<option value="">Choose template</option>
</select>
</div>
</div>
Related
I have a JSON saved that has plenty information:
I am able to fill a select menu with all the names of each element inside the JSON this way:
<select ng-model="car.marca" ng-options="item.brakeId as item.name for item in fillBreaks" class="form-control cforms" required>
<option value="" disabled selected>Sleccionar Marca</option>
</select>
Getting this as result: a select menu filled with the names:
I am able to get the BreakId of the selected element, in this case is saved in 'car.marca' using ng-model.
ng-model="car.marca"
My question is, Based on the selected element lets say 'BrakeId: 9' how can I display the rest of the information of that selected id?
I want to display the price, description, stock, and so on.
You can get the selected object by doing a find on fillBreaks (should be fillBrakes?) for an object with a matching brakeId using ng-change like below. This will allow you to display the additional brake information while keeping car.marca true to holding just a brakeID.
var exampleApp = angular.module('exampleApp', []);
exampleApp.controller('ExampleController', ['$scope', function($scope) {
$scope.car = null;
$scope.fillBreaks = [
{ brakeId: 0, name: 'Brake A', description: 'Good brakes', price: 100, stock: 1 },
{ brakeId: 1, name: 'Brake B', description: 'Great brakes', price: 200, stock: 1 },
{ brakeId: 2, name: 'Brake C', description: 'The best brakes', price: 300, stock: 1 }
];
$scope.brakeInfo = null;
$scope.getBrakeInfo = function(brakeId) {
$scope.brakeInfo = $scope.fillBreaks.find(function(item){return item.brakeId == brakeId});
}
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="exampleApp" ng-controller="ExampleController">
<select ng-model="car.marca" ng-options="item.brakeId as item.name for item in fillBreaks" ng-change="getBrakeInfo(car.marca)" class="form-control cforms" required>
<option value="" disabled selected>Sleccionar Marca</option>
</select>
<p>{{ brakeInfo }}</p>
</div>
You can change your ng-options to grab the entire selected object, instead of just it's ID.
ng-options="item as item.name for item in ctrl.fillBreaks"
See this JSFiddle for example
P.S. A little trick to remove the Placeholder option from the dropdown is to add style="display: none;" to it, so that it can't be intentionally selected; also illustrated in the JSfiddle
Am trying to populate combo box in AngularJS. Below is the controller code.
var app = angular.module('app');
app.controller('roadmap', function($rootScope, $scope, $http, $q, leFactory) {
$rootScope.activityInfoList=[];
$rootScope.brand_strategy_list=[];
$rootScope.brand_strategy_csf=[];
$rootScope.brand_strategy_initiatives=[];
leFactory.getActivityPopupInfo().then(function(activityList) {
$rootScope.activityInfoList=angular.copy(activityList);
console.log($rootScope.activityInfoList);
$rootScope.brand_strategy_list=$rootScope.activityInfoList.listBrandStrategy;
console.log($rootScope.brand_strategy_list);
console.log('editActivityPopup service accepted-> ');
}, function(error) {
console.log('editActivityPopup service rejected-> ', error);
});
$rootScope.items = [{
id: 1,
label: 'aLabel',
subItem: { name: 'aSubItem' }
}, {
id: 2,
label: 'bLabel',
subItem: { name: 'bSubItem' }
}];
});
In the HTML part, am trying to populate $rootScope.brand_strategy_list as below.
<select ng-model="activityInfoList.brandStrategy" class="selectpicker" data-style="btn-inverse" style="display: none;" ng-options="item.strategyName as item.strategyName for item in brand_strategy_list">
<option> Select </option>
</select>
$rootScope.brand_strategy_list is not getting populated. But when I tried populating $rootScope.items, it is getting populated. I made console.log($rootScope.brand_strategy_list) and its showing the complete list.
Dont know what mistake am doing? Pls help me solve this issue. Thanks in Advance.
Try this
ng-options="item.strategyName as item.strategyName for item in $root.brand_strategy_list
Remove style="display: none;" from html and change $rootScope to $scope
<select ng-model="activityInfoList.brandStrategy" class="selectpicker" data-style="btn-inverse" ng-options="item.strategyName as item.strategyName for item in brand_strategy_list">
<option> Select </option>
</select>
I wonder if it is possible to have a <select> which <option> elements are generated on the server filtered by angularjs with some conditions.
Let's assume the following scenario. We have two <select> elements.
<select id="parent">
<option>Parent option 1</option>
<option>Parent option 2</option>
...
<option>Parent option 2000</option>
</select>
<select id="child">
<option>Parent option 1 Child 1</option>
<option>Parent option 1 Child 2</option>
...
<option>Parent option 1 Child 1000</option>
<option>Parent option 2 Child 1</option>
<option>Parent option 2 Child 2</option>
...
<option>Parent option 2 Child 1000</option>
......
<option>Parent option 2000 Child 1</option>
<option>Parent option 2000 Child 2</option>
...
<option>Parent option 2000 Child 1000</option>
</select>
So when parent option is selected then filter the child <select>.
Should I make a routine to read all the options to an arrays in the javascript?
Or should I make ajax calls to the server to obtain the data as json and then populate it(this I saw is the traditional way of doing the trick and then the HTML of the selects is generated on client side)?
I would like to keep HTML been generated on the server side.
BTW server is Apache and I use PHP.
Thanks.
I highly recommend you to use AngularJS to generate HTML on the client side, and get the JSON data from the server.
Trigger action on parent select change
<select id="parent" ng-model="parentSelectValue" ng-change="filterChildSelect(parentSelectValue)">
<option value="parentValue1">Parent option 1</option>
<option value="parentValue2">Parent option 2</option>
<!-- ... -->
<option value="parentValue2000">Parent option 2000</option>
</select>
This will trigger filterChildSelect(parentSelectValue) on your controller when the value selected changes.
Populate child select with server data
In your controller define the variable with your JSON data. For the sake of simplicity I will define an static array, but this should be the JSON data from your server
$scope.childDataOriginal = [
{
name: "Child name 1",
value: "child1"
}, {
name: "Child name 2",
value: "child2"
}
];
// Iterave over a copy of the original data in order not to modify it when filtering
$scope.childData = angular.copy($scope.childDataOriginal);
Then iterave over it in your view:
<select id="child">
<option ng-repeat="child in childData" value="{{child.value}}">{{child.name}}</option>
</select>
Define your filtering function in your controller
Define a function which iterates over your original data and pushes to a temprary array the elements which pass some filter. Then assign that temprary array to your $scope.childData array.
$scope.filterChildSelect = function (parentSelectedValue) {
var i,
childDataTmp = []
for (i = 0; i < $scope.childDataOriginal.length; i = i + 1) {
if (someCondition) {
childDataTmp.push($scope.childDataOriginal[i]);
}
}
$scope.childData = childDataTmp;
}
I think that a problem with generating this server-side is after you have selected an option in the parent (which filters the child options), and then select another option in paren, you need to keep track of what options were there to begin with.
I would suggest providing angular with the options for both <select>.
If angular has the list of options and they are structured something like this, the filtering would be trivial.
...
function controller() {
var vm = this;
vm.parentValue = null;
vm.childValue = null;
vm.parentOptions = [
{key: 'parent 1', value: 1},
{key: 'parent 2', value: 2},
];
vm.childOptions = [
{key: 'parent 1 child 1', value: 'parent1_child1', category: 1},
{key: 'parent 1 child 2', value: 'parent1_child1', category: 1},
{key: 'parent 2 child 1', value: 'parent2_child1', category: 2},
{key: 'parent 2 child 2', value: 'parent2_child2', category: 2},
];
}
...
<html>
...
<div ng-controller="controller as ctrl">
<select ng-model="ctrl.parentValue"
ng-options="parent.key as parent.value for parent in ctrl.parentOptions">
</select>
<select ng-model="ctrl.childValue"
ng-options="child.key as child.value for child in ctrl.childOptions | filter:{category: ctrl.parentValue}">
</select>
</div>
...
</html>
I am having trouble with a <select> input and binding with AngluarJS. I've created a minimum working sample on Plunker: http://plnkr.co/edit/P4T25RoJrU4mvbBiUJ9S?p=preview.
The basic issue is as follows: the value in the dropdown is never pre-selected with the value from my model.
Additionally, in Angular 1.1.5, ng-options appears to not include a "label" on the generated <option> tags, so when you change selection the drop down control doesn't register any change.
Two issues:
Compare strings to strings
Be careful when using select as and track by in the same expression.
JS
angular.module('defaultValueSelect', [])
.controller('ExampleController', ['$scope', function($scope) {
$scope.data = {
availableOptions: [
{id: '1', name: 'Option A'},
{id: '2', name: 'Option B'},
{id: '3', name: 'Option C'}
],
//USE this
selectedOption: '2'
//NOT this
//selectedOption: 2 //This sets the default value
};
}]);
HTML
<!-- remove 'track by option.id' -->
<select name="mySelect" id="mySelect"
ng-options="option.id as option.name for option
in data.availableOptions track by option.id"
ng-model="data.selectedOption">
</select>
From the Docs:
Be careful when using select as and track by in the same expression.
This will work:
<select
ng-options="item as item.label for item in items track by item.id"
ng-model="selected">
</select>
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>
-- AngularJS ng-options Directive API Reference
As requested by OP, adding the comment as the answer.
If you remove the "track by option.id" from the ng-options as following, it should pre-select based on your model.
<select name="mySelect" id="mySelect"
ng-options="option.id as option.name for option in data.availableOptions"
ng-model="data.selectedOption"></select>
Check out the modified Plunker: http://plnkr.co/edit/b4ddyA5Q4jGNcJI1d8eW?p=preview
I have drop down inside ng-repeat as follows.
<div ng-model="list in lists">
<div>
<select ng-model="pType" ng-options="c.name in projType"></select>
<option value="{{list.value}"></option>
</div>
My Controller is
App.controller('pOverCtrl', function ($scope, pOverRepository, $location) {
$scope.lists = projOverRepository.query();
$scope.projType = [
{ value: '0', name: 'None Selected' },
{ value: '1', name: 'Construction' },
{ value: '2', name: 'Maintenance' },
];
})
The dropdown gets populated fine. But my goal is that when ng-repeat is executed it automatically shows the value that is coming from lists scope as selected.
Please let me know how to fix this issue.
use the diretive ng-selected
<div ng-model="list in lists">
<select ng-model="pType" ng-options="c.name in projType">
<option ng-selected="list.value == list.selected" value="{{list.value}"></option>
</select>
</div>
assuming that list.selected variable contains the value of the option selects
$scope.pType should have the selected value as it's bind by ng-model.
Read the docs here: http://docs.angularjs.org/api/ng/directive/select
And if you already have the selected value in $scope.lists, you can use the ngSelected directive.