Tuesday 10 March 2009

C# Form DefaultButton Firefox fix

When should you use default buttons?

A default button should be set when a page has the requirements for two or more forms or buttons, if no default button is set then the first button within the HTML document will be submitted. This default behavoiur is fine for a page with a singular form, however if like we stated earlier their are two or more forms or buttons then this behaviour is not acceptable as in most cases the first button may be a cancel action. This for a user would be very frustrating after filling in a lengthy form, or the user may even think that the form was submitted.

This problem only occurs when the return key is pressed on an input, as we stated earlier if no default button is set then the first button will be submitted

Note that within .Net only one server side form may be implemented.

I will present two solutions the first of which is commonly used but doesn't work, so I felt this was worth presenting.

Solution 1 (not suitable)

You can set a default button only in .Net 2.0+ by using the following code within the server side script.

Page.Form.DefaultButton = btnSubmit.ClientID;

The problem with this solution is it doesn't fix a bug exposed within Firefox, where a textarea will not allow new lines to be inserted. The default action for a textarea within a form should be to create a new line, however an element which is required within Firefox is missing, we will explain this in a bit more detail in solution 2.

Solution 2

This solution fixes a firefox bug, Firefox doesn't support an element known as event.srcElement within javascript. This problem affects the HTML textarea tag. When a return key is pressed within the textarea the default action should be to drop down to a new line. However in .Net 2.0 the action performed is to submit the form.

We can fix this by using this javascript within the header or by creating a javascript file and importing the file into the header:

Javascript 'default-button.js (file to be added)'
// Fix Firefox bug : stop textarea on return key press from submitting the form
function FireDefaultButton(event, target) {
    // srcElement is for IE
    var element = event.target || event.srcElement;

    if (13 == event.keyCode && element != undefined && element.tagName.toLowerCase() != "textarea") {
        var defaultButton = document.getElementById(target);

        if (defaultButton != undefined && defaultButton.click != undefined) {
            defaultButton.click();
            event.cancelBubble = true;

            if (event.stopPropagation) event.stopPropagation();

            return false;
        }
    }
    return true;
}

To use this new function we cannot use the normal default button that is defined by .Net on the form element (solution 1).

We have to add in this line of code to register the event for the client side, please replace btnMyButton with the input that has a runat at server attribute:

Page.Form.Attributes["onkeypress"] = "return FireDefaultButton(event, '" + btnMyButton.ClientID + "')";

Producing the effect of two forms on the same page you ask?

Using a similiar technique we can produce the effect of two forms on one page. To do this we will use a div instead of the form to add our 'onkeypress' event

please replace btnMyButton with the input that has a runat at server attribute:

divForm.Attributes["onkeypress"] = "return FireDefaultButton(event, '" + btnMyButton.ClientID + "')";

No comments: