Reputation: 1
I have a GridView contained within a scrollable div. I also have a Button that selects a row in this GirdView based upon the text of a TextBox on the page. The row is selected just fine, but I cannot get the div to scroll to the selected row programmatically. I have attempted multiple methods involving JavaScript's "scrollTop" method, but for some reason I cannot get them to work correctly. Here is my code so far (some of the code for the "btnGo_OnClick" method is taken from an answer to a similar question on the asp.net forums, but it does not appear to be working for me):
The .aspx file:
<%@ Page Title="" Language="C#" MasterPageFile="~/Site1.Master" AutoEventWireup="true"
CodeBehind="StudentList.aspx.cs" Inherits="WebApplication1.WebForm1" %>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
<br />
<div style="overflow: scroll; height: 400px;">
<asp:GridView ID="StudentList" runat="server" AutoGenerateColumns="False" DataSourceID="DataSource1"
AllowSorting="true" CellPadding="4" DataKeyNames="Email">
<Columns>
<asp:BoundField DataField="LastName" HeaderText="Last" ReadOnly="True" SortExpression="LastName" />
<asp:BoundField DataField="FirstName" HeaderText="First" ReadOnly="True" SortExpression="FirstName" />
<asp:BoundField DataField="MiddleInitial" HeaderText="Middle" ReadOnly="True" SortExpression="MiddleInitial" />
<asp:BoundField DataField="Phone" HeaderText="Phone" ReadOnly="True" SortExpression="Phone" />
<asp:BoundField DataField="Email" HeaderText="Email" ReadOnly="True" SortExpression="Email" />
<asp:BoundField DataField="GPA" HeaderText="GPA" ReadOnly="True" SortExpression="GPA" />
<asp:TemplateField HeaderText="">
<ItemTemplate>
<asp:Button ID="btnEdit1" Text="Edit" AutoPostBack="True" runat="server" OnClick="btnEdit1_OnClick" />
 
<asp:Button ID="btnDelete" Text="Delete" AutoPostBack="True" runat="server" OnClick="btnDelete_OnClick" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
<SelectedRowStyle BackColor="Black" ForeColor="White" />
</asp:GridView>
</div>
<br />
<br />
Search by Last Name:
<asp:TextBox ID="txtSearch" runat="server"></asp:TextBox>
 
