tags:

views:

931

answers:

2

Hi,

I am trying to write table navigation using keys for asp.net gridview. This is what I have so far. It is working fine but it is slow. Please look at it and let me know how to improve the performance if possible.

Basically it is html table with input elements. The structure of table is like this

<table>
<tr>
<td>
<div style="height:22px;">
     <input type = "text">
</div>
</td>
</tr>
<tr>
<td>
<div style="height:22px;">
     <input type = "text">
</div>
</td>
</tr>
...
</table>
jQuery(function($) {
             $('table#<%= myTable.ClientID %>')
                .bind('keydown', funcKeyDown)
        });


function funcKeyDown(event)
        {   
            //get cell element.
            var cell = event.target;

            //get current cellIndex
            var $cell = $(cell);         
            var currCell = $cell.parents("td"); 
            var cellIndex = currCell[0].cellIndex;
            //get current rowIndex
            var currRow = $cell.parents("tr");
            var rowIndex = currRow[0].rowIndex;   

            var nextRowIndex, targetElem = null; 
            var nextCell;           
            switch(event.keyCode) {                
                case 13: //enter key
                    if(shiftKeyPressed == 1){
                        //move left                        
                        if(!(cellIndex == 0)){                        
                        targetElem = currRow.children("td").eq(cellIndex-1).find("input[type=text]");
                        if(targetElem){targetElem.select();}}}
                    else {
                        //move right
                       if(!(cellIndex == (numElements -1))){
                            targetElem = currRow.children("td").eq(cellIndex+1).find("input[type=text]");                        
                            if(targetElem){
                                targetElem.select();
                            }
                        }
                    }                         
                    return false;                          
                case 16: //shift key
                    shiftKeyPressed = 1;
                    return false;
                case 33:                    
                case 34: //page-up, page-down
                    if(event.keyCode == 33){
                        nextRowIndex = rowIndex - pageSize;
                        if(nextRowIndex < 0) nextRowIndex = 0;                
                    }
                    if(event.keyCode == 34){
                        nextRowIndex = rowIndex + pageSize;
                        if(nextRowIndex > numRows) nextRowIndex = numRows;
                    }                      
                    targetElem = currRow.parent().children("tr").eq(nextRowIndex).children("td").eq(cellIndex)
                                    .find("input[type=text]");                                                                
                    if(targetElem != null){targetElem.select();}
                    return false;                   
                case 37: //left       
                    if(!(cellIndex == 0)){                        
                        targetElem = currRow.children("td").eq(cellIndex-1).find("input[type=text]");
                        if(targetElem != null){targetElem.select();}}
                    return false;                                                
                case 38: //up                    
                    if(rowIndex != 0){
                        targetElem = currRow.parent().children("tr").eq(rowIndex-1).children("td").eq(cellIndex)
                                        .find("input[type=text]");                                                                
                        if(targetElem != null){
                        targetElem.select();}}
                    return false;                                                
                case 39: //right arrow
                    if(!(cellIndex == (numElements -1))){
                        targetElem = currRow.children("td").eq(cellIndex+1).find("input[type=text]");                        
                        if(targetElem != null){targetElem.select();}}
                    return false;                                                
                case 40: //down                                               
                    if(rowIndex >= 0){
                        targetElem = currRow.parent().children("tr").eq(rowIndex+1).children("td").eq(cellIndex)
                                        .find("input[type=text]");                                                                
                        if(targetElem != null){targetElem.select();}}
                    return false;                                                                                                        
            }            
        }
+1  A: 

First off all you've got code running for every key press before you get into the switch statement and determine whether you actually need to do anything.

You need to factor that code into a function that simply gets the TD (as a simple element variable not a Jquery wrapper).

On top of this you have to understand that JQuery abstracting the differences between browsers comes with a price, performance. For example when a bound event fires the event has a moderate chunk of Javascript to run through before your actual event function gets called.

Your use of currRow.children("td").eq(cellIndex+1).find("input[type=text]"); isn't going to be particularly great. You could elminate the extra div by specifying height on the td. Then assuming the td only contains such an input.

var tdNext = td.nextSibling;
var textBox =  tdNext ? tdNext.firstChild : null;
if (textBox) $(textBox).select();

The lesson is sometimes you need to circumvent JQueries advantages for the sake of performance. The above code is still very compatible across multiple browsers.

You can apply similar techniques to the other main keys left, up, down and enter.

Is there a reason you are not using event.shiftKey to detect the shift key? Using a global variable as you appear to be doesn't seem sound.

AnthonyWJones
A: 

Hi Anthony,

Thanks for the response. I do not have control over the generation of html for table. we are using third party control to generate the table in asp.net. If a table doesn't have scrollbars, then there won't be tags inside . If a table has scrollbars, then it would have tags. so I have to account for that. I will try using your suggestions. If you have any code samples for this one, please let me know.

Thanks, sridhar.