Ext.Net 1.3 - RowExpander and RowEditor . Saving data in database. (FOR NEWBIES ONLY)

  1. #1

    Ext.Net 1.3 - RowExpander and RowEditor . Saving data in database. (FOR NEWBIES ONLY)

    Hello guys,

    I am new to ext.net
    Recently I downloaded ext.net 1.3 .
    I implemented the grid panel with sorting functionality.
    Then I liked the rowexpander plugin with the + sign. On click the details open and you can save the data.

    I needed a way to pass only the current selected row for update. And not the entire data.
    But the method which I used , passed the entire grid rows including the one selected.
    So the issue was how to let my handler know that which record is to be updated and discard/ignore the rest.
    I solved this issue.
    First I will paste my aspx code having GridPanel, Store , RowExpander and Roweditor plugins :

    My aspx file : MyDocuments.aspx
    My aspx.cs file : MyDocuments.aspx.cs
    My handlers : "Documents.ashx" for read and "DocumentSave.ashx" for POST.


    <%@ Page Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" CodeFile="MyDocuments.aspx.cs" Inherits="MyDocuments" %>
    <%@ Register Assembly="Ext.Net" Namespace="Ext.Net" TagPrefix="ext" %>
    <asp:Content ID="Content2" ContentPlaceHolderID="head" runat="Server">
    
            <link type="text/css" href="css/black-tie/jquery-ui-1.8.16.custom.css" rel="stylesheet" />    
            <script type="text/javascript" src="js/jquery-1.6.2.min.js"></script>
            <script type="text/javascript" src="js/jquery-ui-1.8.16.custom.min.js"></script>
            <link href="resources/css/examples.css" rel="stylesheet" type="text/css" />
    
        <style type="text/css">
            .style1
            {
                width: 183px;
                text-align: right;
                padding-right: 20px;
            }
            .style2
            {
                width: 194px;
            }
        </style>
        <style type="text/css">
            
            
            
    
            
            .mycalendar
            {
                display: none;
            }
            #progressBackgroundFilter
            {
                position: absolute;
                top: 0px;
                bottom: 0px;
                left: 0px;
                right: 0px;
                overflow: hidden;
                padding: 0;
                margin: 0;
                background-color: #000;
                filter: alpha(opacity=50);
                opacity: 0.5;
                z-index: 1000;
            }
            #processMessage
            {
                position: absolute;
                top: 30%;
                left: 43%;
                padding: 10px;
                width: 14%;
                z-index: 1001;
                background-color: #fff;
            }
            .style3
            {
                height: 21px;
            }
            .style4
            {
                width: 222px;
            }
            .style5
            {
                width: 32%;
            }
            .style6
            {
                height: 21px;
                width: 52%;
            }
            .style7
            {
                width: 52%;
            }
            .style9
            {
                width: 82px;
            }
            .style11
            {
                width: 155px;
            }
            .style12
            {
                width: 92px;
            }
        </style>
        
         <style type="text/css">
            .template {
                color: #fff;
                background-color: gray;
            }
            
            .white-footer .x-panel-footer{
              background-color: white !important;
           }
        </style>
        <script type="text/javascript">
            var template = '<span style="color:{0};">{1}</span>';
    
            var change = function (value) {
                return String.format(template, (value > 0) ? "green" : "red", value);
            };
    
            var pctChange = function (value) {
                return String.format(template, (value > 0) ? "green" : "red", value + "%");
            };
              
        </script>
    
        <script type="text/javascript">
            $(function() {
            // Tabs
            $('#tabs').tabs();
            });
        </script>
    
    </asp:Content>
    <asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">
     <table width="100%">
            <tr>
                <td>
                    <h2 runat="server" id="divMilestones">
                        Manage Documents
                    </h2>
                </td>
                <td>
                    <asp:ImageButton Style="float: right;" runat="server" ID="lnkbtnclose" ToolTip="Close Form"
                        ImageUrl="images/close.jpg" OnClick="lnkbtnclose_Click" CausesValidation="False" />
                </td>
            </tr>
        </table>
        <div class="gt-form  gt-content-box gt-form-row">
          <div class="gt-table-controls clearfix">
             <table style="width: 91%">
             <tr>
             <td>
             <div id="tabs">
             <ul>
                    <li><a href="#tabs-1">View/Edit</a></li>                
                    <li><a href="#tabs-2">Folder Management</a></li>                            
                </ul>
               </div>
                   <div id="tabs-1">
             <ext:ResourceManager ID="ResourceManager1" runat="server" />
             <ext:GridPanel
             ID="GridPanel1"
             runat="server"
             Title="Documents"
             Frame="true"
             AutoExpandColumn="filename"
             Height="400" Width="731">
             <Store>
              <ext:Store ID="Store1" runat="server" RemoteSort="true">
               <Proxy>
                <ext:HttpProxy Method="GET" Url="Documents.ashx" />
               </Proxy>
               <UpdateProxy>
                <ext:HttpWriteProxy Json="true" Method="POST" Url="DocumentSave.ashx" />
               </UpdateProxy>
                <WriteBaseParams>
                <ext:Parameter Name="idvalue"  Value="#{Store1}.indexOf(#{RowEditor1}.record)" Mode="Raw" />
               </WriteBaseParams>
               <AutoLoadParams>
                 <ext:Parameter Name="start" Value="={0}" />
                 <ext:Parameter Name="limit" Value="={5}" />
               </AutoLoadParams>
               <Reader>
                 <ext:JsonReader Root="Data" TotalProperty="TotalRecords">
                   <Fields>
                      <ext:RecordField Name="id" Type="Int" />
                      <ext:RecordField Name="filename" />
                      <ext:RecordField Name="size" Type="Float" />
                      <ext:RecordField Name="uploadedon" Type="Date" />                
                    </Fields>
                 </ext:JsonReader>             
               </Reader>
                <Listeners>
                    <Save Handler="Ext.Msg.alert('Submit','Submit successful');" />
                    <SaveException Handler="Ext.Msg.alert('Submit','Submit failure: ' + e.message);" />
               </Listeners>  
               <SortInfo Field="filename" Direction="ASC" />
              </ext:Store>
             </Store>
              <ColumnModel  runat="server">
                    <Columns>
                        <ext:Column ColumnID="id" Header="ID" DataIndex="id" Width="50" Sortable="true" />
                        <ext:Column Header="File Name" DataIndex="filename" Width="80" />
                        <ext:Column Header="Size" DataIndex="size" Width="50" />                    
                        <ext:DateColumn Header="Uploaded On" DataIndex="uploadedon" Width="95" Format="yyyy-MM-dd" />                    
                    </Columns>
                </ColumnModel>
                <SelectionModel>
                    <ext:RowSelectionModel ID="RowSelectionModel1" SingleSelect="true" runat="server" />
                </SelectionModel>  
                 <Plugins>
                    <ext:RowExpander ID="RowExpander" runat="server">
                       <Component>
                          <ext:FormPanel
                            ID="RowEditor1" 
                                runat="server" 
                                Padding="6" 
                                Height="180"
                                Border="false"
                                Layout="form" 
                                ForceLayout="true"
                                ButtonAlign="Right"
                                Cls="white-footer">
                                <Items>
                                   <ext:TextField ID="TextField1" 
                                        runat="server" 
                                        DataIndex="filename" 
                                        FieldLabel="File Name" 
                                        Width="250"
                                        />
                                     <ext:NumberField ID="NumberField2"
                                       runat="server"
                                       DataIndex="size"
                                       FieldLabel="Size"
                                       Width="150"
                                       />
                                        <ext:DateField ID="DateField1" 
                                        runat="server" 
                                        DataIndex="uploadedon" 
                                        FieldLabel="Upload Date" 
                                        Width="150"
                                        />    
                                </Items>
                                <Buttons>
                                   <ext:Button ID="Button1" runat="server" Text="Save" Icon="Disk">
                                      <Listeners>
                                        <Click Handler="#{RowEditor1}.getForm().updateRecord(#{RowEditor1}.record);
                                                               #{RowExpander}.collapseRow(#{Store1}.indexOf(#{RowEditor1}.record));                                                                                                                      
                                                               #{Store1}.commitChanges();
                                                               #{GridPanel1}.submitData();
                                                               " />
                                      </Listeners>
                                   </ext:Button>
                                    <ext:Button ID="Button2" runat="server" Text="Cancel" Icon="Decline">
                                        <Listeners>
                                            <Click Handler="#{RowExpander}.collapseRow(#{Store1}.indexOf(#{RowEditor1}.record));" />
                                        </Listeners>
                                    </ext:Button>
                                </Buttons>
                                
                                
                           </ext:FormPanel>
                       </Component>
                        <Listeners>
                            <Expand Handler="#{RowEditor1}.record = record; #{RowEditor1}.getForm().loadRecord(record);" />
                        </Listeners>
                    </ext:RowExpander>
                 </Plugins>    
                 <BottomBar>
                    <ext:PagingToolbar ID="PagingToolbar1" 
                        runat="server" 
                        PageSize="5"
                        DisplayInfo="true" 
                        DisplayMsg="Displaying docs {0} - {1} of {2}" 
                        EmptyMsg="No docs to display" 
                        />
                </BottomBar>
                <LoadMask ShowMask="true" />
                
             </ext:GridPanel>
           </div>
             
               <%--<div id="tabs">
                 <ul>
                    <li><a href="#tabs-1">View</a></li>
                    <li><a href="#tabs-2">Upload</a></li>
                    <li><a href="#tabs-3">Delete</a></li>
                    <li><a href="#tabs-3">Add Folder</a></li>
                </ul>
               </div>
               <div id="tabs-1">
                 
               </div>--%>
            </td>
               </tr>
             </table>
          </div>
        </div>
        
    </asp:Content>
    Now I will explain you the logic of saving the records only. Since getting the data is easy stuff. And you can handle it.

    Explanation : As you have seen in the code, in the <store> I used the <UpdateProxy> and a <ext:HttpWriteProxy
    <UpdateProxy>
                <ext:HttpWriteProxy Json="true" Method="POST" Url="DocumentSave.ashx" />
               </UpdateProxy>
                <WriteBaseParams>
                <ext:Parameter Name="idvalue"  Value="#{Store1}.indexOf(#{RowEditor1}.record)" Mode="Raw" />
               </WriteBaseParams>
    So the "idvalue" is passed to the datahandler.
    In the RowExpander plugin I used <Listener> for <Button> clicks
    <Listeners>
                                        <Click Handler="#{RowEditor1}.getForm().updateRecord(#{RowEditor1}.record);
                                                               #{RowExpander}.collapseRow(#{Store1}.indexOf(#{RowEditor1}.record));                                                                                                                      
                                                               #{Store1}.commitChanges();
                                                               #{GridPanel1}.submitData();
                                                               " />
                                      </Listeners>
    Please take care to include #{Store1}.commitChanges(); else your data will not be saved in the grid.
    The #{GridPanel1}.submitData(); is for saving data to database i.e.invoking the POST method.


    Explanation of DocumentSave.ashx with code
    +++++++++++++++++++++++++++++++++
    <%@ WebHandler Language="C#" Class="DocumentSave" %>
    
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Services;
    using Ext.Net;
    using Newtonsoft.Json;
    using System.IO;
    using System.Data;
    using System.Data.Sql;
    using System.Data.SqlClient;
    using System.Configuration;
    
    
    
    public class DocumentSave : IHttpHandler {
    
        public string conn=ConfigurationManager.ConnectionStrings["Connection"].ToString();
        public int id = 0;
        public void ProcessRequest (HttpContext context) {
            //context.Response.ContentType = "text/plain";
            //context.Response.Write("Hello World");
            
            Response sr = new Response(true);
            string value = string.Empty;
            
            string x="";
    
            if (!string.IsNullOrEmpty(context.Request["idvalue"]))
            {
                id = int.Parse(context.Request["idvalue"]);
            }
            string json = context.Request["data"];
            Dictionary<string, string>[] documents = JSON.Deserialize<Dictionary<string, string>[]>(json);
            //bool addHeader = true;
    
            int _ctr = 0;
            bool _isrecord = false;
            foreach (Dictionary<string, string> row in documents)
            {
                int _id = 0;
                string _filename = "";
                DateTime _uploaddate = DateTime.Today;                 
    
                foreach (KeyValuePair<string, string> keyValuePair in row)
                {
                    if (id == _ctr)
                        _isrecord = true;
                    else
                        break;                
                    
                    if (_isrecord == true)
                    {
                        if (keyValuePair.Key.ToString() == "id")
                            _id = int.Parse(keyValuePair.Value);
                        if (keyValuePair.Key.ToString() == "filename")
                            _filename = keyValuePair.Value;
                        if (keyValuePair.Key.ToString() == "uploadedon")
                            _uploaddate = DateTime.Parse(keyValuePair.Value);
    
                    }
                }
                if (_isrecord == true)
                {
                    string _qry = "update Documents set filename='" + _filename.Replace("'", "''") + "',";
                    _qry += "uploadedon=convert(varchar(19),'" + _uploaddate.Year.ToString() + "-" + _uploaddate.Month.ToString() + "-" + _uploaddate.Day.ToString() + " 00:00:00',120) ";
                    _qry += "where id='" + _id.ToString() + "'";
                    SqlConnection cn = new SqlConnection(conn);
                    cn.Open();
                    try
                    {
                        SqlCommand cmd = cn.CreateCommand();
                        cmd.CommandType = CommandType.Text;
                        cmd.CommandText = _qry;
                        cmd.ExecuteNonQuery();
                        
                    }
                    catch (Exception ex)
                    {
                        sr.Success = false;
                        sr.Message = ex.Message.ToString();
                    }
                    finally
                    {
                        cn.Close();
                        cn = null;
                    }
                    break;
                }
                else
                    _ctr++;
            }               
            
            sr.Write();
    
            
        }
     
        public bool IsReusable {
            get {
                return false;
            }
        }
    
    }
    Explanation
    ++++++++++
    So here I used the value "idvalue" to get the id of the edited row
    Then I used the Request["data"] from the current context.

    I took this data in a Dictionary object. And then used a counter to match the "idvalue" value.
    If matched, only that data will be saved in database. Others will be ignored.

    Some points to note
    +++++++++++++++
    I had created Document.cs class in App_Code which was used by my reader.
    So make sure you create that.


    In case if anyone is interested to learn about reading the data, I will post that too.

    Enjoy!!!

    Khush
    Last edited by geoffrey.mcgill; Apr 25, 2012 at 7:21 PM. Reason: please use [CODE] tags
  2. #2
    Hi @vbdotnetphp,

    Thanks for sharing!

Similar Threads

  1. RowExpander RowEditor
    By sharif in forum Examples and Extras
    Replies: 4
    Last Post: Nov 20, 2012, 7:47 AM
  2. [CLOSED] Saving grid state to database
    By pj_martins in forum 1.x Legacy Premium Help
    Replies: 2
    Last Post: Jan 13, 2012, 3:07 PM
  3. Replies: 2
    Last Post: Apr 14, 2011, 9:03 AM
  4. Replies: 0
    Last Post: Sep 29, 2010, 2:29 PM
  5. using DataTable as Store and saving data
    By angel colmenares in forum 1.x Help
    Replies: 0
    Last Post: Apr 16, 2010, 12:13 AM

Tags for this Thread

Posting Permissions