问题
I am trying to achieve GridView Up and Down keyboard navigation feature, using jQuery. I have written code for the same, but with a bug that it is working only once.
Steps to reproduce the bug
- After copying my sample code to your WebForm.aspx and WebForm.aspx.cs respectively, run the form
- Click on the 2nd record (for eg.) to select the GridView record
- Press down arrow key to select the next record
- Press down arrow key again to select next record (but it won't work here)
Now, if you will click on any row again the down arrow key will work for once again.
Please indicate what I am missing here.
WebForm1.aspx
<head runat="server">
<title></title>
<style type="text/css">
.normalRow
{
background-color: White;
color: Black;
}
.selectedRowNew
{
background-color: #b0c4de;
color: Black;
}
</style>
<script src="js/jquery-1.6.1.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function () {
// The selector expression tr[id] will ensure the click event is added to only data rows since we have added id attribute
// to only data rows from code behind
$('#<%=GridView1.ClientID %> tr[id]').click(function () {
$('#<%=GridView1.ClientID %> tr[id]').removeClass("selectedRowNew").addClass("normalRow");
$(this).removeClass("normalRow").addClass("selectedRowNew");
});
$('#<%=GridView1.ClientID %> tr[id]').mouseover(function () {
$(this).css({ cursor: "default", cursor: "default" });
});
$('#<%=GridView1.ClientID %> tr[id]').keydown(function (event) {
if (event.keyCode == "40") {
$('#<%=GridView1.ClientID %> tr[id]').removeClass("selectedRowNew").addClass("normalRow");
var row = $(this).closest('tr');
var next = row.next();
next.removeClass("normalRow").addClass("selectedRowNew");
next.focus();
next.click();
}
});
});
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:GridView ID="GridView1" runat="server" OnRowDataBound="GridView1_RowDataBound">
</asp:GridView>
</div>
</form>
</body>
WebForm1.aspx.cs
protected void Page_Load(object sender, EventArgs e)
{
DataTable dt = new DataTable();
dt.Columns.Add("Id", typeof(Int32));
dt.Columns.Add("Name", typeof(String));
dt.Rows.Add(new object[] { 1, "John" });
dt.Rows.Add(new object[] { 2, "James" });
dt.Rows.Add(new object[] { 3, "Christine" });
dt.Rows.Add(new object[] { 4, "Michael" });
dt.Rows.Add(new object[] { 5, "David" });
dt.Rows.Add(new object[] { 6, "Susan" });
GridView1.DataSource = dt;
GridView1.DataBind();
}
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
e.Row.Attributes.Add("id", "0");
}
}
(updated js code) - still not working although stepping through it properly
<script type="text/javascript">
$(document).ready(function () {
// The selector expression tr[id] will ensure the click event is added to only data rows since we have added id attribute
// to only data rows from code behind
$('#<%=GridView1.ClientID %> tr[id]').click(function () {
$('#<%=GridView1.ClientID %> tr[id]').removeClass("selectedRowNew").addClass("normalRow");
$(this).removeClass("normalRow").addClass("selectedRowNew");
});
$('#<%=GridView1.ClientID %> tr[id]').mouseover(function () {
$(this).css({ cursor: "default", cursor: "default" });
});
// @freshbm: your code goes here
$("body").keydown(function (e) {
if (e.keyCode == 40) //down arrow key code
toggleRowSelectionDown();
if (e.keyCode == 38) // up arrow key code
toggleRowSelectionUp();
}); //this code detect is it up or down arrow
function toggleRowSelectionDown() {
var row = $("<%=GridView1.ClientID%> .selectedRowNew");
if (!row.is(":last-child")) { //check for last row in grid
$("<%=GridView1.ClientID%> tr[id]").removeClass("selectedRowNew").addClass("normalRow");
var next = row.next();
next.removeClass("normalRow").addClass("selectedRowNew");
}
}
function toggleRowSelectionUp() {
var row = $("<%=GridView1.ClientID%> .selectedRowNew");
if (!row.is(":last-child")) { // check for first row in grid
$("<%=GridView1.ClientID%> tr[id]").removeClass("selectedRowNew").addClass("normalRow");
var prev = row.prev();
prev.removeClass("normalRow").addClass("selectedRowNew");
}
}
});
</script>
回答1:
I've figured out your problem, you can't bind keydown on table row. But you can add listener to body for keydown:
$("body").keydown(function(e){
if(e.keyCode == 40 ) //down arrow key code
toggleRowSelectionDown();
if(e.keyCode == 38) // up arrow key code
toggleRowSelectionUp();
}); //this code detect is it up or down arrow
I have put your code in functions for easy reading and maintenance:
function toggleRowSelectionDown() {
var row = $("#<%=GridView1.ClientID%> .selectedRowNew");
if (!row.is(":last-child")) { //check for last row in grid
$("#<%=GridView1.ClientID%> tr[id]").removeClass("selectedRowNew").addClass("normalRow");
var next = row.next();
next.removeClass("normalRow").addClass("selectedRowNew");
}
}
function toggleRowSelectionUp() {
var row = $("#<%=GridView1.ClientID%> .selectedRowNew");
if (!row.is(":first-child")) { // check for first row in grid
var prev = row.prev();
if (prev.attr('id')) { // to avoid header row
$("#<%=GridView1.ClientID%> tr[id]").removeClass("selectedRowNew").addClass("normalRow");
prev.removeClass("normalRow").addClass("selectedRowNew");
}
}
}
I created this jsfiddle to demonstrate functionality: http://jsfiddle.net/Ps3WL/31/
Added check for start and end of the grid
回答2:
you can replace your line with my lines only for
(e.keycode==40) $(this).closest('tr').next().find('td:eq('+$(this).closest('td').index()+')').find('input').focus();
来源:https://stackoverflow.com/questions/15020095/gridview-up-and-down-navigation-using-jquery