原贴为英文:http://www.codeproject.com/KB/ajax/Inline_Edit_Controller.aspx
使用了webserivce
Introduction
If you ask people what the most important thing that they want for
web based application UIs, most of them will answer "I want to edit
data really fast, like in Excel!" That is a tough request. It means
that the person wants to click on a row, edit some data, then click on
another row, and have all the data saved into a database. We've found a
solution for this during TargetProcess v.2.6 development. TargetProcess is a great agile project management software (if you are not aware ;)
Problem
The ASP.NET framework provides inline editing functionality in GridView
. But sometimes, you get into situations when you cannot use this functionality:
- You cannot use it with a disabled View State.
- Performance is really bad. When you click a button to switch the
row into edit state, a post back to the server will be initiated. The
post back will happen when you save or cancel the edit mode as well.
Even if you put your grid into an
UpdatePanel
, AJAX.NET
still will update the whole grid instead of just one row, and the size
of the date in the post back remains almost the same (and large).
With bad performance, it will not be like Excel, right? So, we have to look for a solution that:
- Will not initiate post back to the server
- Will work with a disabled view state
- Will be as fast as Excel (at least, less than a second to do an action)
Solution
The Inline Edit Controller (IEC) is JavaScript solution that resolves all our problems (you will see it really soon). It has the following advantages:
- It's a cross-platform solution, you can use it in any environment: ASP, ASP.NET, PHP, JSP etc.
- It's a cross-browser solution.
- It's a very extensible solution; it's pretty simple to extend the basic behavior by adding your custom handlers.
- It can be easily integrated into existing applications without
almost any rework. You can define custom saving methods to put edited
values into a database.
Basic principles
IEC is a plain JavaScript solution that allows editing rows in a
grid. In order to have an editable row, you should mark the row in some
specific manner. Let's call this stuff "Inline Edit Panel". It
contains a button that enables inline editing as well as buttons that
save changes and cancels editing. In fact, the better way to go is to
enable editing on double click, and cancel it on Escape key. That will
be shown in more advanced examples. So far, we have simple buttons:
<asp:GridView CellPadding="0" CellSpacing="0" Width="1px"
GridLines="none" runat="server" AllowSorting="false"
AutoGenerateColumns="false" ID="uxOrders">
<asp:TemplateField>
<ItemTemplate>
<span runat="server" style="white-space: nowrap"
class="inlineEditIcon" inlineeditattribute="true"
rowid='<%# Eval("OrderID")%>'>
<img runat="server" action="edit"
title="Inline Edit" src="~/img/edit.gif" />
<img runat="server" style="display: none"
action="save" title="Save" src="~/img/save.gif" />
<img runat="server" style="display: none"
action="cancel" title="Cancel" src="~/img/cancel.gif" />
</span>
</ItemTemplate>
</asp:TemplateField>
...
Cells that are going to be editable must be located in a specific place holder as well. Let's call this stuff "Edit Area".
<asp:TemplateField HeaderText="Freight">
<ItemTemplate>
<span id="FreightIdPrefix<%# Eval("OrderID")%>">
<asp:Label ID="Label1" runat="server"
Text='<%#Eval("Freight")%>'></asp:Label>
</span>
</ItemTemplate>
</asp:TemplateField>
As you can see, the "Inline Edit Panel" has three buttons, with an extra "action
"
attribute. Each action attribute fires the corresponding event. The IEC
handles all these events and makes the corresponding changes in the
DOM. Let's review the editing process now.
1. User clicks the Edit button
- At this stage, the row switches to an editable state, and input and select boxes are appended to "Edit Areas".
- The usual text labels become invisible. It means that the Freight
label in the code above becomes invisible, and the input text field is
added to the span with
id="FreightIdPrefix777"
.
2. User changes some values and clicks the Save button
- At this stage, IEC extracts all the values from editable fields (input, select, other if any).
- Replace the label texts with new values from the editable fields.
- Create a JavaScript object that holds the edited (new) values.
- It's time to save changes into the database. IEC has no idea how to
save new data, so it just passes the JavaScript object that holds the
new values into the saving method.
3. User pushes the Cancel button
- At this stage, IEC removes editable fields ("input", "select").
- Labels become visible again.
Usage example
The idea looks really simple. But maybe, the solution is hard to
use, who knows… Only a real example can help us judge the solution.
Let's take an ASP.NET example with:
- A
GridView
control to present the data.
- A Web Service to retrieve the data and save the modified data.
- AJAX.NET to generate web methods that can be used from JavaScript.
- For example, we have a pretty simple
Order
class. We want to show all the orders in a grid.
- The
GridView
initialization is a no-brainer as well. OrderService
is a class that can retrieve orders from the database (we don't care how; maybe the GetAllOrders
method uses NHibernate, or maybe plain old SQL).
protected override void OnLoad(EventArgs e)
{
if (!IsPostBack)
{
OrderService orderService = new OrderService();
Order[] orders = orderService.GetAllOrders();
uxOrders.DataSource = orders;
uxOrders.DataBind();
...
- IEC mapping. As mentioned above, we should add columns with inline editing controls (Inline Edit Panel).
<asp:TemplateField>
<ItemTemplate>
<span id="Span1" runat="server" style="white-space:
nowrap" class="inlineEditIcon" inlineeditattribute="true"
rowid='<%# Eval("OrderID")%>'>
<img id="Img1" runat="server" action="edit"
title="Inline Edit" src="~/img/edit.gif" />
<img id="Img2" runat="server" style="display: none"
action="save" title="Save" src="~/img/save.gif" />
<img id="Img3" runat="server" style="display: none"
action="cancel" title="Cancel"
src="~/img/cancel.gif" />
</span>
</ItemTemplate>
</asp:TemplateField>
And insert all the required "Edit Areas".
Collapse
<asp:GridView CellPadding="0" CellSpacing="0" Width="1px"
GridLines="none" runat="server" AllowSorting="false"
AutoGenerateColumns="false" ID="uxOrders">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<span priorityname='<%#Eval("Priority")%>'
id="PriorityIdPrefix<%# Eval("OrderID")%>">
<span>
<%#GetPriorityHTML(Container.DataItem)%>
</span
</span>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Freight">
<ItemTemplate>
<span id="FreightIdPrefix<%# Eval("OrderID")%>">
<asp:Label ID="Label1" runat="server"
Text='<%#Eval("Freight")%>'></asp:Label>
</span>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Ship Name">
<ItemTemplate>
<span id="ShipNameIdPrefix<%# Eval("OrderID")%>">
<asp:Label ID="Label1" runat="server"
Text='<%#Eval("ShipName")%>'></asp:Label>
</span>
</ItemTemplate>
</asp:TemplateField>
...
As you can see, the "Edit Areas" have a composite ID that consists of two parts: "Edit Area prefix + itemID". Such an ID is required to make each row unique.
- Now, we should create an IEC instance, and the
EditAreaSettings
instances (see below) for each "Edit Area".
var editAreasSettings = new Array();
var shipNameEditAreaSettings = new EditAreaSettings("ShipName",
"ShipNameIdPrefix",null, true);
editAreasSettings.push(shipNameEditAreaSettings);
var freightSettings = new EditAreaSettings("Freight","FreightIdPrefix");
freightSettings.onSelectValue = onSelectFreightValueHandler;
editAreasSettings.push(freightSettings);
var prioritySettings = new EditAreaSettings("Priority",
"PriorityIdPrefix","uxPriorities");
prioritySettings.onRenderEditedValue = onRenderPriorityValue;
prioritySettings.onSelectValue = onSelectPriorityValue;
editAreasSettings.push(prioritySettings);
var inlineEditController = new InlineEditController('<%=uxOrders.ClientID%>',
editAreasSettings, onSaveEventHandler, true);
EditAreaSettings( areaName, areaPrefix , dataSourceControlID, isFocused)
Arguments:
-
areaName
– used by IEC to map the edited values to the retObj
that is passed into onSaveEventHandler
.
-
areaPrefix
– used by IEC to find the edit area.
-
dataSourceControlID
– data source control ID that has a collection of predefined values.
-
isFocused - boolean value that specifies whether the edit area will have a focus.
onRenderPriorityValue
and onSelectPriorityValue
are custom handlers that are implemented outside of IEC. It is
impossible to implement all the cases of editing, and for specific
situations, you have to create custom handlers. For example, the
Priority column is an image. When the row is in the usual state, it
shows the priority icon, but when the row is in an editable state, it
should show the select box.
The code of onRenderPriorityValue
and onSelectPriorityValue
are out of the scope for this article; it will be described in Part II (architecture, extensibility, and stuff like that).
- We are getting closer to the final. Let's add the saving handler.
IEC is quite agnostic to data saving, and does not care how you will
implement that. All it needs is a method call that does all the job.
function onSaveEventHandler(retOb)
{
retObj.OrderID = retObj.itemID;
TargetProcess.DaoTraining.BusinessLogicLayer.OrderService.UpdateOrder(retObj,
onRequestComplete,
onErrorRequest);
}
The UpdateOrder
method will be fired on the save event. It has only one input parameter, retObj
, which holds all the edited values. IEC maps the edited values into retObj
using the keys from EditAreaSettings
(for example, shipName
, Freight
). Fortunately, I mapped the "Edit Areas" for IEC to be consistent with the Order
class, except retObj.itemID
that is created by IEC. As a result, retObj
can be casted to the Order
class. I had to do one extra assignment to make retObj
completely consistent with Order
.
retObj.OrderID = retObj.ItemID
The onSaveEventHandler
handler is completely consistent with the web method.
[ScriptService]
public class OrderService : WebService
{
[WebMethod]
public string UpdateOrder(Order order)
{
OrderDao OrderDao = DaoFactory.GetDaoFactory().GetOrderDao();
bool isUpdated = OrderDao.UpdateOrder(order);
if (isUpdated)
return "The order '" + order.OrderID + "' is successfully updated.";
else
return "Unable to find order '" + order.OrderID + "'.";
}
…
I'm using the web service to save the order, but it's not necessary.
It's a pretty flexible approach that allows other mechanisms to save
the data.
分享到:
相关推荐
7. 最后,为了提高用户体验,可以考虑使用AJAX技术实现异步双击事件处理,避免每次双击都需要刷新整个页面,提高网页的响应速度。 通过以上步骤,你可以实现一个功能完善的ASP.NET GridView双击事件处理系统。这个...
本主题将深入探讨如何利用ASP.NET GridView的双击事件来实现用户双击某行时,弹出一个窗口显示该行的详细信息。 首先,我们需要在ASP.NET页面上添加一个GridView控件,并将其与数据源(如SqlDataSource或...
实例195 实现选中、编辑和删除GridView中的 商品信息 310 实例196 供求信息网审核发布信息 (审核权限设置) 312 实例197 获取GridView控件中隐藏的列值 314 实例198 在GridView控件中实现商品信息 自动编号 315 ...
27. 数据插入:在FooterTemplate中添加编辑控件,通过处理InsertCommand事件,实现在GridView末尾插入新记录。 28. 数据删除确认:在删除操作前弹出确认对话框,增加用户操作的安全性。 29. 数据绑定表达式:使用...
通过示例演示如何在`GridView`控件中实现成绩小于60分的单元格显示为红色的效果。 - **5.11 DataList控件使用** - **示例108**:`DataList`控件分页。介绍如何实现`DataList`控件的分页功能。 - **示例109**:...
Jquery数据绑定分页源码 功能介绍: 用jquery模仿gridview绑定数据,实现了jquery版gridvew,双击单元格个修改该条记录信息,分页采用ajax无刷新分页,带翻页效果,右键菜单可以删除数据,测试无误
9.33 双击单元格变为可编辑 9.34 鼠标经过表格时列变色 9.35 鼠标选择表格中的多行 9.36 使用JavaScript向表格中写入数据 9.37 类C# GridView的编辑效果(一) 9.38 类C# GridView的编辑效果(二) 第10章 单选框和...
9.33 双击单元格变为可编辑 9.34 鼠标经过表格时列变色 9.35 鼠标选择表格中的多行 9.36 使用JavaScript向表格中写入数据 9.37 类C# GridView的编辑效果(一) 9.38 类C# GridView的编辑效果(二) 第10章 单选框和...
这通常通过在 DataGrid 的 `ItemDataBound` 事件中,为行或单元格添加 `onclick` 或 `ondblclick` 事件处理程序来实现。这些处理程序可以打开新窗口或直接更改当前页面的 URL。 6. **表格超链接列传递参数**: 在 ...
7. **使用Control对象**:例如,通过`DataGrid.Item.Cells[index]`访问单元格内容,`LinkButton`的`Attributes.Add`方法添加事件处理,这些是ASP.NET中控制台操作的基本方式。 8. **服务器端与客户端交互**:ASP...