How can I set the initial value of a <select> with AngularJS? - angularjs

I am using this code in my controller:
$scope.$watch('option.selectedPageType', function () {
if ($scope.isNumber($scope.option.selectedPageType)) {
localStorageService.add('selectedPageType', $scope.option.selectedPageType);
}
})
getPageTypes: function ($scope) {
$scope.option.pageTypes = [
{ id: 0, type: 'Edit Basic' },
{ id: 1, type: 'Edit Standard' },
{ id: 2, type: 'Report' }
];
$scope.option.selectedPageType = parseInt(localStorageService.get('selectedPageType'));
},
and in my HTML:
<select data-ng-model="option.selectedPageType"
data-ng-options="item.id as item.type for item in option.pageTypes">
<option style="display: none" value="">Select Page Type</option>
</select>
Instead of using the "Select Page Type" option. How can I make it so my code defaults to the value in local storage or if there is nothing there then to one of the values I have in my option.pageTypes list ?

Have your localStorageService return null if there is nothing stored. If it does exist, have the service return the integer
Then in controller:
/* assume want first item in array */
$scope.option.selectedPageType = localStorageService.get('selectedPageType') || $scope.option.pageTypes[0].id

Try using ng-init on the <select ...>:
<select data-ng-model="option.selectedPageType"
data-ng-options="item.id as item.type for item in option.pageTypes"
data-ng-init="option.selectedPageType=DEFAULT_VALUE">
See this fiddle: http://jsfiddle.net/CaeUs/5/

Related

multiselect dropdown in angularjs only works on initialization of Controller

I am using jquery, bootstrap multi-select dropdown. I want to populate multi-select dropdown (talukas) on selectionChange event of other normal (single-select) dropdown (city). I am not able to figure out why the multi select dropdown populates on initial load of a controller and why not on selection change of other dropdown. Can you please help me. Thank you.
Scenario - 1 => This works fine
<div ng-controller="tempController" ng-init="initializeController()" ng-cloak>
<select id="multiSelect" name="multiSelect" multiselect=""
multiple="" ng-model="selectedTalukas" ng-options="option.talukaId as
option.label for option in talukas"></select>
</div>
// .js
$scope.selectedTalukas = [];
$scope.initializeController = function () {
$scope.talukas = [
{ talukaId: 1, label: 'Taluka1' },
{ talukaId: 2, label: 'Taluka2' },
{ talukaId: 3, label: 'Taluka3' }
]
}
Scenario - 2 => This DO NOT works fine - WHY
<select id="city" class="form-control select2" name="ddlCity" ng-model="c" ng-options="c as c.name for c in city | orderBy:'name'"
ng-change="selectedCityChange(c)" >
</select>
<select id="multiSelect" name="multiSelect" multiselect=""
multiple="" ng-model="selectedTalukas" ng-options="option.talukaId as
option.label for option in talukas"></select>
$scope.selectedCityChange = function (selectedValue) {
if (selectedValue !== undefined) {
$scope.selectedCity = selectedValue;
$scope.selectedCityId = selectedValue.cityId;
$scope.ajaxPost(selectedValue.cityId,
'/api/Taluka/getTalukasForSelectedCity',
$scope.selectedCityChangeComplete,
$scope.selectedCityChangeError);
}
};
$scope.selectedCityChangeComplete = function (response) {
$scope.talukas = response.data.talukaMasters;
}

angular ui-select2 not set value in edit mode

<select id="e1" style="width:100%" ui-select2 tabindex="-1" ng-init="GetAllAgent()" ng-model="Agent" ng-options="ctr as ctr.AgentName for ctr in ListAgent track by ctr.AgentId" ng-change="GetSubAgentList(Agent.AgentId)">
<option value=""> </option></select>
when it is in edit mode,could not set the default value using the below code
angular.forEach($scope.ListAgent, function (value, index) {
if (value.AgentId == HR.AgentId) {
$scope.Agent = $scope.ListAgent[index];
}
})
$scope.ListAgent= [{ AgentId: "0", AgentName:"Ann" }, { AgentId: "1", AgentName:"Muh" }];
and
HR.AgentId=1
First off, ui-select2 does not support ng-options: https://github.com/angular-ui/ui-select2/issues/252
Further, ui-select2 does not work with ng-repeat: https://github.com/angular-ui/ui-select2/issues/162
The solution is to use input:
<input ui-select2="select2Options" ng-model="Agent"/>
where select2Options is:
$scope.select2Options = {
data:$scope.ListAgent
}
The list should have structure: [{id,text}] so $scope.ListAgent will be
$scope.ListAgent= [{ id:0, text:"Ann" }, { id:1, text:"Muh" }];
Demo Plunker
For place holder add data-placeholder="----"

Angular Select2 formatResult not updating the template

