CheckBox not getting checked in Knockoutjs - checkbox

I am using a checkbox with a function inside the data-bind, but I am unable to check the checkbox.
view:
<input type="checkbox" data-bind="click: function(){ f('hello parameter'); }">Click me
View Model:
var VM = function () {
this.f = function (param) {
alert(param); // here i am getting 'hello parameter'
return true;
}
}
ko.applyBindings(new VM());
Here is my Fiddle

By default, the click binding prevents the default reaction to a click based on the assumption that your JavaScript click event handler will handle everything. You need to return "true" to get the default behavior anyway, which you are doing from your f() function but not the wrapper inside data-bind:
<input type="checkbox" data-bind="click: function() { f('hello parameter'); }">
should be
<input type="checkbox" data-bind="click: function() { return f('hello parameter'); }">

Without context around the code it's not clear how you intend to use this control. With a checkbox you would normally use the checked binding that is bound to a boolean observable:
The checked binding links a checkable form control — i.e., a checkbox () or a radio button () — with a property on your view model.
So another way of writing this using the checked binding would be:
Sample Code:
var VM = function () {
var self = this;
self.myCheck = ko.observable(false);
self.myCheck.subscribe(function () {
alert('checked value = ' + self.myCheck());
});
}
ko.applyBindings(new VM());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<div>
<input type="checkbox" data-bind="checked: myCheck" />
Click me
</div>
With this example, there's an observable that tracks the value of the checkbox: self.myCheck. So when the checkbox is checked/unchecked, self.myCheck() will be set to true/false.
In order to provide some output or run some code when the value is changed, I've subscribed to the observable, which basically means that every time the value of the observable is changed, the alert will be fired (or whatever code you place in there).
Demo On JS Fiddle

Related

Fire ng-change event for textbox other than keypress or keydown

I want to update a text value when the value is changed by using some method, the method should not call when I am still typing text but when exit from the textbox or change it through script code:
<input type="text" ng-model ="model.value" ng-change = "update()"/>
what should contain update() method,
what I tried is : wrote a directive for this textbox, and
scope.$watch('model', function(nval,oval){
if ((oVal === undefined) && (nVal != undefined)){
update()
}
});
It is calling for the first time, but not whenever the model value changed.
I want to call update method whenever the model.value changed, but not while entering text
You can use ng-blur and you should change your $watch:
JSFiddle
HTML:
<div ng-app="myApp" ng-controller="dummy">
<input type="text" ng-model="model.value" ng-blur="update()"/>
</div>
JS:
angular.module('myApp', [])
.controller('dummy', ['$scope', function ($scope) {
$scope.model = {
value: 'hello'
};
$scope.update = function () {
console.log("changed!");
};
$scope.$watch('model.value', function (nval, oval) {
if (oval !== nval) {
$scope.update();
}
});
}]);
You can use data-ng-model-options directly to achieve your requirement.
Like,
here you can get full reference of data-ng-nmodel-options
https://docs.angularjs.org/api/ng/directive/ngModelOptions
this directive will work for the versions angular 1.4.x ( from 1.4.x version it suppports)

How do I reverse a checkbox state to make it unchecked (AngularJS)?

