65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 JavaScript 在 ASP.NET 中实现支持 Ajax 的 Gridview

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.74/5 (33投票s)

2009 年 2 月 15 日

CPOL

5分钟阅读

viewsIcon

134364

downloadIcon

3359

我创建了一个 JavaScript Gridview,它具有与显示记录的表格格式、分页、排序、删除和在运行时更改页面大小而无需回发的相同操作。

JSGrid.gif

引言

在解释文章之前,我想感谢所有阅读我的文章并为其投票的读者。你们对我文章的赞赏给了我写更多好文章的动力。希望未来我能收到你们宝贵的评论和建议。现在我将不再浪费你们的时间,回到主题。我写这篇文章是关于“使用 JavaScript 在 ASP.NET 中实现支持 Ajax 的 Gridview”。在这篇文章中,我将向你们展示如何仅使用简单的 HTML 表格、JavaScript 和 XML HTTP 进行 Ajax 调用,而无需使用任何 ASP.NET 控件来创建一个 Gridview。

使用代码

使用此 JavaScript Gridview,您可以执行 Gridview 的常规操作,例如以表格格式显示数据、分页查看记录、在运行时排序数据而无需回发。此外,您可以删除记录并设置页面大小。

我们将在以下部分介绍本文:

  1. 从数据源请求数据。
  2. 将 Gridview 与数据绑定或创建 HTML 表格以表格格式显示数据。
  3. 创建分页控件。
  4. 在运行时设置分页大小。
  5. 从网格中删除记录。

现在让我们开始第一步。

1. 从数据源请求数据

我使用了一个 default.aspx 页面在该页面上显示一个网格。页面加载时,会在 body 标签的 onload 事件上调用 JavaScript 函数 fnFillGrid()

function fnFillGrid()
{
        GetResponse('HandleRequest.ashx?RequestType=ShowCart' ,GetCartResponse)
}

函数 fnFillGrid() 本身会调用一个 GetResponse() 函数,该函数有两个参数:一个 URL 和一个用于处理响应的函数。通过异步调用来发送请求并从服务器获取响应。

function GetResponse(url, Response)
{
    if(navigator.appName == "Microsoft Internet Explorer")
    {
	    var xhttp = new ActiveXObject("Msxml2.XMLHTTP");
	}
	else
	{
        var xhttp = new XMLHttpRequest();
    }
	xhttp.open("GET", url, true);
	
	xhttp.onreadystatechange = 
	function() 
	{
		if (xhttp.readyState == 4 && xhttp.responseText) 
		{
			validateResponse(xhttp);
			Response(xhttp.responseXML);
		}
	}
	xhttp.send(null);
}

在 URL 参数中,您会看到一个名为 handlerequest.ashx 的通用处理程序文件。请求将使用一个查询字符串 RequestType 发送到服务器上的此文件,该查询字符串确定服务器上要处理的请求类型。

从 Web 服务器,响应以 XML 格式返回。

在这里,我将向您展示服务器如何处理请求并以 XML 格式发送响应。

当一个请求发送到 Web 服务器上的 handlerequest.ashx 时,会调用一个名为 ProcessRequest() 的函数。在 ProcessRequest 函数中,我声明了一个 XmlTextWriter XML 对象。使用此 XML 对象,会在内存中创建一个 XML 文件并作为响应发送。

XmlTextWriter xml = new XmlTextWriter(context.Response.Output);
xml.WriteStartElement("Root");

要创建 XML 文件,使用了 XmlTextWritter 的三个函数:

  1. WriteStartElement(NodeName)
  2. WriteElementstring()
  3. WriteEndElement()

WriteStartElement 函数用于开始 XML 文件的 root 元素,WriteElementString() 用于创建 Root 元素的子元素。最后,WriteendElement() 用于关闭 Root 元素的标签。

XML 文件的结构将采用以下格式:

<Root>
        <Product>…….</Product> 
        <ProductId>…….</ProductId> 
          ……………………………………………. 
          ……………………………..……………… 
</Root>   

现在,使用一个数据集从存储在应用程序文件夹的 App_Data 文件夹中的 XML 文件 cart.xml 读取数据。

从数据源读取数据后,将记录插入到 Root 元素的子元素中,位于 <Root> 标签之间,然后将其作为响应发送。

DataSet DS = new DataSet();
DS.ReadXml(HttpContext.Current.ApplicationInstance.Server.MapPath
	("~/App_Data/Cart.xml"));
double TotalMRP=0;
double TotalDiscount=0;
double GrantTotal=0;
if(DS.Tables.Count>0)
foreach (DataRow dr in DS.Tables[0].Rows)
{
    double PriceTotal =Convert.ToDouble(dr["MRP"].ToString()) - 
			Convert.ToDouble(dr["Discount"].ToString());
    PriceTotal *= Convert.ToDouble(dr["Qty"].ToString());
    TotalMRP += Convert.ToDouble(dr["MRP"].ToString());
    GrantTotal += PriceTotal;
    TotalDiscount += Convert.ToDouble(dr["Discount"].ToString());
    
    xml.WriteStartElement("Product");

    xml.WriteElementString("ProductId", dr["ProductId"].ToString());
    xml.WriteElementString("ProductName", dr["ProductName"].ToString());
    xml.WriteElementString("Category", dr["Category"].ToString());
    xml.WriteElementString("MRP", dr["MRP"].ToString());
    xml.WriteElementString("Discount", dr["Discount"].ToString());
    xml.WriteElementString("Qty", dr["Qty"].ToString());
    xml.WriteElementString("PriceTotal", PriceTotal.ToString());
    xml.WriteElementString("TotalMRP", TotalMRP.ToString());
    xml.WriteElementString("TotalDiscount", TotalDiscount.ToString());
    xml.WriteElementString("GrantTotal", GrantTotal.ToString());
    
    xml.WriteEndElement();
}