<asp:Button ID="btnGo" Text="Go" AutoPostBack="True" runat="server" OnClick="btnGo_OnClick" />
<br />
<br />
<asp:Label ID="lbl1" runat="server" Text=""></asp:Label>
<asp:AccessDataSource ID="DataSource1" runat="server" DataFile="~/App_Data/University(2).accdb"
SelectCommand="SELECT [LastName], [FirstName], [MiddleInitial], [Phone], [Email], [GPA]
FROM [Students] ORDER BY [LastName]" DeleteCommand=""></asp:AccessDataSource>
</asp:Content>
And the .aspx.cs file:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Text.RegularExpressions;
namespace WebApplication1
{
public partial class WebForm1 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void btnDelete_OnClick(object sender, EventArgs e)
{
Button b = (Button)sender;
GridViewRow containingRow = (GridViewRow)b.NamingContainer;
String strEmail = containingRow.Cells[4].Text;
DataSource1.DeleteCommand = "DELETE FROM [CoursesTaken] WHERE [StudentID] = '" + strEmail + "'";
DataSource1.Delete();
DataSource1.DeleteCommand = "DELETE FROM [Students] WHERE [Email] = '" + strEmail + "'";
DataSource1.Delete();
StudentList.DataBind();
}
protected void btnEdit1_OnClick(object sender, EventArgs e)
{
Button b = (Button)sender;
GridViewRow containingRow = (GridViewRow)b.NamingContainer;
Session["Email"] = containingRow.Cells[4].Text;
Response.Redirect("~/StudentEdit.aspx");
}
protected void btnGo_OnClick(object sender, EventArgs e)
{
int i = 0;
foreach (GridViewRow rowItem in StudentList.Rows)
{
if (rowItem.Cells[0].Text.StartsWith(txtSearch.Text))
{
StudentList.SelectedIndex = i;
int intScrollTo = this.StudentList.SelectedIndex * (int)this.StudentList.RowStyle.Height.Value;
string strScript = "";
strScript += "var gridView = document.getElementById('" + this.StudentList.ClientID + "');\n";
strScript += "if (gridView != null && gridView.parentElement != null && gridView.parentElement.parentElement != null)\n";
strScript += " gridView.parentElement.parentElement.scrollTop = " + intScrollTo + ";\n";
ScriptManager.RegisterClientScriptBlock(this.Page, this.GetType(), "btnGo_OnClick", strScript, true);
break;
}
i++;
}
}
}
}
Can someone explain why it's not working as expected?
Upvotes: 0
Views: 10587
Reputation: 1
I have it working correctly now. Here is my corrected code:
The .aspx file:
<%@ Page Title="" Language="C#" MasterPageFile="~/Site1.Master" AutoEventWireup="true"
CodeBehind="StudentList.aspx.cs" Inherits="WebApplication1.WebForm1" %>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
<script>
function focusRow(id, pxlAmount) {
var tbl = document.getElementById(id);
dTbl = tbl.parentElement.parentElement;
dTbl.scrollTop = pxlAmount;
}
</script>
<br />
<div style="overflow: scroll; height: 400px;">
<asp:GridView ID="StudentList" runat="server" AutoGenerateColumns="False" DataSourceID="DataSource1"
AllowSorting="true" CellPadding="4" DataKeyNames="Email" RowStyle-Height="40px">
<Columns>
<asp:BoundField DataField="LastName" HeaderText="Last" ReadOnly="True" SortExpression="LastName" />
<asp:BoundField DataField="FirstName" HeaderText="First" ReadOnly="True" SortExpression="FirstName" />
<asp:BoundField DataField="MiddleInitial" HeaderText="Middle" ReadOnly="True" SortExpression="MiddleInitial" />
<asp:BoundField DataField="Phone" HeaderText="Phone" ReadOnly="True" SortExpression="Phone" />
<asp:BoundField DataField="Email" HeaderText="Email" ReadOnly="True" SortExpression="Email" />
<asp:BoundField DataField="GPA" HeaderText="GPA" ReadOnly="True" SortExpression="GPA" />
<asp:TemplateField HeaderText="">
<ItemTemplate>
<asp:Button ID="btnEdit1" Text="Edit" AutoPostBack="True" runat="server" OnClick="btnEdit1_OnClick" />
 
<asp:Button ID="btnDelete" Text="Delete" AutoPostBack="True" runat="server" OnClick="btnDelete_OnClick" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
<SelectedRowStyle BackColor="Black" ForeColor="White" />
</asp:GridView>
</div>
<br />
<br />
Search by Last Name:
<asp:TextBox ID="txtSearch" runat="server"></asp:TextBox>
 
