Check all boxes toggle method not working like expected - angularjs

I'm wiriting a method to toggle a checklist as checked / unchecked, as follow:
$scope.checkAllToggle = function(dtProvider, destiny, ev) {
$(ev.currentTarget).parent().find('span').html());
data[destiny] = [];
if ($(ev.currentTarget).parent().find('span').html()=='Check all') {
for (var val in data[dtProvider]) data[destiny].push(data[dtProvider][val].id);
$(ev.currentTarget).parent().find('span').html('Uncheck all');
}
else $(ev.currentTarget).parent().find('span').html('Check all');
}
The label of the toggle button changes every time, but the state of the checkboxs only becomes checked after 2 click, from this point change in each 3 clicks.
What's wrong?
Append
if(!$scope.$$phase) $scope.$apply();
to the method make no difference, as prepending $scope to data
Code in plunker: http://plnkr.co/edit/Zf6UzLbC4osRov7IR5Na?p=preview

Rather than do it that way, this would be the easier way to do it.
Make the master input and assign it to a model.
<input type="checkbox" ng-model="master">
Then have your other inputs be tied to the master like this.
<input type="checkbox" ng-model="box1" ng-checked="master">
<input type="checkbox" ng-model="box2" ng-checked="master">
<input type="checkbox" ng-model="box3" ng-checked="master">
Here is your plunker with these changes.
Master Checkbox Plunker

I got your plunker to work by doing this.
$scope.checkToggle = function(dtProvider, destiny, ev) {
$scope.data[destiny] = [];
if ($(ev.currentTarget).parent().find('span').html() == 'Check all') {
for (var val in $scope.data[dtProvider]){
$scope.data[destiny].push($scope.data[dtProvider][val].id);
$(ev.currentTarget).parent().find('span').html('Uncheck all');
}
} else {
$(ev.currentTarget).parent().find('span').html('Check all');
}
$scope.$apply();
};
I could not get it to work if calling safely like if(!$scope.$$phase){$scope.$apply();} but it is working with straight $scope.$apply(). This might have something to do with rootScope and need to be safetly called in a different manner.
See this link: https://coderwall.com/p/ngisma
You also had some missing {} in your code that could have been causing some issues.

Related

Input text change checkbox model only once [AngularJS]

I have this
<input type="text" ng-click"function1()">
And this:
<input type="checkbox" ng-change="function2()" ng-model="stateCheck">
The functions do this:
$scope.function1 = function(){
$scope.stateCheck = false;
}
$scope.function2 = function(){
$scope.stateCheck = !$scope.stateCheck;
}
But the function1 just works the first time. Does anyone know why? Thanks.
ng-change="function2()"
ng-model="stateCheck"
These two events are conflicting with each other, Basically ng-model makes the $state.stateCheck=true and then functin2() $state.stateCheck=!$state.stateCheck makes it false. Due to this checkbox will always remain unchecked. function1() works fine

using angularjs checkbox is not updating after ajax call

I have this checkbox
<input type="checkbox"
ng-change="defaultMsgsHandler(vuser.use_managed_default_msgs)"
ng-model="vuser.use_managed_default_msgs"
ng-true-value=1 ng-false-value=0>
When i make this ajax call, the checkbox does not reflect the ajax retured has vuser.use_managed_default_msgs set to 1, but the checkbox is not checked. I know the model is correct. vuser.use_managed_default_msgs is a 1 if i dump vuser to the console.
messageServices.getMessageSettingsInfo(user.dir)
.then(function(data) {
if (!data.success) {
$scope.errormessage = data.errors;
} else {
$scope.vuser = data.vuser;
$scope.messages = data.messages;
}
}, function(error) {
alert(error);
});
If i click on the checkbox defaultMsgsHandler changed the model correctly, and the checkbox checks and unchecks.
$scope.defaultMsgsHandler = function( use_managed_default_msgs ){
$scope.vuser.use_managed_default_msgs = use_managed_default_msgs;
};
Thanks for any help
Please, try to use: ng-checked="condition"
There is a similar question here,
How to set checkbox selected on the basis of model value
Not sure if it will help, but I think your
ng-true-value=1 ng-false-value=0
should be
ng-true-value="1" ng-false-value="0"

