Angular Js ng-change function runs on load - angularjs

I have Select box on which i have called a function on ng-change, but don't know why it run when page load. I don't want that function to call on load. I think it is not basic behaviour of ng-change.
<select class="form-control" name="state" id="state_id" ng-model="form.state" ng-change="getStateList(form.state)">
<option value="">Select State</option>
<option ng-repeat="states in state" value="{{states.state_id}}" ng-selected="states.state_id == form.state_id"> {{states.name}} </option>
</select>
and in controller i have function as
$scope.getStateList = function(id) {
$http.post('/statelist',{id:id}).then(function success(response) {
$scope.state = response.data.state;
});
}
and i load $scope.city on load on different call. but when i load page both the functions get called as $scope.getStateList should be call on chnage in select box. Whats wrong ?
and one more problem is ng-select is not working too.

Change ng-model="states.state_id" ng-change="getStateList(states.state_id)" u want pass state id in ng-change event use this and try ..other wise u send whole scope values means send scope where u decalre in ng-repeat

Related

Angular ng-model in `<select>` change function find dynamically

Using Angular 1.x I have two groups of select boxes, both call a function on change:
ng-click="checkOneOptionSelected()"
In my controller I would like to know which group of select boxes called the function:
$scope.checkOneOptionSelected = function(value){
.. do something...
}
Is there a way to get the value of ng-model dynamically without passing a string as a parameter, perhaps using 'this' or similar. HArdcoding the value as a param will work but feels hacky?
When using the ng-model directive, the code should use the ng-change directive instead of ng-click.
<select ng-model="$ctrl.sel1" ng-change="$ctrl.updateSel('sel1',$ctrl.sel1)"
ng-options="...">
<option value="">Select sel1</option>
</select>
<select ng-model="$ctrl.sel2" ng-change="$ctrl.updateSel('sel2',$ctrl.sel2)"
ng-options="...">
<option value="">Select sel2</option>
</select>
To share the same update function, simply add arguments to indicate the source of the change.
this.updateSel = function (id, val) {
console.log(id,val);
//...
};
The ng-click directive fights with the ngModelController. The ng-change directive uses the $viewChangeListeners property of the ngModelController. The ngChange expression is only evaluated when a change in the input value causes a new value to be committed to the model.
For more information, see
AngularJS ng-change Directive API Reference.
You may pass builtin $event object (mentioned in ng-click reference in arguments), which is iQuery event object.
ng-click="checkOneOptionSelected($event)"
Then use its target field to reason about what was clicked:
$scope.checkOneOptionSelected = function(event){
.. do something with event.target, e.g...
if(event.target.id == 'Option123') {
...
}
}

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

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

AngularJS : How to trigger an action on select option?

I am new in Angular. I try to print a form. In the form i have a select input. I dont know how to do an action when the user select an option. I want to retrieve datas from server when the select option is made. I just need an example please.
Although this is an old question I would like to add Sunils comment as an actual answer as it is much simpler than doing a custom directive. If you want to trigger some function when the user selects another option, just use ng-change on the select tag.
In Controller-as Syntax it would look like this.
Note that it is important to have ng-model in there even if you wouldn't need it somewhere else as ng-change is watching out for "yourModel" if I understood the documentation correctly.
<div ng-controller="yourController as controllerName">
[...]
<select ng-model="yourModel" ng-change="controllerName.yourFunction(yourArguments)">
Your options here (or use ng-options on the select tag)
</select>
[...]
</div>
In the controller you then define what is supposed to happen:
this.yourFunction = function(yourArguments){
//do your things here, e.g. http request
}
You Can write a directive like this :
yourApp.directive('changed',function(){
return function(scope,elem,att){
elem.bind('change',function(){
alert('hi');
})
}
});
And then you can use it in your view like this :
Your SELCET TAG here :
<select changed>
<option value="1">1</option>
<option value="2">2</option>
</select>
Also if you want to pass anything from the select to your directive you can do this :
<select changed="passthis">
<option value="1">1</option>
<option value="2">2</option>
</select>
And then in your directive you can get what ever you've sent:
yourApp.directive('changed',function(){
return function(scope,elem,att){
elem.bind('change',function(){
// below will alert: "passthis"
alert(att.changed);
// bellow will alert what ever option user has choosed
alert(elem.value());
})
}
});
You want to run a $http request on selection changed ? easy :
yourApp.directive('changed',function($http){//notice here I injected $http
return function(scope,elem,att){
elem.bind('change',function(){
$http.post('YourUrl',{yourDataTosend})
.success(function(msg){
alert("msg from your backend: ",msg)
}).error(function(){
alert('Error');
})
})
}
});

Resources