Below is the code showing each part.
Products List GridView:
The  edit button onclick event invokes ShowDetails client function  passing  productId as well as item index in the result set. This is  different  from the mechanism shown in Matt's postbut at the end will perform the same job.
Belwo is the DetailsView Control with another UpdatePanel.
Time  to explore client side script. At the begining I did just as  Matt and  registered a handler for pageLoaded client event of the ASP.NET  AJAX.  In addition I registered another handler for endRequest.
The  pageLoaded handler task is just to get the updated row and  display  color animation to indicate the it is updated. We will explore  its code  later.
The endRequest handler task is to display or hide jqModal window after the record has been retrieved and async request is ended. Just to avoid display empty widnows waiting for the DetailsView to be shown showing data. Also we will explore the details of this handler in a min.
Also I initialize jqModal instance as global on the page:
Now  I'll explore the client functions starting from the ShowDetails   function which will be called when edit button is clicked, Code is   commented for better explanation:
As  result of calling   __doPostBack('<%=updPnlProductDetail.ClientID%>', ''); an   AsyncCallBack will be initiationed and when it ends it will rise   endRequest event. So its time to explore endRequest event handler:
Call  jqmShow or jqmClose will rise onShow and onHide events of  jqModal  respectively. Event handlers are binded while create the jqModal   instance. Event handler are shown in the code above.
Server time processing now should be explored, first I'd show the onLoad event of the Page:
This  is going to be excuted each time page loaded. But I placed a  condition  to check for AsyncPostBack as well as if the AsyncPostBack  initiator  is the UpdatePanel that contains the DetailsView. Do you  remember the  __doPostBack('<%=updPnlProductDetail.ClientID%>',  ''); this is  the key beind the above code.
Final on server side is the Save:
This is just a clone from the Matt's sampel with few modifcation to match this example.
Finally and returning back to client side, when the page is loaded again the client event pageLoaded will rise, and it is time to display some animation if the record is updated:
Conclusion:
The idea of displaying on deman retrieved data on popup is very useful. Here I was showing that same idea can be done in different ways. Giving you options to choose the one that matchs your needs. This is also showing the jQuery can be combined with with ASP.NET AJAX to enhance user experiance.
Feel free to download the sample [51.14 kb] and explore the whole code. I hope that this post was helpful.
Products List GridView:
1: <asp:UpdatePanel ID="updatePanel" runat="server" UpdateMode="Conditional">
2: <ContentTemplate>
3: <asp:GridView ID="gvProducts" runat="server" OnRowDataBound="RowDataBound" AutoGenerateColumns="False"
4: AllowPaging="True" AllowSorting="True" CssClass="datatable" CellPadding="0" BorderWidth="0px"
5: GridLines="None" DataSourceID="sqldsProducts" DataKeyNames="ProductID">
6: <PagerStyle CssClass="pager-row" />
7: <RowStyle CssClass="row" />
8: <PagerSettings Mode="NumericFirstLast" PageButtonCount="7" FirstPageText="«"
9: LastPageText="»" />
10: <Columns>
11: <asp:BoundField HeaderText="ID" DataField="ProductID" SortExpression="ProductID">
12: <HeaderStyle CssClass="first" />
13: <ItemStyle CssClass="first" />
14: </asp:BoundField>
15: <asp:BoundField HeaderText="Name" DataField="ProductName" SortExpression="ProductName" />
16: <asp:BoundField HeaderText="Quantity" DataField="QuantityPerUnit" SortExpression="QuantityPerUnit" />
17: <asp:BoundField HeaderText="Unit Price" DataField="UnitPrice" SortExpression="UnitPrice"
18: DataFormatString="{0:c}">
19: <ItemStyle CssClass="money" />
20: </asp:BoundField>
21: <asp:BoundField HeaderText="In Stock" DataField="UnitsInStock" SortExpression="UnitsInStock" />
22: <asp:BoundField HeaderText="On Order" DataField="UnitsOnOrder" SortExpression="UnitsOnOrder" />
23: <asp:TemplateField>
24: <ItemTemplate>
25: <input class="button" type="button" value="Edit"
26: onclick='ShowDetails(<%#Eval("ProductID")%>,<%# Container.DataItemIndex%>)' />
27: </ItemTemplate>
28: </asp:TemplateField>
29: </Columns>
30: </asp:GridView>
31: </ContentTemplate>
32: </asp:UpdatePanel>
Belwo is the DetailsView Control with another UpdatePanel.
1: <asp:UpdatePanel ID="updPnlProductDetail" runat="server" UpdateMode="Conditional">
2: <ContentTemplate>
3: <asp:DetailsView ID="dvProductDetail" runat="server" DataSourceID="sqldsProductDetail"
4: GridLines="None" DefaultMode="Edit" AutoGenerateRows="false" Visible="false"
5: Width="100%" DataKeyNames="ProductID">
6: <Fields>
7: <asp:BoundField HeaderText="Product ID" DataField="ProductID" ReadOnly="true" />
8: <asp:TemplateField HeaderText="Product Name">
9: <EditItemTemplate>
10: <asp:TextBox ID="txtProductName" runat="server" Text='<%# Bind("ProductName") %>' />
11: <asp:RequiredFieldValidator ID="rfvProductName" runat="server" ControlToValidate="txtProductName"
12: ErrorMessage="Required" Display="Static" SetFocusOnError="true" />
13: </EditItemTemplate>
14: </asp:TemplateField>
15: <asp:TemplateField HeaderText="Quantity Per Unit">
16: <EditItemTemplate>
17: <asp:TextBox ID="txtQuantityPerUnit" runat="server" Text='<%# Bind("QuantityPerUnit") %>' />
18: <asp:RequiredFieldValidator ID="rfvQuantityPerUnit" runat="server" ControlToValidate="txtQuantityPerUnit"
19: ErrorMessage="Required" Display="Static" SetFocusOnError="true" />
20: </EditItemTemplate>
21: </asp:TemplateField>
22: <asp:TemplateField HeaderText="Unit Price">
23: <EditItemTemplate>
24: <asp:TextBox ID="txtUnitPrice" runat="server" Text='<%# Bind("UnitPrice") %>' />
25: <asp:RequiredFieldValidator ID="rfvUnitPrice" runat="server" ControlToValidate="txtUnitPrice"
26: ErrorMessage="Required" Display="Static" SetFocusOnError="true" />
27: </EditItemTemplate>
28: </asp:TemplateField>
29: <asp:TemplateField HeaderText="Units In Stock">
30: <EditItemTemplate>
31: <asp:TextBox ID="txtUnitsInStock" runat="server" Text='<%# Bind("UnitsInStock") %>' />
32: <asp:RequiredFieldValidator ID="rfvUnitsInStock" runat="server" ControlToValidate="txtUnitsInStock"
33: ErrorMessage="Required" Display="Static" SetFocusOnError="true" />
34: </EditItemTemplate>
35: </asp:TemplateField>
36: <asp:TemplateField HeaderText="Units On Order">
37: <EditItemTemplate>
38: <asp:TextBox ID="txtUnitsOnOrder" runat="server" Text='<%# Bind("UnitsOnOrder") %>' />
39: <asp:RequiredFieldValidator ID="rfvUnitsOnOrder" runat="server" ControlToValidate="txtUnitsOnOrder"
40: ErrorMessage="Required" Display="Static" SetFocusOnError="true" />
41: </EditItemTemplate>
42: </asp:TemplateField>
43: </Fields>
44: </asp:DetailsView>
45: <div class="footer">
46: <asp:Button CssClass="button" ID="btnSave" runat="server" Text="Save" OnClick="OnSave" CausesValidation="true" />
47: <asp:Button CssClass="button" ID="btnClose" runat="server" Text="Close" CausesValidation="false" />
48: </div>
49: </ContentTemplate>
50: </asp:UpdatePanel>
//  attach to the pageLoaded & endRequest events
Sys.WebForms.PageRequestManager.getInstance().add_pageLoaded(pageLoaded);        
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(endRequest);The endRequest handler task is to display or hide jqModal window after the record has been retrieved and async request is ended. Just to avoid display empty widnows waiting for the DetailsView to be shown showing data. Also we will explore the details of this handler in a min.
Also I initialize jqModal instance as global on the page:
//Initialize global jqModal instance. Review jqModal Documentation http://dev.iceburg.net/jquery/jqModal/ var $jqm = $('#divProductDetail').jqm({modal: true,overlay: 30, trigger: false, onShow: OnShowDetails, onHide: OnHideDetails});
1: function ShowDetails(productId, index)
   2: {3: //Save ProductID in a hidden field to be used by CodeBehind to bind Product Detail DetailsView [dvProductDetail]
4: $('#<%=hdnProdId.ClientID %>').val(productId);
   5:     6: //Save Item Index in a hidden field to be used by CodeBehind to RegisterDataItem for using ScriptManager
7: //This will be used to get the row that was updated on the GridView to display fading effect indicating that
8: //this row was updated.
9: $('#<%=hdnEditItemIndex.ClientID %>').val(index);
  10:     11: //Will be used but endRequest to show the DetailsView Modal Window.
12: show = true;
  13:     14: //Instruct Update panel to PostBack and update its content which is the Product DetailsView.
15: // http://encosia.com/2007/07/13/easily-refresh-an-updatepanel-using-javascript/
16: __doPostBack('<%=updPnlProductDetail.ClientID%>', '');
  17: }1: //Used to show or hide the Modal Popup that display editable Product Detail