ngChecked doesn't seem to want to bind to the model. Why?

I'm using Ionic and thus angularjs, and I'm trying to store a setting in localStorage.
I've a checkbox that I want to use to set analytics on or off. The html looks like this.
Analytics on/off
<label class="toggle toggle-balanced">
<input type="checkbox" ng-click="toggleAnalytics()" ng-checked="analytics">
<div class="track">
<div class="handle"></div>
</div>
</label>
and in the related controller I have:
$scope.analytics = $localstorage.get('analyticsOnOff');
$log.log("Analytics initialised at", $scope.analytics);
$scope.toggleAnalytics = function(){
if($scope.analytics===true){
$scope.analytics = false;
$localstorage.set('analyticsOnOff', false);
}else{
$scope.analytics = true;
$localstorage.set('analyticsOnOff', true);
}
$log.log("Analytics is ", $scope.analytics);
}
So as you can see, when you change the checkbox the toggleAnalytics() function toggles $scope.analytics between true and false and updates the localstorage to reflect that.
Note that I am using $localstorage methods. $localstorage is defined in another service. It's allows you to set and get localStorage objects easily.
Anyway, my issue is a really simple, but baffling one. I know I can alter the analytics value from the console logs, but no matter what I do the checkbox initialises as on.
Any ideas?
You should be using ng-model on your checkbox, this will handle setting the actual property - and you can use a change event then:
<input type="checkbox" ng-change="toggleAnalytics(analytics)" ng-model="analytics" />
And the controller:
$scope.toggleAnalytics = function(isChecked) {
$localstorage.set('analyticsOnOff', isChecked);
$log.log("Analytics is ", isChecked);
}
Thank you very much for the feedback guys.
#nickgraef for altering me to the real problem - that .get() returns a string.
#tymeJV for supplying me with a much more elegant version of my own code.
This is what I did in the end, it's a mash up of both tips. I convert the analytics variable into a boolean straight after I .get() it from localstorage.
$scope.analytics = $localstorage.get('analyticsOnOff');
$scope.analytics = ($scope.analytics == 'true' ? true : false);
$log.log("Analytics initialised at", $scope.analytics);
$scope.toggleAnalytics = function(isChecked) {
$localstorage.set('analyticsOnOff', isChecked);
$log.log("Analytics is ", isChecked);
}

how to stop bind in angularjs

I hava a checkbox ,the model status.useJoin also bind the div.
<input type="checkbox" ng-model="status.useJoin" ng-click="toggleJoin($event);" >
<div ng-if="status.useJoin"> show area</div>
when status.useJoin is true ,will show div.
My question is ,when I want to prevent the default action of the checkbox. I will write function toggleJoin like this.
$scope.toggleJoin = function (dimension,$event) {
if (status.useJoin) {
$event.preventDefault();
return;
}
}
the checkbox action is stopped ,but status.useJoin is still modified. How can I stop the bind?
You can use ng-disabled directive
<input type="checkbox" ng-model="status.useJoin" ng-disabled="onYourDisableCondition();" >
$scope. onYourDisableCondition = function () {
if (status.useJoin) { //Add your additional conditions
return true;
}
}

unable to get ng-checked property for a radio button to check the button when populating a form

