ng-click with ng-checked not updating checkbox state - javascript

small question (possible a logic err), I am trying to get the checkbox to update itself automatically after clicking it and in the same time using the rest api to PUT the changes in DB, and the PUT mothod works, it updates the DB but it`s not updating the checkbox state itself only if I refresh the page, the checkbox will update.
And I have this simple code:
<input type="checkbox" ng-checked="action.state" ng-click="setState($event, key, action)"><div class="track"><div class="handle"></div></div>
and back-end as this:
.controller('Actions', function ($scope, $filter, $resource, $ionicActionSheet, $ionicModal) {
var actionListResource = $resource('/api/actions/');
actionListResource.query(function (data) {
$scope.actions = data;
});
$scope.setState = function (event, index, action) {
if (action.widget === 'toggle' && action.state === 1) {
action.state = 0;
}
else {
action.state = 1;
}
event.preventDefault();
var actionsResource = $resource('/api/actions/:actionId/', {actionId:'#id'}, {
'update': {
method: 'PUT'
}
});
};
...more code here
})
action.state is always a 1 or 0 value, I've checked the $scope.actions[index].state and it`s updating itself when I click the checkbox.
Thank you!

<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<body ng-app="myApp">
<div ng-controller="myCtrl">
<input type="checkbox" ng-model="action" ng-click="setState()">
</div>
<script>
angular.module('myApp', [])
.controller('myCtrl', ['$scope', function($scope) {
$scope.setState = function() {
window.alert($scope.action);
// $scope.action value will be true or false
};
}]);
</script>
</body>
</html>

Try ng-model instead of ng-checked. The toggle stuff looks unecessary. ng-change could also be used to trigger the request.
In their docs they solve exactly the problem you describe.
https://docs.angularjs.org/api/ng/directive/ngChange

Related

Angular filter: how to get filter complete callback?

I am looking for an callback function after $filter filter completes the filtering the data
HTML
<input type="text" ng-model="searchvalue">
<span ng-click="searchbtn()">Search</span>
JS
$scope.searchbtn = function() {
$scope.loading = true;
$scope.mysearchvalue = $scope.searchvalue;
}
When user enters keyword my data will be filtered and i need a callback function after filtering the data.
i have tried using "DOMSubtreeModified" but returning continues logs
var myElement = angular.element(document.getElementById("mycontent"));
myElement.bind("DOMSubtreeModified", function() {
console.log("keep outputting this message");
});
As said in my comment, why not just use a little delay (debounce) and filter results in controller w/o separate input button. Consider
HTML template
<body ng-controller="MainCtrl">
<pre ng-bind="filteredData | json"></pre>
<input type="text" ng-model="search" ng-model-options="{debounce:250}">
</body>
JavaScript
angular.module('app', [])
.controller('MainCtrl', function($scope, $filter) {
$scope.data = [{text:'aa'},{text:'ab'}];
$scope.$watch('search', function(val) {
$scope.filteredData = $filter('filter')($scope.data, val);
});
});

How to display the tick in items checked in the checkbox after reload?

I am trying to save the checked items in the checkbox and display them. I can store them locally and display. However the tick is not stored. Every time i reload the page the checked item that is stored is displayed but the tick is missing. Any idea on how to also store the tick in checked items and display them in the checkbox?
jsfiddle code I am currently trying is : https://jsfiddle.net/bhgmw7ey/
the html code is
'
<div ng-repeat="chip in colores" >
<input type="checkbox" name="{{chip.codigo}}" id="{{chip.codigo}}" ng-model="chip.checked" ng-change="chipsColores()" ng-click="$storage.a = fav">
<label>{{chip.codigo}}</label>
</div>
<div ng-repeat="favorite in $storage.a">
localStorage: {{favorite.codigo}}
</div>
</div>
'
the javascript code is
(function() { angular.module('myApp',['ngStorage']) .controller('favCtrl',[ '$scope', '$filter', '$localStorage', function ( $scope, $filter, $localStorage) {
$scope.colores = [
{'nombre':'blue', 'codigo':'1111'},
{'nombre':'green', 'codigo':'2222'},
{'nombre':'red', 'codigo':'3333'} ];
$scope.chipsColores = function () {
$scope.fav = $filter('filter')($scope.colores, {checked: true});} $scope.$storage = $localStorage.$default({ });}])})();'
your ngStorage is not properly used referring to the official wiki of this library https://github.com/gsklee/ngStorage.
Following the get started guide u should implement the localstorage by bind it to a scope variable so that it can watch and update the variables in localstorage for u.
For ur case it should look like
<div ng-app="myApp">
<div ng-controller="favCtrl">
<div ng-repeat="chip in $storage.colores" >
<input type="checkbox" name="{{chip.codigo}}" id="{{chip.codigo}}" ng-model="chip.checked" ng-change="chipsColores()" >
<label>{{chip.codigo}}</label>
</div>
<div ng-repeat="favorite in $storage.colores">
localStorage: {{favorite.codigo}}
</div>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ngStorage/0.3.6/ngStorage.min.js"></script>
And JS:
angular.module('myApp',['ngStorage'])
.controller('favCtrl',[ '$scope', '$filter', '$localStorage', function ( $scope, $filter, $localStorage) {
$scope.chipsColores = function () {
$scope.fav = $filter('filter')($scope.$storage.colores, {checked: true});
}
//move the 'colores' into storage
$scope.$storage = $localStorage.$default({
colores : [
{'nombre':'blue', 'codigo':'1111'},
{'nombre':'green', 'codigo':'2222'},
{'nombre':'red', 'codigo':'3333'}
]
});
}])

Accessing ng-hide value of one controller to manipulate ng-style of another controller within a global controller

