ng-model is not passing through correct value - angularjs

I have a select element in which users can select a orderBy filter,
%select{
"ng-change" => "select()",
"ng-model" => "selectedItem",
"ng-options" => "option.sortBy for option in listOfOptions"}
This is the listOfOptions
$scope.listOfOptions = [
{sortBy: 'Release date', value:'release_date'},
{sortBy: 'Newly added', value:'created_at'}
];
And the select function,
$scope.select = function(){
console.log($scope.selectedItem.value)
}
In the view the select box shows both the release date and newly added options, but when I select one of them I get the error,
TypeError: Cannot read property 'value' of undefined
So it looks like $scope.selectedItem is undefined, but I can't figure out why.

Well I did a plunker and the select works as expected
Plunker
app.js:
$scope.listOfOptions = [{
sortBy: 'Release date',
value: 'release_date'
}, {
sortBy: 'Newly added',
value: 'created_at'
}];
$scope.select = function() {
console.log($scope.selectedItem.value)
}
Index.html:
<select ng-change="select()" ng-options="option.sortBy for option in listOfOptions" ng-model="selectedItem"></select>
<p>{{selectedItem}}</p>
Can you provide your angular version ?

Related

angular repeat directive, run again

var phoneIdentification = {
'phoneFiled': {
'label': 'Enter Phone',
'regex': '[0-9]{11,12}'
}
};
var mailIdentification = {
'mailField': {
'label': 'Enter Email',
'regex': '^[A-Za-z0-9._%+-]+#[A-Za-z0-9.-]+\.[A-Za-z]{2,4}$'
},
'passwordField': {
'label': 'Enter Password'
}
};
I have for example this two data. Default I render first one:
$scope.data.dataSource = phoneIdentification;
And Than in view:
<div ng-repeat="(key, item) in dataSource">
<label>{{item.label}}</label>
<input type="text" ng-if="item.regex" ng-pattern="{{item.regex}}"/>
</div>
And I have button also, on click I changed dataSource, I'm setting new value from controller:
$scope.data.dataSource = mailIdentification;
View is updating but, problem is validations, It doesn't update input's Reg-exes>
How it is possible to re-render whole view?
You are missing the regex property in the passwordField field in the mailIdentification object. You need it because you are accessing it in the ng-repeat directive.
Your mailIdentification object should look like this:
var mailIdentification = {
...
'passwordField': {
'label': 'Enter Password',
'regex': `some regex here`
}
};

Error when passing filter parameter in Uigrid with cell nav

I have a editable Uigrid with ui-grid-cellnav directive to enable edit on focus. I also have a filter to display value instead of id in the dropdown.
<div ui-grid="gridOptions" ui-grid-edit ui-grid-cellnav class="grid"></div>
JS
$scope.gridOptions.columnDefs = [
{ name:'name', width:100 },
{ name:'age', width:100},
{ name: 'gender', displayName: 'Gender', editableCellTemplate: 'ui-grid/dropdownEditor', width: '20%',
cellFilter: "griddropdown:this", editDropdownIdLabel:'id',
editDropdownValueLabel: 'gender', editDropdownOptionsArray: [
{ id: 1, gender: 'male' },
{ id: 2, gender: 'female' }
] }
];
An error occurs whenever the dropdown value is modified. It seems the filter parameter is passed as a string instead of actual object, but not sure why. Works ok if I remove the cellnav directive.
Plnkr
Thanks in advance!
Interesting, I played with it a little bit and it looks like you are getting the desired results, just that occasionally ui-grid likes to pass a string as a parameter instead of the object.
If you add a check for a string in your filter it looks like you will still be getting the desired results, that's if I am understanding properly:
String check to add:
if (typeof context !== 'string') {}
Full Filter:
.filter('griddropdown', function() {
return function (input, context) {
if (typeof context !== 'string') {
var map = context.col.colDef.editDropdownOptionsArray;
var idField = context.col.colDef.editDropdownIdLabel;
var valueField = context.col.colDef.editDropdownValueLabel;
var initial = context.row.entity[context.col.field];
if (typeof map !== "undefined") {
for (var i = 0; i < map.length; i++) {
if (map[i][idField] == input) {
return map[i][valueField];
}
}
} else if (initial) {
return initial;
}
}
return input;
};
});

unable to update the ngmodel of select list

Case :
I am trying to update the value of ng-model inside the controller but it is not working and i wonder why , any idea ?
HTML :
<select ng-model="dumm" ng-options="item.name as item.type for (name, item) in availableFilters" ng-change="selectFilter()"></select>
JS :
$scope.selectFilter = function () {
$scope.availableFilters[$scope.dumm].visible = true;
$scope.dumm = "";
};
$scope.availableFilters = {
name: {
type: 'Name',
name: 'name'
},
producttype: {
type: 'Product type',
name: 'producttype',
data: $scope.xxx
},
status: {
type: 'Status',
name: 'status',
data: $scope.unitStatusTypes
}
};
$scope.dumm should be an object rather than a string, otherwise the binding won't work - this fact is quite obscure in Angular's docs. The binding should look like this:
<select ng-model="dumm.value"...
and the variable's definition:
$scope.dumm = {value: ""};

AngularJS Select Not Binding To Ng-Model

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/

AngularJS matching data between json arrays and setting a selected option

$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

Resources