0

How to navigate (up or down) in ASP.NET gridview using arrow keys while highlighting the current row?

I am able to move through rows with up and down arrow keys using javascript code and C# code. I also implemented a begin request and end request JS code for maintaining scroll position on postback.

However, my problem is, scrollbar doesn't move up or down to show the highlighted row automatically. Suppose there are 100 rows, I select 15th row, but grid height is like it can show only 10 rows, unless we move scroll bar manually, it doesn't move automatically to display the selected row via arrow keys. How to ensure this synchronous or visibility of highlighted row by moving scroll bar?

My gridview doesn't have checkbox.

Please help me. Its my code here:

<asp:GridView ID="gvCycles" runat="server" AutoGenerateColumns="False" 
    CssClass="grid"
    AllowSorting="True"
    ShowHeader="False"
    ShowFooter="True"
    OnSelectedIndexChanged="gvDeductionList_SelectedIndexChanged" 
    OnRowDataBound="gvDeductionList_RowDataBound" DataKeyNames="CycleID" onselectedindexchanging="gvCycles_SelectedIndexChanging"
    >
    <Columns>               
        <asp:BoundField DataField="CycleID" HeaderText="CycleID"
            HtmlEncode="False"                    
            SortExpression="CycleID">
            <ItemStyle CssClass="GridViewHiddenColumn" />    
        </asp:BoundField> 

What I did to maintain the scroll position on postback is:

<script language="javascript" type="text/javascript">
    // This Script is used to maintain Grid Scroll on Partial Postback
    var scrollTop;
    //Register Begin Request and End Request 
    Sys.WebForms.PageRequestManager.getInstance().add_beginRequest(BeginRequestHandler);
    Sys.WebForms.PageRequestManager.getInstance().add_endRequest(EndRequestHandler);
    //Get The Div Scroll Position
    function BeginRequestHandler(sender, args) {
        var m = document.getElementById('divGrid');
        scrollTop = m.scrollTop;
    }
    //Set The Div Scroll Position
    function EndRequestHandler(sender, args) {
        var m = document.getElementById('divGrid');
        m.scrollTop = scrollTop;
    } 
</script>

Also, I have this in the keydown and keyup

 if (e.keyCode == '38') {
                document.getElementById('<%= controlCapture.ClientID %>').value = false;
                document.getElementById('<%= shiftCapture.ClientID %>').value = false;
                // up arrow
                __doPostBack(pageId, "up");
            }
else if (e.keyCode == '40') {
                document.getElementById('<%= controlCapture.ClientID %>').value = false;
                document.getElementById('<%= shiftCapture.ClientID %>').value = false;
                              // down arrow
                __doPostBack(pageId, "down");

Question: I do not know where to use the code you mentioned in the codeproject such that, when I press key down or up arrow keys, it should move scroll bar automatically. I do not have pagination.

Page_load Code

protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack) //on initial load, default dates to current fbt year
        {
            dpDateFrom.DateValue = currentBT;
            dpDateTo.DateValue = currentBTEnd;

            Searchclick();
        }
            //cursor keys
        else if (Request.Form["__EVENTARGUMENT"] == "up" || Request.Form["__EVENTARGUMENT"] == "down")
        {
            string eventArgument = Request.Form["__EVENTARGUMENT"];
            int intPayCycleId = 0;

            if (gvCycles.SelectedIndex >= 0 && gvCycles.SelectedIndex < gvCycles.Rows.Count)
            {
                if (eventArgument == "down")
                {
                    if (gvCycles.SelectedIndex < gvCycles.Rows.Count-1)
                    {
                        gvCycles.SelectedIndex += 1;

                    }
                }
                else if (eventArgument == "up")
                {
                    if (gvCycles.SelectedIndex > 0)
                    {
                        gvCycles.SelectedIndex -= 1;
                    }
                }

                hdnSelectedRow.Value = gvCycles.SelectedValue.ToString() + ","; //assign hidden value with selected row
                SetRowsStyle(gvCycles);

                if (int.TryParse(gvCycles.SelectedRow.Cells[0].Text, out intCycleId))
                {
                    ShowDeductions(intCycleId, false);
                }
            }
        }
    }