I have a select2 drop down with the following markup:
<select id="selectByName" ui-select2="select2Options" ng-model="selectId" data-placeholder="Select item by name" style="width:250px">
<option></option>
<option ng-repeat='item in items' data-show="{{item.show}}" value="{{item.id}}">
{{item.name}}
</option>
</select>
And the js contains the following:
$scope.items (an array that has a id, a boolean show property and a name property)
and the select 2 options:
select2Options : {
allowClear: true,
placeholder:"select a value",
formatResult: function(state) {
var $elem = angular.element(state.element),
isVisible = $elem.data('show');
return isVisible ? '<span style="color:red">'+state.text+'</span>':
<span style="color:blue">'+state.text+'</span>';
}
},
Well, the ng-repeat updates correctly the html markup and sets data-show attribute to either true or false, but the formatResult function does not update this value.
In the html source the data-show="true" and in the formatResult function $elem.data('show') = false;, why doesn't it update while the function is called every time the select2 is opened?
Here is made a plunker that illustrates my question: plnkr.co/edit/d0LxuhzdQh7hMdzOoxpr?p=preview .It looks the formatResult updates the results correctly only once before opening the select2 for the first time.
Edit
http://plnkr.co/edit/6Vma1WTQWQw0HAIQUVxE?p=preview
$scope.select2options = {
allowClear: true,
placeholder: "select a value",
formatResult: function(state, container) {
var $elem = angular.element(state.element);
var scope = $elem.data('$scope');
if (scope !== undefined) {
isVisible = scope.$eval($elem.data('show'));
$scope.dataShow[$elem.attr('value')] = isVisible;
$scope.updated++;
return isVisible ? '<span style="color:red">' + state.text + '</span>' :
' <span style="color:blue">' + state.text + '</span>'
}
}
}
The key part is grabbing the $scope data from the jqLite element and then calling $eval, which evaluates an unparsed string expression in the context of the scope. If we had used $scope.$eval, it would have used the controller $scope, which wouldn't have the ng-repeat on it. By grabbing it from the element we have a scope that has access to the item property for the ng-repeat.
Having said that I don't recommend using this code (sometimes jQuery widgets force you into unpleasant corners when working with angular). Again if you find yourself manipulating angular.element or using $element in a controller you probably should use a directive instead. Then again we programmers have to deal with non-ideal constraints (time, money, etc.) that prevent us from working "ideally" so given your context this may be a decent solution.
Let me know if any of my explanation doesn't make sense.
Original
http://plnkr.co/edit/vYTdxPwgwqZSgK5m9yk9?p=preview
Is this what you want?
JavaScript
$scope.items = [{
id: 1,
show: false,
name: 'test1'
}, {
id: 2,
show: true,
name: 'test2'
}, {
id: 3,
show: true,
name: 'test3'
}];
$scope.selections = [1, 2];
$scope.getStyleForIndex = function (index) {
var item;
for (var i = 0; i < $scope.items.length; i++) {
if (i === index) {
item = $scope.items[i];
break;
}
}
return item.show ? { color: "red" } : { color: "blue" };
}
$scope.select2options = {
allowClear: true,
formatResult: function(item, container) {
var color = $scope.getStyleForIndex(parseInt(item.id, 10)).color;
container.html('<span style="color:' + color + '">RESULT ' + item.text + '</span>');
},
formatSelection: function(item, container) {
container.append($compile('<span ng-style="getStyleForIndex(' + item.id + ')">SELECTION ' + item.text + '</span>')($scope));
}
}
HTML
<div ng-repeat="item in items">
{{ item.name }}
<input type="checkbox" ng-model="item.show" />
</div>
<select ui-select2="select2options" ng-model="selections" style="width:200px" multiple="true" ng-options="i.id as i.name for i in items"></select>
{{selections}}

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

How do I set a selected option for select in Angular

I have an object
$scope.colleges = [{"CollegeCode":"40","CollegeName":"College1"},
{"CollegeCode":"35","CollegeName":"College2"},
{"CollegeCode":"32","CollegeName":"College3"},
{"CollegeCode":"15","CollegeName":"College4"}]
I'm populating a select element with it's contents
<select ng-model="collegeSelection" ng-options="c as c.CollegeName for c in colleges" name="selectCollege"></select>
It renders on the page like so
<select class="ng-pristine ng-valid" name="selectCollege" ng-options="c as c.CollegeName for c in colleges" ng-model="collegeSelection" style="" selected="selected">
<option value="?" selected="selected"></option>
<option value="0">College1</option>
<option value="1">College2</option>
<option value="2">College3</option>
<option value="3">College4</option>
etc....
I'm also binding this select to collegeSelection and when an item is selected the object look like this
$scope.collegeSelection = {"CollegeCode":"32","CollegeName":"College"}
When someone clicks edit on the page, the college I want selected by default comes from the userToUpdate object.
$scope.userToUpdate = {
Id: 1,
FirstName: 'John',
LastName: 'Doe',
CollegeCode: '35,
CollegeName: 'College2',
Active: true
};
When an edit button and the userToUpdate object is populated, I would like the college in the select element to be set to the college in the user object. How could one make this happen? FYI, the value in the rendered select does not match the CollegeCode. It seems angular uses the index from the colleges object. Thanks
Try this one
<select ng-model="collegeSelection" ng-options="c.CollegeCode as c.CollegeName for c in colleges" name="selectCollege"></select>
<span>{{collegeSelection}}</span>
<input type="button" ng-click="switch()" name="switch" value="switch" />
<script>
var app = angular.module('plunker', []);
app.controller('MainCtrl', function ($scope, $filter) {
$scope.colleges = [{ "CollegeCode": "40", "CollegeName": "College1" },
{ "CollegeCode": "35", "CollegeName": "College2" },
{ "CollegeCode": "32", "CollegeName": "College3" },
{ "CollegeCode": "15", "CollegeName": "College4" }
]
$scope.switch = function () {
$scope.collegeSelection = "32";
};
});

Resources