<asp:Button ID="btnGo" Text="Go" AutoPostBack="True" runat="server" OnClick="btnGo_OnClick" />
<br />
<br />
<asp:Label ID="lbl1" runat="server" Text=""></asp:Label>
<asp:AccessDataSource ID="DataSource1" runat="server" DataFile="~/App_Data/University(2).accdb"
SelectCommand="SELECT [LastName], [FirstName], [MiddleInitial], [Phone], [Email], [GPA]
FROM [Students] ORDER BY [LastName]" DeleteCommand=""></asp:AccessDataSource>
</asp:Content>
The .aspx.cs file:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Text.RegularExpressions;
namespace WebApplication1
{
public partial class WebForm1 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void btnDelete_OnClick(object sender, EventArgs e)
{
Button b = (Button)sender;
GridViewRow containingRow = (GridViewRow)b.NamingContainer;
String strEmail = containingRow.Cells[4].Text;
DataSource1.DeleteCommand = "DELETE FROM [CoursesTaken] WHERE [StudentID] = '" + strEmail + "'";
DataSource1.Delete();
DataSource1.DeleteCommand = "DELETE FROM [Students] WHERE [Email] = '" + strEmail + "'";
DataSource1.Delete();
StudentList.DataBind();
}
protected void btnEdit1_OnClick(object sender, EventArgs e)
{
Button b = (Button)sender;
GridViewRow containingRow = (GridViewRow)b.NamingContainer;
Session["Email"] = containingRow.Cells[4].Text;
Response.Redirect("~/StudentEdit.aspx");
}
protected void btnGo_OnClick(object sender, EventArgs e)
{
int i = 0;
foreach (GridViewRow rowItem in StudentList.Rows)
{
if (rowItem.Cells[0].Text.ToUpper().StartsWith(txtSearch.Text.ToUpper()))
{
StudentList.SelectedIndex = i;
int iScrollTo = (StudentList.SelectedIndex) * ((int)StudentList.RowStyle.Height.Value); /* RowStyle.Height must be explicitly defined in the opening tag of the GridView */
ScriptManager.RegisterStartupScript(StudentList, this.GetType(), "highlight",
string.Format("window.onload = function() {2} focusRow('{0}', {1}); {3};", StudentList.ClientID, iScrollTo, "{", "}"), true);
break;
}
i++;
}
}
}
}
The problem ended up being something simple: I had not explicitly defined the RowStyle.Height Property of the GridView in its opening tag. Thus, this was being evaluated as "0" during the calculation of the position to scroll to in the div.
Upvotes: 0
Reputation: 1
deostroll, I am using Internet Explorer. The rows[rowIndex].tagName propery appears to be null, as it cannot be displayed. Here is my modified code:
The .aspx file:
<%@ Page Title="" Language="C#" MasterPageFile="~/Site1.Master" AutoEventWireup="true"
CodeBehind="StudentList.aspx.cs" Inherits="WebApplication1.WebForm1" %>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
<script>
function focusRow(id, rowIndex) {
var tbl = document.getElementById(id);
var rows = tbl.childNodes[0].childNodes;
alert(rows[rowIndex].tagName);
rows[rowIndex].childNodes[0].focus();
}
</script>
<br />
<div style="overflow: scroll; height: 400px;">
<asp:GridView ID="StudentList" runat="server" AutoGenerateColumns="False" DataSourceID="DataSource1"
AllowSorting="true" CellPadding="4" DataKeyNames="Email">
<Columns>
<asp:BoundField DataField="LastName" HeaderText="Last" ReadOnly="True" SortExpression="LastName" />
<asp:BoundField DataField="FirstName" HeaderText="First" ReadOnly="True" SortExpression="FirstName" />
<asp:BoundField DataField="MiddleInitial" HeaderText="Middle" ReadOnly="True" SortExpression="MiddleInitial" />
<asp:BoundField DataField="Phone" HeaderText="Phone" ReadOnly="True" SortExpression="Phone" />
<asp:BoundField DataField="Email" HeaderText="Email" ReadOnly="True" SortExpression="Email" />
<asp:BoundField DataField="GPA" HeaderText="GPA" ReadOnly="True" SortExpression="GPA" />
<asp:TemplateField HeaderText="">
<ItemTemplate>
<asp:Button ID="btnEdit1" Text="Edit" AutoPostBack="True" runat="server" OnClick="btnEdit1_OnClick" />
 
<asp:Button ID="btnDelete" Text="Delete" AutoPostBack="True" runat="server" OnClick="btnDelete_OnClick" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
<SelectedRowStyle BackColor="Black" ForeColor="White" />
</asp:GridView>
</div>
<br />
<br />
Search by Last Name:
<asp:TextBox ID="txtSearch" runat="server"></asp:TextBox>
 
