I have created a fiddle for showcasing the issue that in selects which are dependent on other selects for their values(I like to call them successive selects)
I am unable to assign an initial value to a successive select.
Like
HTML
<select ng-model="car.brand" ng-options="brand for brand in brands" ng-change="selectedBrand(car.brand)"></select>
<select ng-model="car.model" ng-options="model.name for model in cars[carIndex]"></select>
<input type="text" ng-model="car.model.capacity">
JS
$scope.brands = ['Ford', 'Honda', 'Hyundai', 'Mahindra',
'Maruti Suzuki', 'Nissan', 'Renault', 'Skoda', 'Tata', 'Toyota', 'Volksvagen'
];
$scope.selectedBrand = function(brand) {
console.log(brand);
$scope.carIndex = $scope.brands.indexOf(brand);
}
$scope.cars[0] = [{
name: "Figo",
capacity: 45
}, {
name: "Ecosport",
capacity: 52
}, {
name: "Fiesta",
capacity: 45
}, {
name: "Endeavour",
capacity: 71
}];
/*My Attempt*/
/*Successful*/
$scope.car.brand = $scope.brands[0];
/*Unsuccessful*/
$scope.car.model = $scope.cars[0][0].name;
QUESTION
How do I initialize the second select and the input box dynamically when the first select is used?
First, you should set carIndex. And car.model must be set to the type same as model in <select ng-options=".. for model in ..
$scope.carIndex=0;
$scope.car.brand = $scope.brands[0];
$scope.car.model = $scope.cars[0][0];
Related
How can I filter an ng-repeat to show all items where a certain columnfield is an empty string? When I try this by typing nothing in the field it always seem to give the full list (wich is expected). I only want to see the person with id 1. How can I adjust the filter that a certain character in the inputfield makes the ng repeat filter on empty fields for the name column.
FiddleJs Example
My view:
<div class="panel-heading">
<h3>Filtered by {{filterValue}}</h3>
<input ng-change="filter()" ng-model="filterValue"/>
</div>
<div class="panel-body">
<ul class="list-unstyled">
<li ng-repeat="p in filteredPeople">
<h4>{{p.name}} ({{p.age}}) id: {{p.id}}</h4>
</li>
</ul>
</div>
Controller:
var people = [{
name: '',
age: 32,
id: 1
}, {
name: 'Jonny',
age: 34,
id: 2
}, {
name: 'Blake',
age: 28,
id: 3
}, {
name: 'David',
age: 35,
id: 4
}];
$scope.filter = function (value) {
$scope.filteredPeople = $filter('filter')(people, {
name: $scope.filterValue
});
}
$scope.people = people.slice(0);
Delete your $scope.filter() function in the controller and the ng-change="filter()" in your view. You should change var people array to $scope.people. You also need to delete the line $scope.people = people.slice(0);.
Create a filter function in your controller to only return people whose name property is empty if $scope.filterValue is empty:
$scope.emptyFilter = function(person) {
if ($scope.filterValue.length === 0) {
if (person.name.length === 0) {
return person;
}
} else {
return person;
}
};
Next, update your ng-repeat with the following:
<li ng-repeat="p in people | filter:emptyFilter | filter:{name: filterValue}">
My angular select isn't binding. I can tell the value is correct, but the select isn't updated. Why is not binding if the value is there?
<div ng-controller="MyController" ng-app>
<select class="form-control" ng-model="colorId"ng-options="color.id as color.name for color in colorList">
<option value="">--Select a Color--</option>
</select>
<input type="button" value="submit" ng-click="Select()"></input>
function MyController($scope) {
$scope.colorList = [{
id: '1',
name: 'red'
}, {
id: '2',
name: 'blue'
}, {
id: '3',
name: 'green'
}];
var colorId = 3;
$scope.colorId = colorId;
alert($scope.colorId);
$scope.Select = function () {
var colorId = 2;
$scope.colorId = colorId;
}
}
Here is a fiddle:
http://jsfiddle.net/ky5F4/23/
you need to change the id to a string when doing Select
$scope.Select = function () {
console.log('select fired');
var colorId = 1;
$scope.mySelection.colorId = colorId + "";
}
http://jsfiddle.net/bxkwfo0s/2/
next you should use a property of an object rather than just a scope variable, this will ensure proper model binding
ng-model="mySelection.colorId"
where the object could be something simple
$scope.mySelection = {colorId : colorId };
There are two errors with your code:
You are using colorList as your model in ng-options, but you are calling it datasets in your controller.
You use strings for the id, but set the $scope.colorId to a number.
Here is an updated fiddle changing ids to numbers and changing $scope.datasets to $scope.colorList
function MyController($scope) {
$scope.colorList = [{
id: 1,
name: 'red'
}, {
id: 2,
name: 'blue'
}, {
id: 3,
name: 'green'
}];
var colorId = 3;
$scope.colorId = colorId;
alert($scope.colorId);
$scope.Select = function () {
var colorId = 2;
$scope.colorId = colorId;
}
}
Consider making your ng-model be an object, specifically one of the objects that are already in your $scope.colorList. If you do that you should be able to avoid the post-processing you're doing in the click handler.
So your select will look like this:
<select class="form-control" ng-model="selectedColor"
ng-options="color.name for color in colorList"></select>
One gotcha is that if you have an object in your controller that looks JUST LIKE your red object, like$scope.selectedColorObj = { id : '1', name:'red' } and set the select's ng-model to that option, it won't work. Angular will see that you're setting to the ng-model to an object that's not actually in your data source and add an extra option with value="?", so I use $filter in this case to grab the matching member of the array:
$scope.colorId = '3';
$scope.selectedColor = $filter('filter')( $scope.colorList,{ id: $scope.colorId})[0];
See http://jsfiddle.net/ky5F4/92/
I need to set the option value yo id for the rendered select tag, using the following example I can set the option value as 0, 1, ,2.
Any idea what am I doing wrong here?
http://jsfiddle.net/GFF6P/1/
function ctrl($scope) {
$scope.devices = [{
name: "pc1",
id: 10
}, {
name: "pc2",
id: 20
}, {
name: "pc3",
id: 30
}];
$scope.selectedDevice = $scope.devices[0];
}
<div ng-app ng-controller="ctrl">
<select data-ng-model="selectedDevice" name="devices" data-ng-required="true" data-ng-options="device.name for device in devices"></select>
</div>
View
<select data-ng-model="selectedDevice"
name="devices"
data-ng-required="true"
data-ng-options="device.id as device.name for device in devices">
</select>
Controller
$scope.selectedDevice = $scope.devices[0].id;
Updated Fiddle
I am using Angular to build a SELECT using ng-options, and all is working minus the fact I would like to set the value rather than having Angular auto-populate that.
$scope.form.stage = [{
optional: 1
id: 23
description: UD Visual Inspection - optional
},{
optional: 0
id: 12
description: Flash
}]
My directive:
<select name='test_stage' ng-model='form.selectedStage' ng-change='abc(form)' ng-options='item.description for item in form.stage'>
Rendered HTML:
<select name="test_stage" id="test_form_stage" tabindex="2" ng-model="form.selectedStage" ng-change="abc(form)" ng-options="item.description for item in form.stage" ng-blur="fetchTestStation(form)" class="ng-valid ng-dirty"><option value="0">UD Visual Inspection - optional</option><option value="1">Flash</option></select>
Instead of having the values be set to 0 and 1 I want 23 and 12...
Update Rendered HTML:
<select name="test_stage" id="test_form_stage" tabindex="2" ng-model="form.selectedStage" ng-change="abc(form)" ng-options="item.id as item.description for item in form.stage" ng-blur="fetchTestStation(form)" class="ng-valid ng-dirty"><option value="0">UD Visual Inspection - optional</option><option value="1">Flash</option></select>
Updated: 7-25-15
form: {
selectedStage: null
stage:
[{
optional: 1
id: 23
description: UD Visual Inspection - optional
},{
optional: 0
id: 13
description: Engraving
}]
}
selectedStage: {
$ref: $["form"]["stage"][1]
}
Generated HTML
<select name="test_stage" id="test_form_stage" tabindex="2" ng-model="form.selectedStage" ng-options="item as item.description for item in form.form.stage" ng-blur="fetchTestStation(form)" class="ng-valid ng-dirty"><option value="?"></option><option value="0">UD Visual Inspection - optional</option><option value="1">Engraving</option></select>
My Controller
$scope.fetchTestRecord = function($scope){
// Set vars
$scope.workorder = {};
$scope.product = {};
// Set params to send in request
var params = $.param({
serial: $scope.serial
});
/**
* Get stage data for serial from API [Factory]
*/
tstFrmServices.locateRecord(params).success(function (result) {
$scope.data = result.data;
// Handle successfull response
if ($scope.data['success'][0].code == 200){
$scope.form = {
selectedStage: null,
stage: $scope.data['success'][0].data
};
$scope.workorder = $scope.data['success'][0].wo;
$scope.product = $scope.data['success'][0].product;
}
}).error(function (result) {
});
};
});
Data returned from Factory
"data": [{"optional": 1, "id": 23, "description": "UD Visual Inspection - optional"}, {"optional": 0, "id": 13, "description": "Engraving"}], "product": "10P91685-010"}]}
If you let selectedStage be the entire selected object, you can get the value you want from form.selectedStage.id
<select name='test_stage'
ng-model='form.selectedStage'
ng-change='abc(form)'
ng-options='item as item.description for item in form.stage'>
</select>
http://embed.plnkr.co/fsn5qakC6nKUOdQKhYjR/preview
$scope.opts =
{
unit: [
{ id: 1, val: "px", name: "px"},
{ id: 2, val: "%", name: "%"}
]
}
The above is my options list array and now I set my default option.
$scope.user.unit = $scope.opts.unit[0];
The above creates the following in my html
<select class="unit ng-pristine ng-valid" data-ng-options="a.name for a in opts.unit" data-ng-model="user.unit">
<option value="0" selected="selected">px</option>
<option value="1">%</option>
</select>
When I use the below I am pulling the data that was stored in a db from the options selected in the above example.
$http.get('/assets/inc/file.php?id='+thisPage).success(function(response) {
var userData = response.userData;
var locationData = response.locationData;
$scope.user = userData;
$scope.locations = locationData;
console.log($scope.user.unit);
});
This console.logs me the following Object { id=1, val="px", name="px"}
I may be wrong but the <select> box is binded to $scope.opts
How would I be able to link the retrieved data from $scope.user.unit to $scope.opts.unit so that when the data is retrieved it will then mark the correct option as :selected?
I'm not 100% sure but you can try this (or create JSFiddle):
JS:
$http.get('/assets/inc/file.php?id='+thisPage).success(function(response) {
var userData = response.userData;
var locationData = response.locationData;
$scope.user = userData;
$scope.locations = locationData;
$scope.selected = {};
angular.forEach($scope.opts.unit, function (value)
{
if (value.val == $scope.user.unit.val) {
$scope.selected = value
}
});
console.log($scope.user.unit);
});
and in View:
<select class="unit ng-pristine ng-valid" data-ng-options="a.name for a in opts.unit" data-ng-model="user.unit">
<option value="{{selected.val}}">{{selected.name}}</option>
</select>
Your ng-model for the select element is an object, and not a primitive type, which is fine, but then you reassign $scope.user to a brand new object (returned from $http.get), so user.unit is a new object too, so it's not identical to any of your ng-options. I can think of two ways which should fix the problem:
bind the select to the 'id' property of the unit object:
<select ng-options="a.id as a.name for a in opts.unit" ng-model="user.unit.id">
or leave the select bound to user.unit, but use the track by feature of ng-options:
<select ng-options="a.name for a in opts.unit track by a.id" ng-model="user.unit">
One of the things in Angular is that you rarely need to do is explicitly create <option> elements manually as the framework will generate this for you. Therefore, the following will work: (Working jsfiddle at http://jsfiddle.net/LMHLq/12/)
HTML:
<select data-ng-model='user.unit' data-ng-options="o.id as o.name for o in opts.unit"/>
JavaScript:
$scope.opts ={
unit: [
{ id: 1, val: "px", name: "px"},
{ id: 2, val: "%", name: "%"},
{ id: 3, val: "pt", name: "pt"}
]
}
$http.get('/assets/inc/file.php?id='+thisPage).success(function(response) {
var userData = response.userData;
var locationData = response.locationData;
$scope.user = userData;
$scope.locations = locationData;
console.log($scope.user.unit);
});
$scope.opts ={
unit: [
{ id: 1, val: "px", name: "px"},
{ id: 2, val: "%", name: "%"},
{ id: 3, val: "pt", name: "pt"}
]
}
I noticed that the $scope.opts builds my select element and populates it but when the data is retrieved via db it needs to go into $scope.user.unit but this is binded to $scope.opts so what I have done is sought out the ID for the item that was retrieved and then added -1 to it so it will select from the array of $scope.opts.unit
var testUnit = $scope.user.unit.id-1; //gets the ID of the unit thats been retrieved
$scope.user.unit = $scope.opts.unit[testUnit]; //sets the selected option in the dom