EDIT: for those of you who don't want to go through the code, I'm basically passing the form a "node" object with node.selectedAnswer = "4,1,4" or some string like that. The form has radio buttons and one of the buttons has a value "4,1,4". the radio button also has ng-checked="node.selectedAnswer" expression. But that doesn't work. I know for sure that node.selectedAnswer has the appropriate value.
I have a series of radio button questions that I'm asking the user. I want them to be able to go previous and next. I'm using a stack to store the data retrieved from ajax call, as well as selectedAnswer when they select an option and click next. I've commented the code itself to explain the situation where I can. Everything seems to be working, except ng-checked is just not picking up node.selectedAnswer, even though I can output {{node.selectedAnswer}} properly to the page.
<div class="container-fluid" ng-app="AccountRequest" ng-controller="GameNode" ng-init="outside={}">
<div class="row-fluid">
<div class="span2"></div>
<div class="span10">
<form>
<!-- node.selectedAnswer displays the selectedAnswer correctly when clicking previous and going back.
However, ng-checked is somehow not selecting the appropriate radio button. -->
<span>{{node.Question.Text}} selected answer: {{node.selectedAnswer}}</span>
<div class="radio" ng-repeat="answer in node.Answers">
<input type="radio" id="answerGroup" name="answerGroup" ng-checked="node.selectedAnswer" ng-model="outside.selectedAnswer"
value="{{answer.BranchId}},{{node.LeafId}},{{answer.Id}}"/> {{answer.Text}}
</div>
<div>
<input type="button" ng-click="previous()" value="Previous"/>
<input type="button" ng-click="next(outside.selectedAnswer)" value="Next"/>
</div>
</form>
</div>
</div>
</div>
//below is the script
app.controller('GameNode', function ($scope, $http) {
var nodes = [];
function load(branchId, leafId, answerId) {
$http.get("/AccountRequest/GetNode?branchId=" + branchId +
"&leafId=" + leafId +
"&answerId=" + answerId)
.success(function (data) {
//get data and push it in the stack
nodes.push(data);
$scope.node = data;
});
}
function populateValues(selectedAnswer) {
var answer = null;
if (selectedAnswer === undefined || selectedAnswer == null)
selectedAnswer = "0,0,0";
//when next is clicked, retrieve the selectedAnswer from form and store it in current node as a property.
if (nodes.length > 0) {
var curNode = nodes.pop();
curNode.selectedAnswer = selectedAnswer;
nodes.push(curNode);
}
answer = selectedAnswer.split(',');
if (answer != null) {
load(answer[0], answer[1], answer[2]);
}
}
$scope.next = populateValues;
$scope.previous = function () {
//when previous is clicked, pop the current node out and throw it away.
//then pop the previous node out, read it, and push it back in as current node.
if (nodes.length > 1) {
nodes.pop();
var prevNode = nodes.pop();
nodes.push(prevNode);
$scope.node = prevNode;
}
};
populateValues();
});
Older Answer - This works, (was marked correct) but using $parent can get a bit messy in nested repeats.
In this instance, you don't need to use ng-checked at all. Since this is a radio group, the checked attribute will be bound to the model. If the model is bound to the value of an individual radio button, then your ability to change which button is "checked" becomes very simple.
Here is a plunk that demonstrates the concept.
So in your case a few changes need to be made.
1. Get rid of 'id' attribute - the ID must be unique for each element.
2. Each item created in an ng-repeat creates its own child scope. So to access the original model, "$parent" must be invoked.
<input type="radio" name="answerGroup" ng-model="$parent.someAnswerAttribute"
value="{{answer.BranchId}},{{node.LeafId}},{{answer.Id}}"/>
In your controller define the model as you already did, then modify it to be tied to a value of a button, which in your case will be a bit lengthy, since you have multiple attributes within your value.
$scope.someAnswerAttribute = // exactly what the value of a radio button would be.
Again, the plunker above reflects this concept. Hope this helps!
..
..
Edit - Better Answer:
Since the ng-repeat creates its own child scope, and two-way binding is necessary, the ng-model should be referencing an object instead of a primitive. In other words, if the model was $scope.myModel="Biff", the child scope can not access that without invoking $parent (in the answer below). However, if the model is referencing a property of an object, the child will receive prototype inheritance of that object. (I think I said that right).
So using the older answer example, we can change:
From this in the parent controller:
$scope.someAnswerAttribute = "Biff";
To this in the parent controller:
$scope.someAnswerAttribute = {value: "Biff"}
And in the radio group:
<input type="radio" name="answerGroup" ng-model="someAnswerAttribue.value"
value="{{answer.BranchId}},{{node.LeafId}},{{answer.Id}}"/>
This plunk is forked from the older answer and demonstrates model as an object property.

Resources