Jasmine
  • 5,186
  • 16
  • 62
  • 114
  • Any ideas or thoughts? Can someone please help me with the javascript code for achieving this? I couldn't get any source in the entire internet for this. 23 views, no answers yet! – Jasmine Oct 27 '14 at 23:21
  • Share your code first. How can someone help without seeing your code? – Sam Oct 27 '14 at 23:36
  • Sam, thank you again, I do not know how to use it for my gridview. Look, I do not have a table, but gridview. The author has written only for left right arrow keys for grid if you read the last line what he mentioned. I want it ONLY for up and down which is not working when I pass the name of the gridview that I have. Am I doing it correct? – Jasmine Oct 27 '14 at 23:38
  • Ok, share what you have done so far. then I'll be able to fix the issue – Sam Oct 27 '14 at 23:40
  • 1
    Ok, give me some time. I'm in the middle of some work and will have a look at this soon. Cheers! – Sam Oct 28 '14 at 00:22
  • @Sam: Sure, thank you, cheers. You seem to be from Australia, if so me too ;) Cheers and I am eagerly aiting for the quick solution as business is very much behind me for this functionality for last 3 days. I never did JS coding and hence I do not know hwo to implement it – Jasmine Oct 28 '14 at 00:24
  • 1
    Yes I'm from Victoria. Where are you from? Can you also share the Page_Load and keyup and keydown JS code? – Sam Oct 28 '14 at 00:30
  • @Sam: I am from NSW, working in the heart of Sydney :) :) Ok I will edit my post above to paste the page_load code. But I am not that experienced in programming, I need to get this resolved by this noon or evening, business is badly behind me. :( :( – Jasmine Oct 28 '14 at 00:45
  • Ok since you are in a hurry have a look at these posts to figure out the solution. I'll need some time as I'm busy with work. I'll work on the solution when I get some free time. http://www.codeproject.com/Articles/25675/GridView-Rows-Navigation-Using-Arrow-Up-Down-Keys and the answer in this http://forums.asp.net/t/1200983.aspx?How%20do%20I%20set%20the%20gridview%20to%20allow%20keyboard%20commands%20such%20as%20delete%20up%20down%20etc And, follow these steps to make your header fixed when scrolling http://www.codeproject.com/Articles/614041/GridView-with-Fixed-Header-and-Scroll-Bar – Sam Oct 28 '14 at 00:50
  • @Sam: Sure, I will follow these pointers you gave in the meantime. – Jasmine Oct 28 '14 at 00:53
  • @Sam: Well none of them talk about scroll viewer moving up and down using arrow keys, I am afraid, or do I miss anything? Its all talking about fixed header, which I already have – Jasmine Oct 28 '14 at 01:09
  • Have a look at my updated answer. That solution moves the GridView with scrollbar up and down when you use arrow keys to navigate. – Sam Oct 28 '14 at 03:18

1 Answers1

1

Have a look at this SO thread

And, here's a great sample code

UPDATE

I just had a look at the code here. Auto Scrolling works fine if you wrap the GridView with a DIV as shown below. (I'm using the same code as given in this link and just added the DIV with the CSS style. Also increased the no of records displayed in the grid by changing the for loop in the code behind to n < 100)

<div class="scrollable">
        <asp:GridView ID="gridView" runat="server" AutoGenerateColumns="False" OnRowCreated="gridView_RowCreated"
            TabIndex="0" GridLines="Horizontal">
            <Columns>
                <asp:BoundField HeaderText="S#" DataField="sno">
                    <HeaderStyle HorizontalAlign="Center" VerticalAlign="Middle" Width="50px" />
                    <ItemStyle HorizontalAlign="Center" VerticalAlign="Middle" Width="50px" />
                </asp:BoundField>
                <asp:BoundField HeaderText="Random No" DataField="rndno">
                    <HeaderStyle HorizontalAlign="Center" VerticalAlign="Middle" Width="150px" />
                    <ItemStyle HorizontalAlign="Center" VerticalAlign="Middle" Width="150px" />
                </asp:BoundField>
                <asp:BoundField HeaderText="Date" DataField="date">
                    <HeaderStyle HorizontalAlign="Center" VerticalAlign="Middle" Width="100px" />
                    <ItemStyle HorizontalAlign="Center" VerticalAlign="Middle" Width="100px" />
                </asp:BoundField>
                <asp:BoundField HeaderText="Time" DataField="time">
                    <HeaderStyle HorizontalAlign="Center" VerticalAlign="Middle" Width="100px" />
                    <ItemStyle HorizontalAlign="Center" VerticalAlign="Middle" Width="100px" />
                </asp:BoundField>
            </Columns>
            <RowStyle BackColor="#FFE0C0" />
            <HeaderStyle BackColor="#FF8000" Font-Bold="True" ForeColor="White" />
            <AlternatingRowStyle BackColor="#FFC080" />
        </asp:GridView>
      </div>

And, here's the CSS

<style type="text/css">
    .scrollable {
        height: 460px;
        width: 100%;
        overflow: auto;
        border: 0;
    }
    </style>

enter image description here

UPDATE 2

  1. Comment your JavaScript code (It has a __doPostBack, which will do a postback and that causes your scroll bar to misbehave)

  2. comment the else if section of your Page_Load event, which we'll not be using since you commented your JS code

  3. Now add following code to your page

JavaScript

<script type="text/javascript">
    var SelectedRow = null;
    var SelectedRowIndex = null;
    var UpperBound = null;
    var LowerBound = null;

    window.onload = function()
    {
        UpperBound = parseInt('<%= this.gvCycles.Rows.Count %>') - 1;
        LowerBound = 0;
        SelectedRowIndex = -1;        
    }

    function SelectRow(CurrentRow, RowIndex)
    {        
        if(SelectedRow == CurrentRow || RowIndex > UpperBound || RowIndex < LowerBound) return;

        if(SelectedRow != null)
        {
            SelectedRow.style.backgroundColor = SelectedRow.originalBackgroundColor;
            SelectedRow.style.color = SelectedRow.originalForeColor;
        }

        if(CurrentRow != null)
        {
            CurrentRow.originalBackgroundColor = CurrentRow.style.backgroundColor;
            CurrentRow.originalForeColor = CurrentRow.style.color;
            CurrentRow.style.backgroundColor = '#DCFC5C';
            CurrentRow.style.color = 'Black';
        } 

        SelectedRow = CurrentRow;
        SelectedRowIndex = RowIndex;
        setTimeout("SelectedRow.focus();",0); 
    }

    function SelectSibling(e)
    { 
        var e = e ? e : window.event;
        var KeyCode = e.which ? e.which : e.keyCode;

        if(KeyCode == 40)
            SelectRow(SelectedRow.nextSibling, SelectedRowIndex + 1);
        else if(KeyCode == 38)
            SelectRow(SelectedRow.previousSibling, SelectedRowIndex - 1);

        return false;
    }
    </script>

Code Behind

protected void gvCycles_RowCreated(object sender, GridViewRowEventArgs e)
    {
        if (e.Row.RowType == DataControlRowType.DataRow && (e.Row.RowState == DataControlRowState.Normal || e.Row.RowState == DataControlRowState.Alternate))
        {
            e.Row.TabIndex = -1;
            e.Row.Attributes["onclick"] = string.Format("javascript:SelectRow(this, {0});", e.Row.RowIndex);
            e.Row.Attributes["onkeydown"] = "javascript:return SelectSibling(event);";
            e.Row.Attributes["onselectstart"] = "javascript:return false;";
        }
    }

Hope this helps.

Community
  • 1
  • 1
Sam
  • 2,917
  • 1
  • 15
  • 28
  • I commented the attributes inside my div and used the style class scrollable as above by pasting the code. Then I also commented my JS code that cointains all keyup and down events, now I see two scrollbars :D lol Well All my exiting features broken, as in row doesn't selects on arrow keydown events – Jasmine Oct 28 '14 at 04:59
  • So you didn't do what I asked. No need to comment your DIV. Just leave it there. And, don't add a new DIV with Style (I suggested this thinking that you didn't have a div). Then follow the steps in my updated answer (Update 2) – Sam Oct 28 '14 at 05:16
  • Sam, thank you, it partially works and not always. It works ONLY when I scrolldown and select the last row and then press up arrow keys. And, let me tell you, when I enable my JS code to maintain scroll position using begin request, the problem happens again, that it doesn't scroll automatically. So I am afraid it is not the close fix. Or any tweaking can be done? – Jasmine Oct 28 '14 at 05:46
  • Sam, now again I tried your code or suggestions, its not working at all and even the existing functionality – Jasmine Oct 28 '14 at 06:11
  • Any solution at all? For achieving both my existing functionality as well as the scrolling? – Jasmine Oct 28 '14 at 22:38
  • Let me know exactly what you do in your postback? or the functionality you intend to achieve. – Sam Oct 29 '14 at 22:55
  • Hi Sam, sure. For the time being I requested the users to push my current changes and I will look into this meanwhile. Well, I am on to other priority tasks, but this afternoon or evening I will post here again on this problem. SUrely, we both resolve this problem and I learn :) – Jasmine Oct 30 '14 at 01:20
  • 1
    ok, how about you vote and accept this answer as it solves your initial issue (move up-down using arrow keys) and then create a new question with your current logic so we'll focus on that? – Sam Oct 30 '14 at 01:42
  • could you please help me on this please at your free time? Lets see to it that we implemented this (Make this work) – Jasmine Nov 18 '14 at 05:03
  • Can we start fresh? Can you accept and close this and create a new question with details, what you tried and failed? I'd like to see the code behind and markup code related to the GridView. Cheers! – Sam Nov 20 '14 at 22:43