2: function endRequest(sender,args)
   3: {4: if(show)
5: $jqm.jqmShow(); //Will rise onShow event of jqModal
6: else
7: $jqm.jqmHide(); //Will rise onHide event of jqModal
   8:         9: show = false;
  10: }11: function OnShowDetails(hash)
  12: {13: //onShow Handler of jqModal. Review jqModal Documentation. http://dev.iceburg.net/jquery/jqModal/
14: hash.w.slideDown('slow');
  15: }16: function OnHideDetails(hash)
  17: {18: //onHide Handler of jqModal. Review jqModal Documentation. http://dev.iceburg.net/jquery/jqModal/
19: hash.w.slideUp('fast',function(){hash.o.remove();});
  20: }Server time processing now should be explored, first I'd show the onLoad event of the Page:
1: protected override void OnLoad(EventArgs e)
   2: {3: //View and bind DetailsView only if AsyncPostBack is initiated and the initiator is updPnlProductDetail
4: if (smDefault.IsInAsyncPostBack && smDefault.AsyncPostBackSourceElementID == updPnlProductDetail.ClientID)
   5:     {6: // set it to true so it will render
7: this.dvProductDetail.Visible = true;
8: // force databinding
9: this.dvProductDetail.DataBind();
  10:     }11: base.OnLoad(e);
  12: }Final on server side is the Save:
