ajax模仿Excel,实现双击GridView单元格保存编辑
来源:互联网 发布:js怎么格式化时间戳 编辑:程序博客网 时间:2024/05/16 07:23
使用了webserivce
- Download source code - 3.65 KB
- Download demo - 71.4 KB
- Light Speed Inline Editing Using ASP.NET AJAX and Web Services (Architecture and Customization) - Part II
Introduction
If you ask people what the most important thing that they want forweb based application UIs, most of them will answer "I want to editdata really fast, like in Excel!" That is a tough request. It meansthat the person wants to click on a row, edit some data, then click onanother row, and have all the data saved into a database. We've found asolution 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 therow into edit state, a post back to the server will be initiated. Thepost back will happen when you save or cancel the edit mode as well.Even if you put your grid into an
UpdatePanel
, AJAX.NETstill will update the whole grid instead of just one row, and the sizeof 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 withoutalmost any rework. You can define custom saving methods to put editedvalues into a database.
Basic principles
IEC is a plain JavaScript solution that allows editing rows in agrid. In order to have an editable row, you should mark the row in somespecific manner. Let's call this stuff "Inline Edit Panel". Itcontains a button that enables inline editing as well as buttons thatsave changes and cancels editing. In fact, the better way to go is toenable editing on double click, and cancel it on Escape key. That willbe 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 IEChandles all these events and makes the corresponding changes in theDOM. 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 Freightlabel in the code above becomes invisible, and the input text field isadded 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 tosave new data, so it just passes the JavaScript object that holds thenew 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 touse, 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 theGetAllOrders
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();
//ShipName is a property of Order class
//ShipNameIdPrefix is an id of span element
//(EditArea of ShipName property)
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 theretObj
that is passed intoonSaveEventHandler
.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
andonSelectPriorityValue
are custom handlers that are implemented outside of IEC. It isimpossible to implement all the cases of editing, and for specificsituations, you have to create custom handlers. For example, thePriority column is an image. When the row is in the usual state, itshows the priority icon, but when the row is in an editable state, itshould show the select box.The code of
onRenderPriorityValue
andonSelectPriorityValue
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 willimplement 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 intoretObj
using the keys fromEditAreaSettings
(for example,shipName
,Freight
). Fortunately, I mapped the "Edit Areas" for IEC to be consistent with theOrder
class, exceptretObj.itemID
that is created by IEC. As a result,retObj
can be casted to theOrder
class. I had to do one extra assignment to makeretObj
completely consistent withOrder
.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 savethe data.
- ajax模仿Excel,实现双击GridView单元格保存编辑
- 如何实现双击GridView 单元格编辑单元格内容
- GridView实现双击进行编辑,更新
- GridView实现双击进行编辑,更新
- GridView实现双击进行编辑,更新
- GridView实现双击进行编辑,更新
- 如何编辑gridview单元格
- gridview 单元格单击编辑
- 编辑GridView单元格
- Flex DataGrid双击编辑单元格
- Asp.net的GridView控件实现单元格可编辑
- ASP.NET 双击Gridview编辑
- 禁止gridView中的单元格编辑
- 双击单元格变成可编辑的文本框
- 双击单元格变成可编辑的文本框
- jQuery 单击编辑 双击编辑 保存
- easyui datagrid 单元格编辑保存
- 实现可编辑单元格(使用Ajax完成后台交互)。
- 北大2590题
- Beginning ASP.NET 3.5 in C# 2008 From Novice to Professional Second Edition(ASP.NET 3.5(C#2008)入门 )翻译-第十章(3)
- 表空间作用与维护
- libvirt XML format
- Windows CE VS WIndows Mobile
- ajax模仿Excel,实现双击GridView单元格保存编辑
- 用PHP控制您的浏览器cache
- 链表
- Hibernate中Inverse和Cascade的区别
- PHP中ob_start()函数的用法
- 深入浅出Win32多线程程序设计之线程控制 一
- Ubuntu下的apt与dpkg使用简介
- 优化MyEclipse的启动速度和运行效率
- 深入浅出Win32多线程程序设计之线程控制 二