by Andreas

JQuery / KnockoutJS – define default button within a DIV

We’ve previously covered several aspects of using Default buttons in ASP.NET and Silverlight (the latter is in Norwegian, but should be semi-readable through an automagically translated version – sponsored by Google Translate).

This time I thought I’d show you how I did this without the need of server side controls. Why? First of all, adding server side controls adds unnecessary overhead by increasing the view state. Second, in my complex client side user interface I’ve stuck to clean HTML, javascript / jQuery and KnockoutJS. I didn’t want to clog it up, and since the solution was as simple as it turned out to be I am glad I stuck to my guns.

I had a look at what ASP.NET generates when a default button is defined for a Panel control. As you may or may not know, the server side Panel control is rendered as a DIV when the page is returned to the client browser. And as expected, Javascript is used to invoke the defined default button click event so I thought I’d just steal this javascript function and call it myself from within my pure HTML DIV element. Not surprisingly, this worked and why shouldn’t it? I just did the exact same thing as the .NET framework does, and there’s not much voodoo or black magic in that.

So, I wanted to invoke the click event for a “Save Changes” button displayed within a Fancybox dialog, simply by clicking ENTER. First, I added the javascript function that I stole from the .NET server control rendering engine (I am pretty sure that’s not what it’s called):

function WebForm_FireDefaultButton(event, target) {
    if (event.keyCode == 13) {
        // this variable has to be added
        var __nonMSDOMBrowser =
            (window.navigator.appName.toLowerCase().indexOf('explorer') == -1);

        var src = event.srcElement || event.target;
        if (!src || (src.tagName.toLowerCase() != "textarea")) {
            var defaultButton;
            if (__nonMSDOMBrowser) {
                defaultButton = document.getElementById(target);
            }
            else {
                defaultButton = document.all[target];
            }
            if (defaultButton && typeof (defaultButton.click) != "undefined") {
                defaultButton.click();
                event.cancelBubble = true;
                if (event.stopPropagation) event.stopPropagation();
                return false;
            }
        }
    }
    return true;
}

Note that I had to add the __nonMSDOMBrowser variable. This is usually added as a global variable on the page, but I saw no reason to do so because none of my other functions care about it.

Then, within my dialog box DIV element I make sure the onkeypress calls the new function with the ID of the button as a parameter:

<div id="addContactDialogBody" class="modal-body" onkeypress="javascript:return WebForm_FireDefaultButton(event, 'btnSaveContact')">
      <!-- This is my user input form, containing a couple of input text fields -->
</div>
<div id="addContactDialogFooter" class="modal-footer">
    <!-- dont be confused, the data-bind attribute is KnockoutJS related and has nothing to do with this example -->
    <input id="btnSaveContact" type="button" value="Save" data-bind="click: addNewContact, visible: true" />
    <input id="btnCancelContact" type="button" value="Cancel" onclick="javascript: $.fancybox.close();" />
</div>

 

When the focus is on an element within the first DIV (removed for clarty in the example code), pressing the enter Key will invoke the click event (or in my case, a KnockoutJS click binding) for the button with id btnSaveContact.