Angularjs select list not initialize default value - angularjs

I have 2 select lists:
<select class="input-large" ng-model="bu.box.categoryId" ng-change="getSubCats()">
<option ng-repeat="cat in cats" value="{{cat.id}}">{{cat.name}}</option>
</select>
<select class="input-large" ng-model="bu.box.subCategoryId">
<option ng-repeat="subcat in subCats" value="{{subcat.id}}">{{subcat.name}}</option>
</select>
The object bu, subcats is injected to my controller from resolve and exists before bindings is render and cats i get from local storage:
$stateProvider.state('box',
{
url: '/box-card/:id',
templateUrl: '/partials/main.module/contollers/box.html?v=' + global_app_version,
controller: 'BoxController as boxCtrl',
resolve: {
Box: function ($stateParams, httpService) {
return httpService.getBox({ boxid: $stateParams.id });
}
}
})
Controller variables initialization look like this:
function boxController($scope, localStorageService, httpService, $state, appData, uiGridConstants, $modal, helpersService, $stateParams, $sce, Box) {
$scope.bu = Box.data.bu;
$scope.cats = localStorageService.get("cats");
$scope.subCats = Box.data.currentSubCats;
............
var controllers = angular.module('app.controllers');
controllers.controller('BoxController', boxController);
The problem is, when the select lists is rendered, they not initialized correctly,
The first option is selected instead of relevant initialization by ng-model.
What happen here? Why is not working correctly?
I checked all variables in debug, all fine... Need help here.

Try to solve the problem with ng-selected.

<select class="input-large" ng-model="bu.box.categoryId" ng-init="cat = cats[0]" ng-change="getSubCats()">
<option ng-repeat="cat in cats" value="{{cat.id}}">{{cat.name}}</option>
</select>
<select class="input-large" ng-model="bu.box.subCategoryId" ng-init="subcat = subCats[0]">
<option ng-repeat="subcat in subCats" value="{{subcat.id}}">{{subcat.name}}</option>
</select>
I use in my project ng-init like ng-init="subcat = subCats[0]"
change the subCats[0] and cats[0] for your init values

Try using $scope.$apply() .
From the article:
If you write any code that uses Ajax without $http, or listens for
events without using Angular’s ng-* listeners, or sets a timeout
without $timeout, you should wrap your code in $scope.$apply
It looks like exactly your case. Box is updated in a background request and angular listeners do not know that it was updated.
UPD1
Also Just noticed that the problem could hide here
$scope.bu is initialized before $scope.cats so model actually tries to match a still empty list of options.
upd2
just noticed in the comment that ng-options binding was a bit off.
try using
<select ng-options="cat.name for cat.id in cats track by cat.id" class="input-large" ng-model="bu.box.categoryId" ng-change="getSubCats()">

Related

ngModel doesn't bind to select option

I can't figure out why i can't bind to a select element
there is my code:
<select ng-model="site" ng-change="getAll()">
<option value="SG1">SG1</option>
<option value="PZ1">PZ1</option>
<option value="NE1">NE1</option>
</select>
getAll() make an alert of 'site' but the var is never updated.
$scope.site is nerver use except in getAll()
$scope.getAll = function () {
alert($scope.site);
}
If i set $scope.site to a value it is display but never update either
Edit:
I forgot a big detail...
The select is display with a ng-include directive
<section id="sectionLeft" ng-include="nav[navId]">
</section>
ng-include creates a new scope which prototypally inherits from your controller. So you are initially reading the selected option from your controller, but when the select element writes a new selected option it ends up writing to the inherited scope.
You can bind to an object instead.
Controller:
$scope.data = { site: "SG1" };
$scope.getAll = function() {
alert($scope.data.site);
}
Template:
<select ng-model="data.site" ng-change="getAll()">
<option value="SG1">SG1</option>
<option value="PZ1">PZ1</option>
<option value="NE1">NE1</option>
</select>
See this answer for more details.
If you don't like switching to an object, look up controller as syntax and bind directly to the controller instead of $scope.
I've fiddled your code and i'm able to get the updated value in the alert box.
$scope.getAll = function() {
alert($scope.site);
};
Working Fiddle

Select Dropdown not displaying $scope value in model

I've used angular plenty of times, but can't seem to spot the issue I'm getting:
I pass through an ID like so as a clickable link within a repeater:
<td data-title="'Company Name'" sortable="'CompanyName'"><a ui-sref="Locations({company_id: row.CompanyID})">{{row.CompanyName}}</a> </td>
The value is correctly passed through and received by the relevant controller I use a query string service to get the relevant filters. The console.log correctly shows the correct value. However, it is not selecting the relevant value within the select dropdown:
angular.module('app').controller("LocationsController", ['$timeout',
'$scope', '$http', 'QueryStringService', 'NgTableParams', '$location',
function ($timeout, $scope, $http, QueryStringService, NgTableParams,
$location) {
var default_filters = { location_name: "", address_1: "", company_id: "" };
$scope.filterBy = QueryStringService.getFilters(jQuery.extend(true, {}, default_filters));
console.log($scope.filterBy.company_id);
}
// Displayed on relevant view
<select ng-model="filterBy.company_id" ng-options="option.CompanyID as option.CompanyName for option in companies" class="form-control form-control-query">
<option value="">All</option>
</select>
Can anyone notice anything?
I think you are facing a controller scope issue:
You are setting a variable in a controller instance, and trying to get it from another instance.
The fact is that a controller is instancied for each page, even if it is the same controller name (that may be confusing).
You should use a service to store this variable (for example your QueryStringService), and access it from your other page.
Here is a JSFiddle demo.

AngularJs ng-mouseover not working in option tags

I use angularJS and I want to call function when mouse change over in option list. I tried ng-mouseover="changeProjectColor(t)" but it not working for me.
<select id="select-tamplete" ng-model="tamplete">
<option ng-repeat="t in tampletes" ng-mouseover="changeProjectColor(t)" ng-value="t">{{t.name}}</option>
</select>
controller:
app.controller('ControlBoxCtrl',function($scope, adminSer, $log){
$scope.adminSer = adminSer;
$scope.tampletes = [
{name:"gray",colorClass:"gray"},
{name:"green",colorClass:"green"},
{name:"yellow",colorClass:"yellow"},
{name:"blue",colorClass:"blue"},
{name:"purple",colorClass:"purple"},
{name:"red",colorClass:"red"},
{name:"amber-light",colorClass:"amber-light"},
{name:"teal",colorClass:"teal"}
];
$scope.changeProjectColor = function(){
$log.debug("change color");
}
});
You cannot attach ng-mouseover, ng-clicked, ng-mousemove events with options list. You can do so with the select element since events can only be attached to elements and not to options. Better use ng-change event with selectbox to accomplish your requirement.
<select id="select-tamplete" ng-model="tamplete" ng-options="t.name for t in tampletes" ng-change="changeProjectColor(tamplete)">
</select>

AngularJS/UI-Router change state from select/option

So I have a SPA using AngularJS/UI-Router and I have a section where I need to change states from a select/option. I originally had links in an ng-repeat like this:
<ul class="unstyled">
<li data-ng-repeat="course in courses">
<a data-ui-sref=".materials({ courseCode:course.CourseCode })">{{course.Title}}</a>
</li>
</ul>
The issue is that I am going to have upwards of 50 different courses to choose from, so I want to put them into a select/option setup something like this:
<select style="padding:3px 1px; width:100%;" data-ng-model="placeholder" data-ng-options="course.Title for course in courses track by course.CourseCode"></select>
Now, I know I can change the scope with the above by setting up an ng-repeat and just using that ng-model="placeholder", but I need the ability to change states from that select/option. Basically, I have a check that occurs on state change that will either deny or allow access based on a permissions check. If I can do the permissions check from this state, I am more than open to that as an option, but it seemed easier to switch states and do the check on that.
As always, thank you in advance!
Edit: So I looked some more into this and found that I might be able to do something with ng-switch and UI-Router's $state.go. Here is what I have come up with so far:
The controller:
.controller('CoursesTrackCtrl', function ($scope, $stateParams, $http, $log, $state) {
$scope.changeState = function (course) {
$state.go('.materials({ courseCode:course.CourseCode })');
}
});
The state with the select:
<select style="padding:3px 1px; width:100%;" data-ng-model="course" data-ng-options="course.Title for course in courses" data-ng-change="changeState(course)">
<option value="">-- Select a Course --</option>
</select>
I am getting an undefined is not a function when I change the option in the select menu. I can get an alert to pop and pass through pieces of the courses so I know that course is being passed through the scope just fine. I made sure that $state had been added to the controller, but it seems like $state.go isn't going anywhere and I am still not even sure if that would be the correct syntax to actually pass through $stateParams like I would with a normal ui-sref.
Solution:
With the help of David Spence, I was able to solve the error I was having. I was both injecting $state into the controller and using it as a parameter so it was throwing an error. Thank you!
As for the solution, this was the final section of code for the controller:
.controller('CoursesTrackCtrl', function ($scope, $stateParams, $http, $log, $state) {
$scope.changeState = function (course) {
$state.go('courses.track.materials', { courseCode: course.CourseCode });
}
});
The big change here was the syntax for $state.go, which needed to resolve the full path of the state (courses.track.materials vs. just .materials) and the syntax for the parameters differed from the normal ui-sref syntax so it had to be setup as a { parameter : value }.
And for the state itself:
<select style="padding:3px 1px; width:100%;" data-ng-model="course" data-ng-options="course.Title for course in courses" data-ng-change="changeState(course)">
<option value="">-- Select a Course --</option>
</select>
This had been mostly unchanged, but the big thing was to ensure that course was being passed through the scope.
Hope this helps someone else too!
The only thing I can see that is wrong is that $state is being passed as a parameter the changeState method instead of being injected into the controller. See example below without any errors. Just check the state name is correct you are changing to. Looks a bit odd the way it starts with a dot...
function BasicController($scope) {
$scope.changeState = function(course) {
console.log(course.Title);
// todo: transition!
}
$scope.courses = [{
Title: 'maths'
}, {
Title: 'science'
}];
}
DEMO

why select items are not being populated

Here is my html code
<select id="userGroups" name="userGroups" ng-model="userGroups" class="form-control">
<option value="{{grp.groupId}}" ng-repeat="grp in groups">{{grp.groupName}}</option>
</select>
here is my controller
function MyController($scope, MYAPI) {
$scope.groups = MYAPI.GroupList.get();
}
Why options are not being popuplated?
Ok I have changed my controller to resolve the GroupList before populating the view, but its still not showing
MYApp.controller('CreateUserController', ['$scope', 'groupList', function($scope, groupList) {
$scope.groups = groupList;
debugger; //here I can see groups has objects which I need to display
}]);
but still dropdown is not loading...
As Martin said you need to use ng-options.
This is how it should look like:
<select id="userGroups"
name="userGroups"
ng-model="userGroups"
ng-options="grp.groupId as grp.groupName for grp in groups"
class="form-control">
</select>
Accorting to the AngularJS documentation of select you have to use ng-options. This use case is not supported by ng-repeat:
ngOptions provides an iterator facility for the <option> element which should be used instead of ngRepeat when you want the select model to be bound to a non-string value. This is because an option element can only be bound to string values at present.

Resources