<asp:Button ID="btnGo" Text="Go" AutoPostBack="True" runat="server" OnClick="btnGo_OnClick" />
<br />
<br />
<asp:Label ID="lbl1" runat="server" Text=""></asp:Label>
<asp:AccessDataSource ID="DataSource1" runat="server" DataFile="~/App_Data/University(2).accdb"
SelectCommand="SELECT [LastName], [FirstName], [MiddleInitial], [Phone], [Email], [GPA]
FROM [Students] ORDER BY [LastName]" DeleteCommand=""></asp:AccessDataSource>
</asp:Content>
The .aspx.cs file:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Text.RegularExpressions;
namespace WebApplication1
{
public partial class WebForm1 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void btnDelete_OnClick(object sender, EventArgs e)
{
Button b = (Button)sender;
GridViewRow containingRow = (GridViewRow)b.NamingContainer;
String strEmail = containingRow.Cells[4].Text;
DataSource1.DeleteCommand = "DELETE FROM [CoursesTaken] WHERE [StudentID] = '" + strEmail + "'";
DataSource1.Delete();
DataSource1.DeleteCommand = "DELETE FROM [Students] WHERE [Email] = '" + strEmail + "'";
DataSource1.Delete();
StudentList.DataBind();
}
protected void btnEdit1_OnClick(object sender, EventArgs e)
{
Button b = (Button)sender;
GridViewRow containingRow = (GridViewRow)b.NamingContainer;
Session["Email"] = containingRow.Cells[4].Text;
Response.Redirect("~/StudentEdit.aspx");
}
protected void btnGo_OnClick(object sender, EventArgs e)
{
int i = 0;
foreach (GridViewRow rowItem in StudentList.Rows)
{
if (rowItem.Cells[0].Text.ToUpper().StartsWith(txtSearch.Text.ToUpper()))
{
StudentList.SelectedIndex = i;
ScriptManager.RegisterStartupScript(StudentList, this.GetType(), "highlight",
string.Format("window.onload = function() {2} focusRow('{0}', {1}); {3};", StudentList.ClientID, i + 1, "{", "}"), true);
break;
}
i++;
}
}
}
}
Upvotes: 0
Reputation: 11995
Some bit of javascript can help. Have a look at the following post: https://stackoverflow.com/a/4558637/145682
Here is a POC:
Markup:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="GridViewScrollIndex.Default" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<style type="text/css">
#form1
{
height: 225px;
}
</style>
<script>
function focusRow(id, rowIndex) {
var tbl = document.getElementById(id);
var rows = tbl.childNodes[0].childNodes;
rows[rowIndex].childNodes[0].focus();
document.getElementById('console').innerText = rows[rowIndex].childNodes[0].innerHTML;
}
</script>
</head>
<body>
<form id="form1" runat="server">
<div style="padding:10px; background-color:lightblue; height:105px; overflow:scroll;">
<asp:GridView ID="GridView1" runat="server">
<SelectedRowStyle BackColor="Yellow" />
</asp:GridView>
</div>
<div>
<asp:DropDownList ID="ddlSelectIndexes" runat="server"></asp:DropDownList>
<asp:Button ID="btnSelect" runat="server" Text="Select" OnClick="btnSelect_Click" />
<div id="console"></div>
</div>
</form>
</body>
</html>
Code Behind:
using System;
using System.Linq;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace GridViewScrollIndex
{
public partial class Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
var arr = Enumerable.Range(1, 100);
GridView1.DataSource = arr;
GridView1.DataBind();
ddlSelectIndexes.DataSource = arr.Select(x=> new {f1=x, f2=x});
ddlSelectIndexes.DataValueField = "f1";
ddlSelectIndexes.DataTextField = "f2";
ddlSelectIndexes.DataBind();
}
}
protected void btnSelect_Click(object sender, EventArgs e)
{
string selVal = ddlSelectIndexes.SelectedValue;
int i=0;
foreach (GridViewRow row in GridView1.Rows)
{
if (row.RowType == DataControlRowType.DataRow)
{
if (row.Cells[0].Text == selVal)
{
GridView1.SelectedIndex = i;
ScriptManager.RegisterStartupScript(GridView1, this.GetType(), "highlight",
string.Format("window.onload = function() {2} focusRow('{0}', {1}); {3};", GridView1.ClientID, i+1, "{", "}"), true);
break;
}
}
i++;
}
}
}
}
Hope this helps.
Upvotes: 0