Odd Knockout click event data binding

Looks like, Knockout data-binding for click event suppress default behavior of html elements like A, BUTTON, INPUT.
I spotted on this behavior at work in scope of my project, and I’ve done some research to verify it.
Based on my own experience, created github issue and discussion with @mbest, I share some my motes here.

knockout-click-data-bind-example-screen

 

Initial ideas was

  • To have A element, and depends on other UI elements
  • Compose/combine URL and set to A via
data-bind="attr: {href = downloadReportURL}"
  • When href is set I planned to click on A, and meanwhile it downloads file (planned to have huge file, so some delay time expected) I wanted to kinda disabled (grayish, etc.)
  • In fact that “disabling” planned to be reset by another UI logic (not related to original issue).

As I mentioned in initial github issue description, my guess is, that when I provide click data-binding for A element, in fact Knockout kinda suppresses default A element click behavior, and as result such A element attribute href is not useful anymore.

Maybe it’s default Knockout behavior and it was designed so, but I was surprised.

 

JSFiddle example

So, here is my jsfiddle: code is a bit different, and uses ONLY Knockout 3.2.0 (debug) and no KSB.
http://jsfiddle.net/landike/9emtsnaa/37/

Use cases: (based on jsfiddle example)

Case 1:

  1. Initially no url set to A element and no data-binding for BUTTON element.
  2. Then I “setUrl”, so A element has attr.href now, and in theory I expect, that A should be clickable.
  3. I click on A element, and click handler executed (u will see alert), but clicking on A href is not used and download doesn’t work.
  4. When I remove click: hyprlinkClick, from this code:
     <a target="_blank" href="#" data-bind="click: hyprlinkClick, attr: {href: bindAttrHref}"></a>

    then click event data-binding, and href/download works as expected.

  5. U can see, that there is free A element, with no binding, where href is used as usual (u can download file).

Case 2:

  1. On the other hand, BUTTON element is a bit different element, but because it doesn’t have href I can’t use for my feature. But if the button of submit type, the parent form is not submitting after button click.

Case 3:

  1. With added CHECKBOX element, behavior the same – when click data-bind applied by Knockout, event with empty function, u simply can’t check/un-check checkbox, which is funny 🙂
    So again, I understand, that applying click data-binding, Knockout call something kinda event.preventDefault() and apply new handler on top of default element behavior.

I realize, it might look like it’s OK, because by using click handler we replace A element default behavior.
But again, I was surprised with such data-binding case.

 

Solution

As simple as possible. Simply READ DOCS 🙂

knockout-click-data-bind-note-3

And yes, I changed my function a bit, and all elements works correctly.

this.hyprlinkClick = function(){
    alert('Click event on A - Done. But ...');
    this.inProgress(true);
    return true;
};
this.checkboxClick = function(viewModel,event){
    //alert('Click event on CHECKBOX - Done.');
    //this.bindAttrDisabled(true);
    return true;
};
this.buttonClick = function() {
    alert('Click event on BUTTON - Done. I can use URL as I wish: '+this.bindAttrHref());
    this.bindEnable(true);
    return true;
};

 

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s