why select items are not being populated - angularjs

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.

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

Angular ng-option index issue

I am stuggling with ng-options in Angular version 1. The issue is a follows:
I have a json file that I read to populate a drop-down select:
$http({method: 'GET', url: 'collection_countries.json'})
.then(function successCallback(response) {
$scope.collection_countries = response.data;
$scope.collection_country=$scope.collection_countries[0]; // pre-seelct
}
);
I then generate the drop down as follows:
<select class="form-control" name="deliver_to" ng-model="destination_country" ng-options="item as item.country for item in countries track by item.id" required>
<option value="" disdabled>Select Country</option>
</select>
This works ok to this point, however I am trying read the selected value and corresponding data form the json as follows:
$scope.countries[ $scope.destination_country['country']['id'] ];
As you can see the value $scope.destination_country['country']['id'] is the id which is arbitrary and does not correspond with the index of the json object.
As I see it I have two options:
In the ng-options directive I track by $index (or similar as I know $index is for ng-repeat and not ng-options)
Some how reference the json object by the country_id
I created this plunkr to demonstrate the issue.
https://plnkr.co/edit/19H8A12VnVpdlHQe5vM7?p=preview
Thanks.

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 select list not initialize default value

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()">

How can I use Variable expressions in AngularJS

In PHP I can use a double dollar sign to use a variable to represent another variable. If like to do the same in AngularJS expressions.
For example if I had an object with property1, property2 etc each with different values I would reference them directly as {{$scope.property1}}
What I would like to do is something like string propertyToDisplay = 'property1' and then use {{$scope.propertyToDisplay}} show the value stored in property1.
Does AngularJS support this?
This appears to be an XY problem. In general, the $scope variable shouldn't be appearing in your views at all, let alone that you seem to be trying to go outside the boundaries of what should be put in the markup for an AngularJS view.
In general, the parts of your controller that should appear in your view are (1) properties of the scope (or properties of properties, etc.) (2) functions that are part of the scope (with scope properties passed in as arguments). For anything involving dynamic functionality, you should generally be using the latter. So you could have your controller defined like this:
angular.module('myModule', [])
.controller('myController', ['$scope', function ($scope) {
$scope.properties = {
property1: "Hey!",
property2: "Hi"
};
$scope.selectedProperty = '';
$scope.getProperty = function (propertyName) {
return $scope.properties[propertyName];
};
}]);
And then your view could have something like this:
<select ng-model="selectedProperty">
<option value="property1">Property 1</option>
<option value="property2">Property 2</option>
</select>
<p>The value of the property you selected is: {{getProperty(selectedProperty)}}</p>
You can access variable object attribute using square brackets:
attrname ='attribute_name';
obj[attrname] = something;
How about using another object to store the visibility of each object property (DEMO).
$scope.visible = {};
$scope.person = {
first_name: 'John',
last_name: 'Rambo',
city: 'Hollywood'
};
Create a list with checkboxes for each property:
<div ng-repeat="(key, value) in person">
<input id="{{key}}Check" type="checkbox" ng-model="visible[key]">
<label for="{{key}}Check">{{key}}</label>
</div>
And check the visibility of each property in the form:
<input type="text" ng-model="person.first_name" ng-show="visible['first_name']">
If you want the form to be dynamic too (only input fields in this case) you can of course put this in a ng-repeat too:
<input ng-repeat="(key, value) in person" type="text" ng-model="person[key]" ng-show="visible[key]">
Hope this is at least close to what you want.

Resources