AngularJS ng-repeat default value does not work - angularjs

I am working with AngularJS and I am so new in that.
My aim is fill a tag SELECT with OPTION element from a datasource.
That is what I do basically:
<script>
function LocalizationController($scope, $http) {
$scope.Regions = [
{ ID: "001", DESC: "DESC_1" },
{ ID: "002", DESC: "DESC_2" },
{ ID: "003", DESC: "DESC_3" },
{ ID: "004", DESC: "DESC_4" },
];
$scope.Region = "003";
$scope.init = function () {
$scope.Region = "003";
}
}
</script>
<div ng-controller="LocalizationController" ng-init="init();">
<input type="button" ng-click="Region='002'" value="test">
<select id="region" name="RegionCode" ng-model="Region">
<option ng-repeat="item in Regions" value="{{item.ID}}">{{item.DESC}}</option>
</select>
</div>
Everything works good, the Select is fill of my items,
but I would like to set default value.
How you can see
- I set my object model which is ng-model="Region"
- I set its default value into init() function by $scope.Region = "003";
when the SELECT is loaded I do not why but dafault value is the first one "001"
I also tried to change value manually by
in that case the SELECT gets the right value selection.
Anyone can explain why it does not work?
I know that is a common problem, I am already looked for that,
any solution suggestion to use NG-OPTION, that directive works good,
it can fill my SELECT with my array of object, it can select default value,
very nice but it does not solve my problem because the value into the
the option element id an integer autoincrement which is not what I want.
so in summary:
NG-REPEAT can render the SELECT how I want but default value does not work
NG-OPTIONS can render the SELECT how I want, default value works but the value into option
item cannot be set how I want.
any suggestions?
thanks in advance
EDIT
I found a "solution"
<div ng-controller="LocalizationController" EXCLUDE-ng-init="init();">
<select id="region" onload="alert();angular.element(this).scope().Region='002'" name="RegionCode" ng-model="Region">
<option ng-repeat="item in Regions" value="{{item.ID}}">{{item.DESC}}</option>
{{init();}}
</select>
</div>
I do not like so much but works pretty good:
- ng-init="init();" does not work good
- If we exclude the initialize of default value into ng-init so EXCLUDE-ng-init="init();" and put the initilize when option are loded it works
Have a look at the code blow, I put {{init();}} after ng-repeat. Everithing works good
{{item.DESC}}
{{init();}}
I do not think is the best solution but Works,
1) I have a droopdown fill of my elements
2) The value of option into my list is CORRECT, "001", "002" and not a stupid autoincremental value which is useless.
I hope that can help someone...
THANKS TO EVERYONE TRIED TO HELP ME

Just use ng-options
<select id="region" name="RegionCode" ng-model="Region" ng-options="option.ID as option.DESC for option in Regions">
And do
$scope.init = function () {
$scope.Region = $scope.Regions[2];
}
When you inspect the select box while using ng-options the values for the options will be like 0,1,2,3.., that is auto increment integer as you said. But don't worry about that. Its the value just for showing up there, but once you post your form you will get the right value as you possess, in your case ID.

use ng-options
and in this case if you play with object (not single values) it should be so
$scope.init = function () {
$scope.Region = $scope.Regions[2];
}

Related

How to bind a list of checkboxes in AngularJS

I have a list of checkboxes as following :
<div flex="50" ng-repeat="formationType in formationTypeList">
<md-checkbox class="md-warn md-align-top-left"
value="{{formationType.codeFormation}}"
name="formationSelection[]"
ng-checked="formationSelection.indexOf(formationType) > -1"
ng-click="toggleFormationTypeSelection(formationType)">
{{ formationType.nom }}
</md-checkbox>
</div>
This is the format of formationSelection after I send my form :
formationSelection = [
{
codeFormation: 1,
nom: "ENSA"
},
{
codeFormation: 2,
nom: "CPGE"
}
]
In another scenario I want when I open my form to check the checkboxes which are defined in an array as following :
$scope.formationSelection = res.candidatureProjetProfessionnel.formations;
the object res.candidatureProjetProfessionnel.formations contains this :
formationSelection = [
{
codeFormation: 1,
nom: "ENSA"
},
{
codeFormation: 2,
nom: "CPGE"
}
]
And when I inspect $scope.formationSelection it contains the data I got from res.candidatureProjetProfessionnel.formations :
But I don't know why my checkboxes are not checked even though the $scope.formationSelection is not empty.
How can I solve this ?
i'm not sure what the md-checkbox directive is so i'm just going to use a normal checkbox input. Generally speaking, setting a default value for inputs in angular involves 2 things:
Make sure your inputs have ng-model to store the value of the checkbox and for 2 way data binding (so that you can set it from the controller as well)
In your controller set the variable declared in the ng-model to whatever default value you want.
So in you html:
<input type="checkbox" class="md-warn md-align-top-left" ng-
model="formationSelection[$index]" ng-true-value="{{formationType}}"
name="formationSelection[]">
Make sure you use ng-true-value to declare the value of each checkbox when checked. The ng-model is set to formationSelection[$index] which basically means each checkbox is an item inside the formationSelection array, this way the array will be the collection of the values of all checked inputs.
Now $scope.formationSelection = res.candidatureProjetProfessionnel.formations should work
Here's a working plunker:
http://plnkr.co/edit/sGm39DRWH9EOReiiSrIl?p=preview
You have to use ng-model as shown below.It should be an object like $scope.data = {};.This is just an example where hope you can get the point and work on your scenario. Actually you're having individual check boxes as shown below but values are being set through the loop.So you can apply this concept for your use case as well.Hope this will help to you.
Html
<md-checkbox ng-model="data.cb1" aria-label="Checkbox 1">
Checkbox 1: {{ data.cb1 }}
</md-checkbox>
JS
$scope.data = {};
$scope.data.cb1 = true;
Play with it on Codepen
I think that your method isFormation(formationType) on the directive ng-checked it's not return the result.
In your controller create a function
$scope.isFormation(_type){
return $scope.formationSelection.filter(function(f){return f.nom === _type;}).length > 0;
}