So I am trying to access the boolean value of ng-hide from one controller to change css properties of another controller using a global controller. Here is the link on jsfiddle: https://jsfiddle.net/dqmtLxnt/
HTML
<div ng-controller="mainCtrl">
<div class="first" ng-style="changeColor" ng-controller="firstCtrl">
{{ accessOne }}
</div>
<div class="second" ng-hide="hideSecond" ng-controller="secondCtrl">
{{ accessTwo }}
</div>
</div>
JS
angular.element(document).ready(function() {
angular.module('app', [])
.controller('mainCtrl', ['$scope', function($scope) {
if ($scope.hideSecond == true) {
$scope.changeColor = {
'color': 'blue'
};
}
}]).controller('firstCtrl', ['$scope', function($scope) {
$scope.accessOne = "One";
}]).controller('secondCtrl', ['$scope', function($scope) {
$scope.accessTwo = "Two";
$scope.hideSecond = true;
}]);
angular.bootstrap(document.body, ['app']);
});
I am able to change both changeColor and hideSecond from mainCtrl but I'm not able to access the value set from secondCtrl in the mainCtrl. I even tried setting hideSecond=true in ng-hide and access it on mainCtrl but to no avail.
Can someone help me on this?
You can use a Angular Service for this, storing the value into a service and than retrieving it from the service in another controller.
In your situation the main controller is loaded before the second controller so it would never know when the value is updated. You can use $watch for this, calling an update function when the $scope is updated.
Here if your fiddle updated: https://jsfiddle.net/dqmtLxnt/2/
Service:
angular.module('app.services', [])
.factory('hide', function() {
// Allows for passing of data between controllers
var x = false;
// Sets savedData to what ever is passed in
function set(data) {
x = data;
}
// Returns saved data
function get() {
return x;
}
return {
set: set,
get: get
}
})
Using it in Main Controller:
$scope.$watch(function () { return hide.get(); },
function (value) {
console.log(value);
$scope.update(value);
});
$scope.update = function(value) {
if (value == true) {
$scope.changeColor = {
'color': 'blue'
};
}
}
Using it in Second Controller:
$scope.hideSecond = true;
hide.set(true);
Make sure you inject the service into the app and the service into the controllers.

Submit form on page load in Angular

I would like to submit a search form on page load if search terms were specified in the route. The problem is that searchForm isn't defined yet when search() runs. I've seen others get this to work by putting ng-controller right on the form element, but I have multiple forms on this page, so the controller has to be a parent of the forms.
How can I ensure the form is defined when I call search()?
myModule.controller('MyController', ['$scope', '$routeParams',
function($scope, $routeParams){
$scope.model = {searchTerms: ""};
$scope.search = function(){
if($scope.searchForm.$valid){
...
}
};
if($routeParams.terms !=""){
$scope.model.searchTerms = $routeParams.terms;
$scope.search();
}
}]);
View:
<div ng-controller="MyController">
<form name="searchForm" ng-submit="search()">
...
</form>
<form name="detailForm" ng-submit="save()">
...
</form>
</div>
This seems to work:
$scope.$on('$routeChangeSuccess', function () {
if($routeParams.terms !=""){
$scope.model.searchTerms = $routeParams.terms;
$scope.search();
}
});
Have you tried just using $watch on searchForm?
if($routeParams.terms != "") {
var unregister = $scope.$watch(function() {
return $scope.searchForm;
}, function() {
// might want to wrap this an if-statement so you can wait until the proper change.
unregister(); //stop watching
$scope.model.searchTerms = $routeParams.terms;
$scope.search();
});
}

angularjs dynamically change model binding

I have 2 forms - a billing and a shipping. If the user checks a checkbox, the shipping address should be populated with the billing address and turn disabled. If the user unchecks the box, the shipping address should be blank and return to enabled.
I have this working right now with $watch but it feels hacky. I have 2 $watches nested in eachother watching the same element. I want to know if there is a better way to achieve what I am doing.
I tried using a ternary operator in the ng-model like below but that didn't work either.
<input ng-model="isSameAsBilling ? billName : shipName" ng-disabled="isSameAsBilling" />
A plunkr of my "working" code
HTML:
<input ng-model="billName" />
<input type="checkbox" ng-checked="isSameAsBilling" ng-click="sameAsBillingClicked()"/>
<input ng-model="shipName" ng-disabled="isSameAsBilling" />
JavaScript:
$scope.isSameAsBilling = false;
$scope.sameAsBillingClicked = function(){
$scope.isSameAsBilling = !$scope.isSameAsBilling;
};
$scope.$watch('isSameAsBilling', function(isSame){
if ($scope.isSameAsBilling) {
var shipNameWatcher = $scope.$watch('billName', function (newShipName) {
$scope.shipName = $scope.billName;
var secondBillWatcher = $scope.$watch('isSameAsBilling', function(isChecked){
if (!isChecked){
shipNameWatcher();
secondBillWatcher();
$scope.shipName = '';
}
});
});
}
});
I think I've finally got what you're after here.
When the checkbox is checked, it registers a $watch on the billName and mirrors it to the shipName.
When the checkbox is unchecked, the deregisters the $watch and clears the shipName
angular
.module('app', [])
.controller('appController', ['$scope', function($scope){
$scope.isSameAsBilling = false;
$scope.isSameChanged = function() {
if ($scope.isSameAsBilling) {
// register the watcher when checked
$scope.nameWatcher = $scope.$watch('billName', function(bName) {
$scope.shipName = bName
})
} else {
// deregister the watcher and clear the shipName when unchecked
$scope.nameWatcher();
$scope.shipName = ''
}
}
}]);
and here is the PLUNK

Categories

Resources