I basically want that when the user clicks on a checkbox, their decision is immediately reversed and the checkbox is unchecked. The code below is not working. I tried other variations like value = !value instead of value = false and tried initializing another controller variable to be equal to the checkbox variable and changing the other controller variable. None of this works; basically, I cannot set the checkbox state unless the application is first being initialized.
HTML code:
<input type="checkbox" ng-model="avariabledefinedincontroller" ng-click="changemystate(avariabledefinedincontroller)">
Controller code:
$scope.avariabledefinedincontroller = false;
$scope.changemystate = function(value){
if (value == true) {
value = false;
}
else {
value = value;
}
};
The value passed into changemystate will be the value the checkbox has when it is clicked. So if you want it to stay at that value, you can set up a timeout to restore it to that value. No negation is needed.
Also, assigning a value to value will do nothing. You have to modify the scope variable. If you want to identify the scope variable for the item that was clicked, you can pass in a string:
function MyController($scope, $timeout) {
$scope.mybool = false;
$scope.changemystate = function(key) {
var value = $scope[key];
$timeout(function () {
$scope[key] = value;
}, 0);
};
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.10/angular.min.js"></script>
<div ng-app="" ng-controller="MyController">
<input type="checkbox" ng-model="mybool" ng-click="changemystate('mybool')" />
{{mybool}}
</div>
Actually, you don't need a function for that :
In the template :
<input type="checkbox" ng-model="avariabledefinedincontroller" />
And in the controller, you'll have just the variable :
// Default state
$scope.avariabledefinedincontroller = false;
Fiddle
Edit : The purpose of this question was actually to prevent the user to check a checkbox, but without disabling the checkbox. For that, #JLRishe's answer addresses well the problem, though I would personally add the state value to set as an argument to setState :
angular.module('demoApp', []).controller('DemoController', function($scope, $timeout) {
$scope.myVar = false;
$scope.setState = function (varName, val) {
$timeout(function() {
$scope[varName] = val;
}, 0);
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.14/angular.js"></script>
<div ng-app="demoApp" ng-controller="DemoController">
<input type="checkbox" ng-model="myVar" ng-click="setState('myVar', false)" />
{{myVar}}
</div>
VYou can also use a short-hand:
<input type="checkbox" ng-model="avariabledefinedincontroller" ng-click="aVariable = !aVariable"/>
There are a number of options available to you, but just in case this can help someone, I did two things.
I passed the $event in so that I could run event.preventDefault() (so it wont get checked)
ng-click="changemystate($event, avariabledefinedincontroller)">
In $scope.changemystate() I then added the event param, and called
event.preventDefault()
Secondly, I then just added a return so that the method terminates, so there is no need to roll back the value, because it prevents it from being updated in the first place.

AngularJS Data Binding with Getter and Setter Service Method

I'm struggling to understand how data binding and Service works togheter in AngularJS.
I've 1 controller and 1 service.
My service:
myAppServices.factory('SharedData',['$http',function($http){
var _data = {
"first_prop" :{
"name": "first_prop",
"info": "infofirst_prop"
},
"second_prop" :{
"name": "second_prop",
"info": "infosecond_prop"
}
};
return {
getProp: function (name) {
return _data[name];
},
setProp: function (name,value) {
_data[name] = value;
}
};
}])
My controller code:
webAppControllers.controller('FirstCtrl', ['$scope', '$http','SharedData',
function ($scope, $http,SharedData) {
$scope.data = angular.copy(SharedData.getProp("first_prop"))
$scope.print = function()
{
console.log(SharedData.getProp("first_prop"));
}
$scope.modify = function()
{
SharedData.setProp("first_prop",$scope.data)
}
}
]);
And this is my view:
<form role="form">
<div class="form-group">
<label for="nome">Name</label>
<input type="text" ng-model="data.name" class="form-control" id="name" placeholder="Modify the name...">
</div>
<div class="form-group">
<label for="info">Info</label>
<input type="text" ng-model="data.info" class="form-control" id="info" placeholder="Modify the info ...">
</div>
<button ng-click="modify()" class="btn btn-default">Modify</button>
<button ng-click="print()" class="btn btn-default">Print</button>
</form>
If i modify the view, overriding value in the form, and then i click on print button, console.log return me values store in services(into private variable _data), and this is what i excpected.
Then if i click on modify button, and again print button, this time cosole.log shows me modified values that was saved on private var _data in my service. Also this behavior is expected.
The strange thing appear when after i did this interaction with my webapp, i again modify value in the form and click on print button without clicking on modify button. Values stored in service are modified even if i never click modify button and so i never call SharedData.setProp() method.
With the method angular.copy(), i expected to create new variable(a new copy of a variable), and so if i modify this "$scoped" variable i expected it was impossible modify directly private _data variable in my service.
Why this happens? Are there a method to modify and access private variable in service only by some defined method?
Thanks in advance.
Best regard,
Alessandro.
After you click setProp, the object in SharedData and in the scope is the same object.
To solve this, call this line again after you call "modify()":
$scope.modify = function()
{
SharedData.setProp("first_prop",$scope.data)
// grab another copy of the first_prop object, or else its the same reference.
$scope.data = angular.copy(SharedData.getProp("first_prop"));
}
There are other ways to solve this, such as in setProp, pass angular.copy($scope.data), etc.
Always be aware that when you pass objects in javascript, the pass by reference, not by value.

checkbox lost state after ember action

I have input type="checkbox"
<input type="checkbox" {{action 'checkInvoice' item.number}}/>
after ember calls acttion , checkbox loses state. this is simple action code
checkInvoice:function(number){
var invoices=this.get('invoices');
var model=this.get('model');
model.forEach(function(item){
if (item.number===number) {
invoices.pushObject(item);
}
});
return;
}
How embers treats so? or may I reach the same result with ember helper (how to set parameter for action)?
{{input type="checkbox" action='checkInvoice' }}
You can define an itemController for each item in the model, bind the checked property of the checkbox to a property in the itemController and observe the property in the itemController to handle pushing the object into another array.
App.IndexController = Ember.ArrayController.extend({
invoices: [],
itemController: 'indexItem'
});
App.IndexItemController = Ember.ObjectController.extend({
isCheckedChanged: function(){
if(this.get('isChecked')) {
this.get('parentController.invoices').pushObject(this.get('content'));
} else {
this.get('parentController.invoices').removeObject(this.get('content'));
}
}.observes('isChecked')
});
In the template:
{{#each item in model}}
<li>
{{input type="checkbox" checked=item.isChecked}}
{{item.name}}
</li>
{{/each}}
Sample working jsbin .
I have done view for checkbox. use this answer Trigger an action on the change event with Ember.js checkbox input helper?
export default Ember.Checkbox.extend({
hookup: function () {
var action = this.get('action');
if (action) {
this.on('change', this, this.sendHookup);
}
}.on('init'),
sendHookup: function (ev) {
var action = this.get('action'),
controller = this.get('controller');
controller.send(action, this.$().prop('checked'));
},
cleanup: function () {
this.off('change', this, this.sendHookup);
}.on('willDestroyElement')
});
so this is my checkbox
{{view "checkbox" action='testaction' checked=item.selected }}
and after click moved value 'selected' will changed. so I can filter model with selected property. Also can send to action with params

Angular data-binding $watch

My web page looks like (abbreviated)
<HTML ng-app="scanning">
...
<BODY ng-controller="scanningController">
<INPUT id=R_name maxLength=50 size=35 ng-bind='BOOKING.R_NAME'>
</BODY>
</HTML>
My code is
function scanningController($scope){
$scope.depot = depot;
$scope.BOOKING = {R_NAME: ''};
/* Does anything get changed. */
$scope.$watch('BOOKING', function() {
...
}, true);
}
var scanningModule = angular.module('scanning', []);
scanningModule.controller('scanningController', scanningController);
The watch event does not get called when the user changes the value of R_NAME via the textbox. It does get called when the page initially loads, just not when values are changed by the user.
I have forced the event to fire by using an interval timer, changing a test property and calling $digest. In that case when I debug I can see that nothing entered through the textbox has been stored on the object. So it seems that I have not setup databinding correctly.
You should use ng-model for two-way binding instead of ng-bind.
<INPUT id="R_name" maxLength="50" size="35" ng-model="BOOKING.R_NAME">
You can also use ng-change instead of adding a $watch in your controller
<INPUT id="R_name" maxLength="50" size="35" ng-model="BOOKING.R_NAME" ng-change="onChange()">
Controller
function scanningController($scope){
$scope.depot = depot;
$scope.BOOKING = {R_NAME: ''};
/* Does anything get changed. */
$scope.onChange = function () {
...
};
}

Resources