1: protected void OnSave(object sender, EventArgs args)
   2: {3: if (this.Page.IsValid)
   4:     {5: // move the data back to the data object
6: this.dvProductDetail.UpdateItem(false);
7: this.dvProductDetail.Visible = false;
   8:  9: //DataItemIndex to calculate the updated row index in the GridView
10: int dataItemIndex = int.Parse(this.hdnEditItemIndex.Value);
11: if (dataItemIndex > gvProducts.PageSize)
  12:             dataItemIndex = dataItemIndex - (gvProducts.PageSize * gvProducts.PageIndex);  13:  14: // add the css class for our yellow fade
15: ScriptManager.GetCurrent(this).RegisterDataItem(
16: // The control I want to send data to
17: this.gvProducts,
18: // The data I want to send it (the row that was edited)
  19:             dataItemIndex.ToString()  20:         );  21:         22: // refresh the grid so we can see our changed
23: this.gvProducts.DataBind();
24: this.updatePanel.Update();
  25:     }  26: }Finally and returning back to client side, when the page is loaded again the client event pageLoaded will rise, and it is time to display some animation if the record is updated:
1: function pageLoaded(sender, args){
   2:     3: // the data key is the control's ID
4: var dataKey = '<%= this.gvProducts.ClientID %>';
5: var updatedRowIndex = args.get_dataItems()[dataKey];
   6:     7: // if there is a datakey for the grid, use it to
8: // identify the row that was updated
9: if(updatedRowIndex){
  10:         11: var index = parseInt(updatedRowIndex) + 1;
12: // get the row that was updated
13: var $tr = $('#'+dataKey+'>tbody>tr:eq('+index+')');
  14:         15: //Perform Color Animation on the updated row. http://plugins.jquery.com/project/color
16: $($tr).animate({}, { queue: false, duration: 7000 }).animate({ backgroundColor: "yellow" }, 1000)
17: .animate({ backgroundColor: "white" }, 1000);
  18:     }  19: }The idea of displaying on deman retrieved data on popup is very useful. Here I was showing that same idea can be done in different ways. Giving you options to choose the one that matchs your needs. This is also showing the jQuery can be combined with with ASP.NET AJAX to enhance user experiance.
Feel free to download the sample [51.14 kb] and explore the whole code. I hope that this post was helpful.
 
No comments:
Post a Comment