现在响应发送到浏览器。

在第二步中,我将向您展示如何将此响应数据绑定到网格。

2. 将 Gridview 与数据绑定

我们知道响应是以 XML 格式发送的,因此数据是按标签逐个检索并存储在相应的数组中。稍后处理这些数组以形成网格数据。

var ProductNameList = XML.getElementsByTagName('ProductName'); 
var ProductIdList = XML.getElementsByTagName('ProductId');     
var MRPList = XML.getElementsByTagName('MRP');     
var DiscountList = XML.getElementsByTagName('Discount');     
var CategoryList = XML.getElementsByTagName('Category');
var QtyList = XML.getElementsByTagName('Qty');
var PriceTotalList= XML.getElementsByTagName('PriceTotal');

var TotalMRPList= XML.getElementsByTagName('TotalMRP');
var TotalDiscountList= XML.getElementsByTagName('TotalDiscount');
var GrantTotalList= XML.getElementsByTagName('GrantTotal');

现在,网格的项在这里创建。

strTable = strTable + '<tr class="gvHeader" >';

strTable = strTable + '   <td style=width:8% align=center>';
strTable = strTable + ' Delete' ;
strTable = strTable + '   </td>';

strTable = strTable + '   <td style=width:30% class=gvHeader align=center>';
strTable = strTable + ' Product Name';
strTable = strTable + '   </td>';

strTable = strTable + '   <td style=width:24%  class=gvHeader align=center>';
strTable = strTable + ' Category';
strTable = strTable + '   </td>';

strTable = strTable + '   <td style=width:10% class=gvHeader align=center>';
strTable = strTable + ' MRP';
strTable = strTable + '   </td>';

strTable = strTable + '   <td style=width:10% class=gvHeader align=center>';
strTable = strTable + ' Discount';
strTable = strTable + '   </td>';

strTable = strTable + '   <td style=width:8% class=gvHeader align=center>';
strTable = strTable + ' Quantity';
strTable = strTable + '   </td>';

strTable = strTable + '   <td style=width:10% class=gvHeader align=center >';
strTable = strTable + ' Total';
strTable = strTable + '   </td>';

strTable = strTable + '</tr>'; 

创建表格后,将其作为 innerHTML 分配给一个 div 控件 gvCart

现在我们有了一个 JavaScript Gridview。

3. 创建分页控件

为了创建分页控件,我使用了默认的页面大小 3。页数是通过将 ProductIdList 数组的长度除以页面大小来确定的。每次分页都有一个 onclick 事件,当用户单击页码时会触发该事件。

要创建页码链接,我们有这段代码。

for(var pageCount=1 ; pageCount<=Math.ceil(ProductIdList.length/PageSize);pageCount++)
{
    Pagelink= Pagelink + '<a  href=javascript:void(0) 
	onclick=javacsript:PageIndexChanging('+ (pageCount-1) + '); 
	id=a_'+ pageCount+'> ' + (pageCount) + '</a>'
}

当用户更改页面时,会调用 PageIndexChanging 函数,我们在其中更改页面内容。

在这里,我没有发送任何页面数据请求。我只是将页面行隐藏或显示,即当用户将页码从 1 更改为 2 时,属于第 2 页的所有行都会显示出来,而其他页面的所有行都会被隐藏。

以下代码执行此操作:

var arrProduct;
    arrProduct = document.getElementsByName('chkSelect');
    for (var i=0; i< arrProduct.length ; i++)
    {
      if(i >=(PageNo*PageSize) && i < (PageNo+1)*PageSize)
        document.getElementById('trSelect'+i).style.display=''
      else
        document.getElementById('trSelect'+i).style.display='none'
    }

if 条件中,您将看到我显示了属于选定页面的所有行,并将其余行隐藏。

现在进行第四步。

4. 在运行时设置分页大小

使用一个下拉列表来在运行时更改网格的页面大小。默认页面大小设置为 3

var PageSize=3;
    
if(document.getElementById('ddlPageSize'))
  PageSize = document.getElementById('ddlPageSize').value;

第一次绑定网格时,我们实际上还没有创建分页下拉列表。所以默认大小是 3。但是当我们更改页面大小时,我们就有分页下拉列表,可以从中获取页面大小的值。在这里,我们可以从下拉列表中设置网格的页面大小。

现在进入最后一步 5。

5. 从网格中删除记录

要从网格中删除记录,我们需要一个复选框来选择,一个按钮来删除记录。为此,我创建了一个名为 btnDelete 的按钮和一个名为 DeleteItem() 的函数,当用户单击删除按钮时会触发该函数。

var arrProduct;
arrProduct = document.getElementsByName('chkSelect');
var ProdIds='';
for (var i=0 ; i<arrProduct.length ; i++)
{
    if(arrProduct[i].checked)
    {
       ProdIds = ProdIds + arrProduct[i].id.substring(7,arrProduct[i].id.length) + ',';
    }
}
if(ProdIds !='')
{
    if(confirm('Are you sure want to delete selected item(s)?'))
    {
        ProdIds=ProdIds.substring(0,ProdIds.length-1)
        GetResponse('HandleRequest.ashx?RequestType=DeleteCart&ProdIds='+ 
			ProdIds,GetCartResponse);
    }
}
else
{
    alert('Please select item(s) to delete.');
}

在这个 JavaScript 函数中,我找到了所有被选中的复选框,然后将它们作为请求发送到服务器以删除这些项,并从服务器接收新的响应以用剩余的记录填充网格。复选框的值在页面更改期间得以保留。

历史

  • 2009年2月15日:初始发布
© . All rights reserved.