Null model in select in Angular template

I have a databound <select> element in an angular app. To bind it I am using:
<select id="AllKeyValuePairsInput" size="4" style="width:500px; height: 175px;" ng-options='item.key as (item.key + ": " + item.value) for item in data.availableOptions' ng-model="selected">
</select>
In my controller I have the following code, that according to the Angular documentation should remove that initial dirty model:
$scope.selected = $scope.data.availableOptions[0];
But I still see an empty entry appearing first in the select. I have it up and running in JSFiddle at https://jsfiddle.net/alchiggs/d12tdapv/
I'd be most grateful if anyone could point me in the right direction. One last point, it's the first bit of Angular I've ever written, so please don't hate me!!!! ;-)
This is how loadInitialData should look, note the change in the default value:
$scope.loadInitialData = function() {
var initialData = [{"key":"Maximum length","value":"200mm"},{"key":"Maximum width","value":"5000mm"}]
angular.forEach(initialData, function(object, index) {
$scope.keyValuePairs.push({ key: object.key, value: object.value});
});
$scope.selected = $scope.keyValuePairs[0].key; // THIS IS THE CHANGE I MADE
}
I've set the default value using the key property and not the element itself because your ngOptions define that the value of each option is item.key

Angular model and select not working

I've been having an issue for a day or two trying to get a select element working with my angular model.
I have a driving log, and one of the fields is truck. The value should be the truck id, which is received and sent from/to an API.
I've tried a couple methods, using ng-repeat to generate options, as well as using ng-options. The problem I ran into with the ng-repeat method was that I wasn't able to set the selected item, even with a lot of tinkering and doing things that shouldn't have to be done, and bad practice.
The second method I believe is the correct one, and it's using ng-options.
<select ng-model="timeLog.truck" convert-to-number
ng-options="truck.description for truck in trucks track by truck.id">
<option value="">Choose Truck</option>
</select>
.controller('EditTimeLogCtrl', function($scope, $stateParams, $location, timeLog, LogEntry, localStorageService) {
// edit an individual time log
$scope.timeLog = timeLog;
$scope.trucks = localStorageService.get('trucks');
$scope.saveTimeLog = function() {
LogEntry.update($scope.timeLog, function(data) {
$location.path('/tab/logs/edit');
});
}
})
Everything else in my timeLog model works, and the value in the model is an integer.
For some reason, I can't get the initial value to set correctly even though the docs specify to use this to set a default value.
The other issue I have when using ng-options is that when I submit the form, it uses the truck object {"description": "big red", "id": 7, ... } instead of the value of the option, which would just be 7. The API is expecting the id, so that does not work.
I've found 3 stackoverflow articles about that, and they all give various answers which don't really solve the problem.
This seems like a very common use case, maybe I'm thinking about it the wrong way? I just have a model which has a dropdown/select field and I need that to populate to what the selected value is if the model already exists (i.e. edit form), and pass the id value in the model save.
Your ngOptions syntax is a bit off - it's value as text for obj in arr - so change yours to:
ng-options="truck.id as truck.description for truck in trucks track by truck.id"
And then set your model to the id of the object you want selected:
$scope.timeLog.truck = 7; //truck id 7 selected.
If you want the whole object as the value:
ng-options="truck as truck.description for truck in trucks track by truck.id"
And set the whole object:
$scope.timeLog.truck = $scope.trucks[0];
Make sure your timeLog.truck IS (===) the actual object in the trucks array (same referenced object)
angular
.module('app', [])
.controller('myController', myController);
function myController($scope) {
$scope.trucks = [{
"description": "big red",
"id": 7
}, {
"description": "big yellow",
"id": 6
}];
$scope.timeLog = {truck: $scope.trucks[0]};
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.10.1/lodash.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.8/angular.js"></script>
<div ng-app="app">
<div ng-controller="myController">
<select ng-model="timeLog.truck" ng-options="truck.description for truck in trucks">
<option value="">Choose Truck</option>
</select>
</div>
</div>

How to dynamically change values in drop down using other drop down change using angular?

I have two drop downs. Initially both has values like "First","Second","Third",...
When 1st dropdown has value "First" the second should not offer a value "First" that is second should have other than what is selected from 1st one. I want to do this using angularjs. Values in 2nd dropdown should be changed dynamically.
<select class="form-control" ng-model="Data.firstType">
<option>First</option>
<option>Second</option>
<option>Third</option>
</select>
<select class="form-control" ng-model="Data.SecondType">
<option>First</option>
<option>Second</option>
<option>Third</option>
</select>
Can anyone help on this?
Thanks in advance.
If you're items in the drop downs are static you can do this fiddle
ng-if="Data.FirstType !== First"
If they are dynamic then you can filter the items in the second list based upon the item selected in the first drop down
Here is a fiddle to dynamically filter the second list if the lists are being populated dynamically.
function MyCtrl($scope){
$scope.Data = {};
$scope.items = [{id:1, name:'First'}, {id:2, name:'Second'}, {id:3, name:'Third'}];
$scope.exclude = function(x){
return x !== $scope.Data.firstType;
}
}
Just use a $watch:
$scope.$watch('Data.firstType', function(val) {
//Get index of type in Data.yourArrayData
var idx = $scope.Data.yourArrayData.indexOf(val);
$scope.Data.yourArrayData.splice(idx, 1);
});
This assumes you are binding your second select to yourArrayData using an ng-repeat. I haven't tested this code, but it should be what you need.

How to trigger binding of select based on the changed value in another select?

Let's say that I have list of countries and each country has a list of states/regions. So there are two selects. First to select country, and when country changes I want to trigger binding of the states select. How do you link these two controls to trigger binding of the states select when country changes?
<select id="countries"
data-ng-model="vm.permanentAddress.countryCode"
data-ng-options="country.code for country in vm.form.countries">
</select>
<select data-ng-model="vm.permanentAddress.stateCode"
data-ng-options="state.value for state in vm.getStatesForCountry(vm.permamentAddress.countryCode)">
</select>
UPDATE:
I was probably not explicit in my question as to what I want to do. I do not want to create any new properties that are then watched by angular for a change. I just want to tell anuglar, hey something has changed, go ahead and re-evaluate the binding for this control.
Is it not possible?
In your controller have something like this:
$scope.setStateOptions = function(country){
$scope.stateOptions = /* whatever code you use to get the states */
}
Then your html can be:
<select id="countries"
data-ng-model="vm.permanentAddress.countryCode"
data-ng-options="country.code for country in vm.form.countries"
data-ng-change="setStateOptions(country)">
</select>
<select
data-ng-model="vm.permanentAddress.stateCode"
data-ng-options="state.value for state in stateOptions">
</select>
May be you should use the jquery chanied select plugin:
http://jquery-plugins.net/chained-selects-jquery-plugin
I have used it for 4 select list chained and it worked fine.
Thx
Here is a working example. You just need to use the ng-change to change the model you have set for the states
You can take advantage of the dynamic nature of JavaScript to bind the key from the first list to the second list. Then you only have to set a default value on the change. If you remove the $watch it will still work, the second select will just default to empty when you switch the category.
Here's my data set-up and watch:
app.controller("myController", ['$scope', function($scope) {
$scope.data = ['shapes', 'colors', 'sizes'];
$scope.data.shapes = ['square', 'circle', 'ellipse'];
$scope.data.colors = ['red', 'green', 'blue'];
$scope.data.sizes = ['small', 'medium', 'large'];
$scope.category = 'colors';
$scope.$watch('category', function () {
$scope.item = $scope.data[$scope.category][0];
});
And here's the HTML:
<div ng-app="myApp" ng-controller="myController">
<select id="categories"
data-ng-model="category"
data-ng-options="category for category in data"></select>
<select id="item"
data-ng-model="item"
data-ng-options="item for item in data[category]"></select>
{{category}}: {{item}}</div>
You can, of course, change this to host complex objects and use keys or other identifiers to switch between the lists. The full fiddle is here: http://jsfiddle.net/jeremylikness/8QDNv/

Resources