0

I'm trying to deal with a checkbox checked event on my Magento project, here is my html code for the checkbox:

<td class="col col-method">
    <input type="checkbox" data-bind="checked: checkedAction, click: clickedAction"/>
</td>

And below is the js code:

define([
    'jquery',
    'underscore',
    'Magento_Ui/js/form/form',
    'ko'
], function ($, _, Component, ko) {
    'use strict';

    return Component.extend({
        defaults: {
            template: 'Vendor_Module/checkout/shipping/template'
        },
        initialize: function() {
            var self = this;
            this._super();
            this.setCheckbox();
        },
        setCheckbox: function() {
            var viewModel= {
                selectedAction: ko.observable(false),
                clickedAction: function() {
                    window.alert('checkbox checked!!');
                    return true;
                }
            };

            ko.applyBindings(viewModel);
        }
    });
});

It didn't work unluckily, could you point out what is wrong here?

Mark Fox
  • 8,694
  • 9
  • 53
  • 75
Joel
  • 57
  • 2
  • 10

2 Answers2

2

Using a click binding on a checkbox is almost always the wrong thing to do in Knockout. In particular, having both a checked and a click binding on a checkbox usually indicates a misunderstanding about how they work, and you wind up with the two actions stepping on each other.

The checked binding will register the state of the checkbox into a variable, and it is two way: the checkbox and the variable will stay in sync, no matter whether it is changed in the view or in your code. To have something happen when that state changes, you subscribe to the variable with whatever you want to happen.

For example:

vm = {
  state: ko.observable(false)
};

vm.state.subscribe(function(newState) {
  if (newState) {
    alert("Checked!");
  } else {
    alert("Unchecked!");
  }
});

ko.applyBindings(vm);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<input type="checkbox" data-bind="checked: state" />
Roy J
  • 42,522
  • 10
  • 78
  • 102
  • Why is a bad idea to bind the `click` event of whichever control? Which problems can it bring into scene? And, supposing you're right, are you sure that the OP wants to know when a value bound to the check state of a checkbox changed or that the user checked the control? – JotaBe Jan 05 '16 at 14:38
  • @JotaBe The user included both a checked and a click binding. I have seen that in several questions before, and it has always been wrong. It is possible that the user specifically wants to know when the box was checked, distinct from possible value changes, which is why I said "almost always". – Roy J Jan 05 '16 at 14:46
  • You improved your answer by including an explanation of why it can be wrong. That's exactly what I expected ;) – JotaBe Jan 05 '16 at 14:51
  • The fact that i'm working on a Magento project makes the code so hard to implement, and yes, I just heard about knockoutJs about 7 hours ago, so I'm no more than a complete newbie at this – Joel Jan 05 '16 at 14:58
0

There is no such thing as a checked event. There are click and change events.

There is a generic way of binding events in knockout, without using a custom binding. Something like this:

var vm = {
 clicked: function() {alert('Clicked!')},
 changed: function() {alert('Changed!')},
};

ko.applyBindings(vm);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js">
</script>
<label>
Click me! <input type="checkbox" data-bind="event: {change: clicked}"/>
</label>
<label>
Change me! <input type="checkbox" data-bind="event: {change: changed}"/>
</label>

For some events, there are also specific bindings, like this one for click:

Click me! <input type="checkbox" data-bind="click: clicked"/>

And the checked binding refers to an observable that will be set to true or false depending on the checkbox state.

NOTE: please, see the interesting point in Roy J's answer. This answer shows how you can use events in checkboxes. But, as Roy J's points out, if what you really need to detect is that the checked state changed, it's much better to subscribe to the corresponding observable. Handling events in the wrong way can lead to problems: for example you can avoid the checkbox to change its state, specially if you use jQuery events. See this: knockout.js and listen to check event on checkbox

Community
  • 1
  • 1
JotaBe
  • 38,030
  • 8
  • 98
  • 117
  • @AdamJeffers Please read the link you have provided: *"The checked binding links a checkable form control — i.e., a checkbox () or a radio button () — with a property on your view model."* Doesn't it look like my explanation? You should be more cautious when you speak about soemthing that you don't know in depth. – JotaBe Jan 05 '16 at 14:27
  • Thanks a lot, I will try to implement it and tell you if it's the right solution – Joel Jan 05 '16 at 14:29
  • @AdamJeffers I've created a whole new jsfiddle for you to see that my explanation is exact, and refers to what the documentation says. Please, keep reading the documentation and see my sample. You'll discover that `checked` is not an event, but an state which is false or true. I insist that you should be more cautious: https://jsfiddle.net/jbustos/prgeuxvy/ As you can see in my example there is a checkbox, that I of course noticed in the OP question. Had I been rude or not (I didn't pretend to) you're making the same mistake twice. – JotaBe Jan 05 '16 at 14:48
  • @AdamJeffers You finally understood you was wrong.Your second comment "Your explanation is not the same as that given in the docs" proves that you was still wrong and insisting in your error, and that comment was not a "fingers-faster-than-brain" problem. Plesae read again: "And the checked binding refers to an observable that will be set to true or false depending on the checkbox state." which is what you exactly see in the working sample, and in a relaxed reading of ko docs. I hope that, on next occasions, if someone tells you that you're wrong at least you'll try to understand why – JotaBe Jan 05 '16 at 15:22
  • Haha, nope, I wasn't wrong... I think we have our wires crossed :-D Happy coding! – An0nC0d3r Jan 05 '16 at 15:29
  • @AdamJeffers If you say so! – JotaBe Jan 05 '16 at 15:32
  • Following your edited answer... my comments no longer apply so have removed ;-) – An0nC0d3r Jan 05 '16 at 15:36