Thursday, April 16, 2009

Focus the first control of your page

In all pages we have to put the focus on the first control of the page. It can be a textbox,a radio button, a checkbox, a select field, a textarea or a button. For my current project i have created a function which i have placed inside the masterpage and it will traverse through the page starting from a particular control (inside the control) and will take the first occurance of the above types of control and will put the cursor focus on the control. Below is the javascript code i used to achieve this

function selectFirstControl()
{
var objIP = getFocusableControl(document.getElementById('tdContentBody'));
if(objIP!=null)
{
objIP.focus();
return;
}
}

function getFocusableControl(parentCtrl)
{
if(!$(parentCtrl).visible())
return null;
if(parentCtrl.tagName == "INPUT")
{
if(parentCtrl.getAttribute("type")=="hidden")
{
return null;
}
return parentCtrl;
}
else
{
if(parentCtrl.tagName == "SELECT")
{
return parentCtrl;
}
}
var children = $(parentCtrl).childElements();
for(var i = 0;i<children.length;i++)
{
var resCtrl = getFocusableControl(children[i]);
if(resCtrl != null)
return resCtrl;
}
}


Call the function selectFirstControl(); from the bottom of your page.
Here i have called the function "getFocusableControl" recursively to get the control. It is checking the tagname of the node, if it is "Input" or "Select" then it is excluding the hidden fields by checking the type property for for inputs and if it is not hidden, then it is putting the focus on the control.
Iam checking if the parent control visible or not with $(parentCtrl).visible() which is a function from prototypejs to check the visibility. But this checks for the inline "display" property of the element, if "display :none" it returns false. But it cannot check if you are using the hidden property of hiding the control with stylesheet class.
If you are not using prototypejs, you can check the direct style property of the control.

Tuesday, April 7, 2009

Trigger Html/Javascript Event from Javascript

In many situation i had to trigger JavaScript Event from code. Like click on a button when something happened to post the page. It mainly comes into picture when i use UpdatePanel or using modalpopup for click on a button inside grid/list/gridview ect. This creation of event is very much dependent on the browser. Here is the code to trigger a button click event
function clickButton()
{
if( document.createEvent )
{
var evObj = document.createEvent('MouseEvents');
evObj.initMouseEvent( 'click', true, false, window, 0, 12, 345, 7, 220, false, false, true, false, 0, null );
$(' btnTransRefresh').dispatchEvent(evObj);
}
else
if( document.createEventObject )
{
$('btnTransRefresh').fireEvent('onChange');
}
}

Here i am using Prototyprjs framework, so you see the "$". You can replace those with document.getElementById('') syntax.
initMouseEvent takes the following parameters.
initMouseEvent( 'type', bubbles, cancelable, windowObject, detail, screenX, screenY, clientX, clientY, ctrlKey, altKey, shiftKey, metaKey, button, relatedTarget )

In many scenarios we do some javascript calculation on change of value in some particular textboxes. But in some scenarios, the value in the textbox on change of which we need to calculate is done through some javascript. Like in my project i was using calender from ajax control toolkit which is inside a project specific control names PRPCalender. In some pages i had to do some calculations only when the value in calender is changed. So i could not use the javascript events associated with the calender control (ajax). So i decided to go with triggering onchange event as the textbox showing the calender control doesn't fire the onchange event as the value is changed through JavaScript.
string methodName = "prpCalenderDateChanged" + txtCalendar.ClientID;
calendarExtender.OnClientDateSelectionChanged = methodName;
System.Text.StringBuilder sb = new System.Text.StringBuilder();
sb.AppendFormat(@"
function {0}(sender,eArg)
{{
//alert('Calender Date Changed');
var tbId = '{1}';
//$(tbId).blur();
//$(tbId).focus();
if( document.createEvent )
{{
var evObj = document.createEvent('HTMLEvents');
evObj.initEvent( 'onchange', true, false);
$(tbId).dispatchEvent(evObj);
}}
else
if( document.createEventObject )
{{
$(tbId).change();
}}
}}
", methodName, txtCalendar.ClientID);
ScriptManager.RegisterStartupScript(this, this.GetType(), "textChanged" + txtCalendar.ClientID, sb.ToString(), true);
Here inside my calender control PRPCalender, i am registering a function which is unique for each calender control inside any page (i am using the client id as concatined to generate the method name) which fires the onchange event on the textbox.
calendarExtender.OnClientDateSelectionChanged = methodName;
which is called by toolkit JS when the date value is changed.
Some Useful Link Link1