Saturday, January 08, 2011

Html form validation on a webkit mobile browser

In this post, I am going to talk about how can we run validation logic on form fields on mobile webkit browser and stop it from being submitted if the validation fails and submit it if the validation passes. It is well known that if the browser/ or your javascript code has invoked the submit event on the form, it is too late to run the validation logic i.e. you can never stop the browser to submit the form if the validation logic fails. Even if you try to set the return value of the event to false or if you try to stop default action from submit event handler. I always use the following method to kill an event

 // e: Event
function stopEvent(e)
{
if(e===null) e = window.event;
if(e!=null && typeof e != 'undefined')
{
e.cancelBubble = true;
e.returnValue = false;
if (e.stopPropagation) {e.stopPropagation();};
if (e.preventDefault) {e.preventDefault();};
}
}

On mobile devices, user would submit a form by hitting "Go" or "Search" button on iPhone or "return" button on Android unless you have your own submit button on the page. When the user hits the button, browser would fire the submit event on the form and if you call stopEvent method from your form submit event handler, the browser would still submit the form. So in order to solve the problem, we need to get hold of an event that browser fires before it fires submit event on the form. If we can find such an event, then we can run the validation logic in that event handler and stop bubbling of the event if the validation logic fails. In that case, submit event would never be triggered on the form and we will achieve our goal.

In my case, I have an input field (type=text) and for discussion purpose, I just want to make sure that the value in input field is not empty. The way I solved this problem is by running the validation logic in keydown event handler of the field. When the user taps on "Go" or "return" button on the phone, browser sets the event keycode to 13. So assuming OnKeyDownEventHandler is your event handler for keydown event, you can do the following:

function OnKeyDownEventHandler(e)
{
if(e===null)e=window.event;
if(e!=null && typeof e != 'undefined')
{
var keycode = e.keyCode;
if(keycode===13)
{
// IsValid runs the validation logic
if(!IsValid())
stopEvent(e);
}
}
}

Note that on iPhone 3 (not sure below iphone 3), browser sets the keycode to 10 instead of 13. So you to make this logic work on iphone 3 and above, you need to run the logic when the keycode is also 10.

function OnKeyDownEventHandler(e)
{
if(e===null)e=window.event;
if(e!=null && typeof e != 'undefined')
{
var keycode = e.keyCode;
if(keycode===13 || keycode===10)
{
// IsValid runs the validation logic
if(!IsValid())
stopEvent(e);
}
}
}

Some might argue that other browsers might fire keycode 10 for a different key and this would break the logic. True. But practically I have never came across such a situation. If you want, you can do device sniffing by getting the UA and running the logic for keycode = 10 only if the device is iphone with version 3.

No comments: