Question

Sample 1 - functionally broken

In this Durandal 2.0.1 view the click handlers don't fire.

<div class="messageBox">
  <form class="form-inline" data-bind="submit: commit">
    <div class="modal-header">
      <h3>Upload item</h3>
    </div>
    <div class="modal-body">
      <section>
        <fieldset class="main">
          ... (lots of data bound fields) ...
       </fieldset>
      </section>
    </div>
    <div class="modal-footer">
      <button class="btn btn-primary button" data-bind="click: commit">OK</button>
      <button class="btn button" data-bind="click: rollback">Cancel</button>
     </div>
  </form>
</div>

Instead, the form submit handler fires, giving no indication of which button was clicked.

Sample 2 - visually broken

In this sample, the only difference is that the buttons are in the body div instead of the footer div. In this case, the button click handlers do fire, but the buttons aren't positioned correctly and the UI looks dreadful.

<div class="messageBox">
  <form class="form-inline" data-bind="submit: commit">
    <div class="modal-header">
      <h3>Upload item</h3>
    </div>
    <div class="modal-body">
      <section>
        <fieldset class="main">
          ... (lots of data bound fields) ...
          <button class="btn btn-primary button" data-bind="click: commit">OK</button>
          <button class="btn button" data-bind="click: rollback">Cancel</button>
        </fieldset>
      </section>
    </div>
    <div class="modal-footer">
    </div>
  </form>
</div>

In the dialog sample on the Durandal website there is an "ok" handler that is bound to both form submit and button click, as in the sample views here. It took me ages to figure out that it wasn't the button click event firing but the form submit event.

I need to put the buttons in the footer for proper layout, but I need the click events to fire so that I know whether the user clicked OK or Cancel. I can explicitly bind onclick="commit" and onclick="rollback" for the two buttons, but that's ... so hacky.

What's fouling up the binding when they're in the footer and what can I do about it?

Was it helpful?

Solution

Answer from comments to original post:

Normally, click bindings within a submit binding should fire correctly, as shown in this example based on the posted code: http://jsfiddle.net/SeKkc/

If you have a rogue ko comment, or some other markup that changes the binding scope, perhaps in the section marked:

... (lots of data bound fields) ...

This may interfere with your two bindings to click: commit and click: rollback as it may not be able to find those bindings. In other words, the commit function that you are attempting to bind to is accessible by the submit: commit binding, but something inbetween causes it to become inaccessible for the click: commit binding.

If the click binding cannot find commit and rollback, then a click on those buttons will fallback to the submit binding, which happens to be bound to commit. This fallback behaviour is shown here, where clicking the buttons will fire the commit function: http://jsfiddle.net/SeKkc/2/

This behaviour may also be caused by a binding to a property that does not exist on the model. The buttons are at the end of the page and are processed last. Preprocessing stops when the invalid binding is encountered; this is before the buttons are processed, so no click handler is bound to them. This is why moving them to the start of the body caused them to start working.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top