[CLOSED] GridPanel Dynamic Editor Fields

Page 1 of 2 12 LastLast
  1. #1

    [CLOSED] GridPanel Dynamic Editor Fields

    Hi folks,

    I have a GridPanel in which I would like to render a different Editor Control based on my custom type.
    The example below is based on yours Data Prepare example.

    The custom type is a column within the same data.
    I'd like to give the user the abilitity to use a datefield is the my custom type is "date" or a textfield if my custom type is "text". I could not figure out how to do this.

    I noticed the editor accepts only one child control. However I also noticed the Editor accept Coolite MultiField type and someone already tackle a similar question here (if it is possible to use MultiField in GridPanel? Didn't work for me either). I really don't know. Maybe the solution is use MultiField, maybe there is another solution, I am just guessing.

    At the moment I use an extended version of the asp:GridView with edit option. Similar to Data Prepare, on DataBound I render the right control (combobox, textbox), based on my criteria.

    As an additional complexity, my "Information" is recursive. If the information has parent data, I'd like to ignore the Description field and display a combobox with the list of child name/id on the parent.

    It is a level of complexity that I could not achieve so far, and I hope to find a solution as I am converting all my screens to Coolite-Only controls. I will consider any other solution. It is very important at this stage.

    Thank you.
    Leo.


    <%@ Page Language="C#" %>
    
    <%@ Import Namespace="System.Collections.Generic" %>
    <%@ Register Assembly="Coolite.Ext.Web" Namespace="Coolite.Ext.Web" TagPrefix="ext" %>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    
    <script runat="server">
        protected void Page_Load(object sender, EventArgs e)
        {
            List<Information> list = new List<Information>(5);
    
            for (int i = 1; i <= 8; i++)
            {
                Information info = new Information
                                        {
                                            ID = i,
                                            Name = ("Info Name" + i),
                                            Description = "Description" + i,
                                            InfoType = "Type" + i,
                                            Valid = Convert.ToBoolean(i % 2)
                                        };
    
                if (info.InfoType.Equals("Type3") || info.InfoType.Equals("Type5"))
                    info.Description = DateTime.Today.ToShortDateString();
                
                if (i > 5)
                    info.ParentInfo = list[1];
                else
                    list.Add(info);
            }
    
            Store1.DataSource = list;
            Store1.DataBind();
        }
    
    
        public class Information
        {
            public int ID { get; set; }
            public string Name { get; set; }
            public string Description { get; set; }
            public string InfoType { get; set; }
            public bool Valid { get; set; }
            public Information ParentInfo { get; set; }
        }
    
    </script>
    
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head id="Head1" runat="server">
        <title>Based on Coolite Toolkit Example - Data Prepare</title>
    
         <script type="text/javascript">
             function prepare(value, rec) {
                 rec.Name = value.Name;
                 rec.Description = value.Description;
                 rec.InfoType = value.InfoType;
                 rec.Valid = value.Valid;
             }
        </script>
    
    </head>
    <body>
        <form id="form1" runat="server">
            <ext:ScriptManager ID="ScriptManager1" runat="server" />
            
           <ext:Store runat="server" ID="Store1" AutoLoad="true" SerializationMode="Complex">
                <Reader>
                    <ext:JsonReader>
                        <Fields>
                            <ext:RecordField Name="ID" Type="Int" />
                            <ext:RecordField Name="Name" />
                            <ext:RecordField Name="Description" />
                            <ext:RecordField Name="Valid" />
                            <ext:RecordField Name="InfoType" />
                            <ext:RecordField Name="ParentInfo">
                                <%--<Convert Fn="prepare" />--%>
                            </ext:RecordField>
                        </Fields>
                    </ext:JsonReader>
                </Reader>
            </ext:Store>
            
             <ext:GridPanel 
                ID="GridPanel1" 
                runat="server" 
                Title="Customers" 
                ClicksToEdit="1"
                Height="300"
                StoreID="Store1">
                <ColumnModel ID="ColumnModel1" runat="server">
                <Columns>
                    <ext:Column Header="ID" DataIndex="ID" />
                    <ext:Column Header="Name" DataIndex="Name"  />
                    <ext:Column Header="Description" DataIndex="Description">
                        <Editor>
                            <ext:TextField ID="TextField1" runat="server">
                            </ext:TextField>
                        </Editor>
                    </ext:Column>
                    <ext:CheckColumn Header="Active" DataIndex="Valid" />  
                    <ext:Column Header="InfoType" DataIndex="InfoType" />         
                </Columns>
                </ColumnModel>
                <LoadMask ShowMask="true" />
            </ext:GridPanel> 
        </form>
    </body>
    </html>
  2. #2

    RE: [CLOSED] GridPanel Dynamic Editor Fields

  3. #3

    RE: [CLOSED] GridPanel Dynamic Editor Fields

    Hi Vlad,

    Thank you for your quick response. Yes, your example helps, indeed! It gives all flexibility to render controls for each row.
    The only thing I'm still not sure how to do is to set the store data for each row to the combobox case.

    Your example is brilhant, thank you for this, but it sets a 'fixed' Ext.data.SimpleStore data.
    In my case I need to set the Store DataSource for each line and rebind the dropdown and I have no clue how to do this on markup.
    Also I noticed that when I set SerializationMode="Complex", I can then see my Inner DataSource. However I can only see it on Store Convert event. Let's say:
    <ext:Store ...> ... <ext:RecordField .. > <Convert Fn="prepare" /> ...
    And the inner content is not available on BeforeEdit event:

    <ext:GridPanel ... > ... <Listeners ..> <BeforeEdit Fn="setEditor" /> ...
    For each row of my main PanelGrid I have a inner collection. If this collection is not empty, I need to show the items on the combobox.

    I am very close to accomplish what I need. Sorry to bother you again. I really tried before ask you again, but couldn't do it.
    All examples I found are using combobox inside the grid with the store binding the data from outside the grid records context. Either a separete store or fixed data.

    Can you help me, please?

    Thanks
    Leo.
  4. #4

    RE: [CLOSED] GridPanel Dynamic Editor Fields

    Never mind Vlad,

    I found what I was looking for. Just adding a new RecordField on my Store and setting IsComplex="true" it will do the trick.
    I also managed to load the collection for my Store data using Store.loadData(myInnerList).

    The only bit that is still not working is the <Convert Fn="prepare" /> function handler and maybe you can advise me.
    When I use the convertion function it actually does not display the data on the grid it comes blank.

    I am setting the fields as it is in your example:

         <script type="text/javascript">
             function prepare(value, rec) {
                 rec.City = value.City;
                 rec.StreetAddress = value.StreetAddress;
             }
        </script>
    Do I need to set all fields in the prepare function?
    Do I need to set any other property in order to the Convert event to work?

    The other odd thing is that the Convert function is on a field that is not complex and after my changes what I am receiving on rec variable is the Inner Data list elements.

    I will try my best to solve this on my own, but I am really confuse how to use the convert event.
  5. #5

    RE: [CLOSED] GridPanel Dynamic Editor Fields

    Hi,

    It is hard to say whats wrong because I need to see what data you bind and configuration of the store with reader. Does the record field with Convert function has Name which referenced on complex property?
  6. #6

    RE: [CLOSED] GridPanel Dynamic Editor Fields

    Hi Vlad,

    Yeah, I understand and agree that is hard without see the data. I will try to modify my example to show you more precisely I am doing in terms of data.

    I am not sure if I understood your question. Please have a look at my Store and prepare function.
    The Name property of the RecordField is set. I have also forced the IsComplex="false" on the Description field as it is not the field that is complex. The complex field is the InnerDetails in my example.

    Let me explain you better.

    ...
            function prepare(value, rec) {
                rec.InfoCharacteristicDetailID = value.InfoCharacteristicDetailID;
                rec.InfoCharacteristicParentID = value.InfoCharacteristicParentID;
                rec.InfoCharacteristicID = value.InfoCharacteristicID;
                rec.InfoCategoryID = value.InfoCategoryID;
                rec.ItemID = value.ItemID;
                rec.Method = value.Method;
                rec.DetailName = value.DetailName;
                rec.Description = value.Description;
                rec.Valid = value.Valid;
                rec.Flags = value.Flags;  
            }
    ...
    
          <ext:Store ID="Store1" runat="server" DataSourceID="CharDetailListDataSource" 
                OnRefreshData="Store1_Refresh" AutoLoad="true" SerializationMode="Complex"
                OnBeforeRecordUpdated="Store1_BeforeUpdated"
                OnBeforeRecordInserted="Store1_BeforeInserted"
                OnBeforeStoreChanged="Store1_BeforeChange" >
                <Reader>
                    <ext:JsonReader ReaderID="InfoCharacteristicDetailID">
                        <Fields>
                            <ext:RecordField Name="InfoCharacteristicDetailID" />
                            <ext:RecordField Name="InfoCharacteristicParentID" />
                            <ext:RecordField Name="InfoCharacteristicID" />
                            <ext:RecordField Name="InfoCategoryID" />
                            <ext:RecordField Name="ItemID" />
                            <ext:RecordField Name="Method" />
                            <ext:RecordField Name="Validation" />
                            <ext:RecordField Name="DetailName" />
                            <ext:RecordField Name="Description" DateFormat="d/m/Y" IsComplex="false" >
                                <Convert Fn="prepare" />
                            </ext:RecordField>
                            <ext:RecordField Name="Valid" Type="Boolean" />
                            <ext:RecordField Name="Flags" />
                            <ext:RecordField Name="InnerDetails" IsComplex="true" />
                        </Fields>
                    </ext:JsonReader>
                </Reader>
            </ext:Store>
    Initially when debugging, before use these IsComplex properties, the "rec" variable in the "prepare" function was returning the current row's data. By the current row I mean the row of this store bound to the grid.
    So if I debug the prepare function now with these code all fields on my rec variable will come as undefined except for the InnerDetails field.

    What I am trying to do is display different things on Description field according to the data bound. For instance, if the method field is date I will show a datefield. If is phone, I will display a textfield.
    So far, so good... this is working fine following your example.

    The part is still unfinished IS NOT using the right Editor. The part I need is to show the right info when the grid first load.
    Form what I understood, I would use the prepare function to manipulate data before it gets displayed on grid. Is my understanding correct?

    I may find a way to do without the Convert event, so I am not very worried about it to be honest. I was just trying to understand how it works.

    Based on what I just explained, I now have a more relevant question to ask you.

    Can I choose what field the Editor control will return to the the grid? What is the purpose of the Mapping/Server Mapping property on the RecordField?

    For instance, let's stick with this combobox sample. When the user clicks on the Description field it is showing a combobox with the options for the row's InnerDetails. The combobox have valueField:"InfoCharacteristicID" and displayField:"DetailName". When the user selects one of the combobox's options the data returned to grid is the ValueField. I need to keep the Valuefield and display on grid the displayfield.

    Please advice me.

    Leo
  7. #7

    RE: [CLOSED] GridPanel Dynamic Editor Fields

    Hi,

    I am confuse with prepare function. Why do move values from value to the rec? Or is it just for demonstration.

    1. Lets sort out Convert

    ExtJS docs

    convert : Function<div class="mdesc" style="margin: 0px; padding: 5px 0px; color: rgb(68, 68, 68);"><div class="long" style="margin: 0px; padding: 0px; display: block; line-height: 18px;">A function which converts the value provided by the Reader into an object that will be stored in the Record. It is passed the following parameters:<div class="mdetail-params" style="margin: 10px 0px 0px; padding: 0px 0px 0px 12px; font-size: 12px;"><ul style="margin: 12px; padding: 0px; list-style-type: circle; list-style-position: inside;"><li style="margin: 0px; padding: 0px; list-style-position: inside; list-style-type: circle;">v : Mixed<div class="sub-desc" style="margin: 5px 5px 5px 16px; padding: 0px;">The data value as read by the Reader, if undefined will use the configured <tt>defaultValue</tt>.
    <li style="margin: 0px; padding: 0px; list-style-position: inside; list-style-type: circle;">rec : Mixed<div class="sub-desc" style="margin: 5px 5px 5px 16px; padding: 0px;">The data object containing the row as read by the Reader. Depending on the Reader type, this could be an Array (ArrayReader), an object (JsonReader), or an XML element (XMLReader).[/list]
    <code style="font-style: normal; font-weight: normal; font-size: 12px; color: rgb(0, 0, 0); line-height: 16px ! important; font-family: 'Lucida Console','Courier New',Courier,monospace;"><i style="font-weight: normal; font-style: normal; color: rgb(153, 153, 153);">// example of convert <b style="font-weight: normal; color: rgb(153, 153, 153); font-style: normal;">function[/b][/i]
    <b style="font-weight: normal; color: rgb(128, 0, 128);">function[/b] fullName(v, record){
    <b style="font-weight: normal; color: rgb(128, 0, 128);">return[/b] record.name.last + <em style="font-style: normal; font-weight: normal; color: rgb(0, 128, 128); background-color: rgb(238, 238, 238);">', '[/i] + record.name.first;
    }

    <b style="font-weight: normal; color: rgb(128, 0, 128);">function[/b] location(v, record){
    <b style="font-weight: normal; color: rgb(128, 0, 128);">return[/b] !record.city ? <em style="font-style: normal; font-weight: normal; color: rgb(0, 128, 128); background-color: rgb(238, 238, 238);">''[/i] : (record.city + <em style="font-style: normal; font-weight: normal; color: rgb(0, 128, 128); background-color: rgb(238, 238, 238);">', '[/i] + record.state);
    }

    <b style="font-weight: normal; color: rgb(128, 0, 128);">var[/b] Dude = Ext.data.Record.create([
    {name: <em style="font-style: normal; font-weight: normal; color: rgb(0, 128, 128); background-color: rgb(238, 238, 238);">'fullname'[/i], convert: fullName},
    {name: <em style="font-style: normal; font-weight: normal; color: rgb(0, 128, 128); background-color: rgb(238, 238, 238);">'firstname'[/i], mapping: <em style="font-style: normal; font-weight: normal; color: rgb(0, 128, 128); background-color: rgb(238, 238, 238);">'name.first'[/i]},
    {name: <em style="font-style: normal; font-weight: normal; color: rgb(0, 128, 128); background-color: rgb(238, 238, 238);">'lastname'[/i], mapping: <em style="font-style: normal; font-weight: normal; color: rgb(0, 128, 128); background-color: rgb(238, 238, 238);">'name.last'[/i]},
    {name: <em style="font-style: normal; font-weight: normal; color: rgb(0, 128, 128); background-color: rgb(238, 238, 238);">'city'[/i], defaultValue: <em style="font-style: normal; font-weight: normal; color: rgb(0, 128, 128); background-color: rgb(238, 238, 238);">'homeless'[/i]},
    <em style="font-style: normal; font-weight: normal; color: rgb(0, 128, 128); background-color: rgb(238, 238, 238);">'state'[/i],
    {name: <em style="font-style: normal; font-weight: normal; color: rgb(0, 128, 128); background-color: rgb(238, 238, 238);">'location'[/i], convert: location}
    ]);

    <i style="font-weight: normal; font-style: normal; color: rgb(153, 153, 153);">// create the data store[/i]
    <b style="font-weight: normal; color: rgb(128, 0, 128);">var[/b] store = <b style="font-weight: normal; color: rgb(128, 0, 128);">new[/b] Ext.data.Store({
    reader: <b style="font-weight: normal; color: rgb(128, 0, 128);">new[/b] Ext.data.JsonReader(
    {
    idProperty: <em style="font-style: normal; font-weight: normal; color: rgb(0, 128, 128); background-color: rgb(238, 238, 238);">'key'[/i],
    root: <em style="font-style: normal; font-weight: normal; color: rgb(0, 128, 128); background-color: rgb(238, 238, 238);">'daRoot'[/i],
    totalProperty: <em style="font-style: normal; font-weight: normal; color: rgb(0, 128, 128); background-color: rgb(238, 238, 238);">'total'[/i]
    },
    Dude <i style="font-weight: normal; font-style: normal; color: rgb(153, 153, 153);">// recordType[/i]
    )
    });

    <b style="font-weight: normal; color: rgb(128, 0, 128);">var[/b] myData = [
    { key: 1,
    name: { first: <em style="font-style: normal; font-weight: normal; color: rgb(0, 128, 128); background-color: rgb(238, 238, 238);">'Fat'[/i], last: <em style="font-style: normal; font-weight: normal; color: rgb(0, 128, 128); background-color: rgb(238, 238, 238);">'Albert'[/i] }
    <i style="font-weight: normal; font-style: normal; color: rgb(153, 153, 153);">// notice no city, state provided <b style="font-weight: normal; color: rgb(153, 153, 153); font-style: normal;">in[/b] data object[/i]
    },
    { key: 2,
    name: { first: <em style="font-style: normal; font-weight: normal; color: rgb(0, 128, 128); background-color: rgb(238, 238, 238);">'Barney'[/i], last: <em style="font-style: normal; font-weight: normal; color: rgb(0, 128, 128); background-color: rgb(238, 238, 238);">'Rubble'[/i] },
    city: <em style="font-style: normal; font-weight: normal; color: rgb(0, 128, 128); background-color: rgb(238, 238, 238);">'Bedrock'[/i], state: <em style="font-style: normal; font-weight: normal; color: rgb(0, 128, 128); background-color: rgb(238, 238, 238);">'Stoneridge'[/i]
    },
    { key: 3,
    name: { first: <em style="font-style: normal; font-weight: normal; color: rgb(0, 128, 128); background-color: rgb(238, 238, 238);">'Cliff'[/i], last: <em style="font-style: normal; font-weight: normal; color: rgb(0, 128, 128); background-color: rgb(238, 238, 238);">'Claven'[/i] },
    city: <em style="font-style: normal; font-weight: normal; color: rgb(0, 128, 128); background-color: rgb(238, 238, 238);">'Boston'[/i], state: <em style="font-style: normal; font-weight: normal; color: rgb(0, 128, 128); background-color: rgb(238, 238, 238);">'MA'[/i]
    }
    ];</code>

    Value argument - value from current item (determines by Name)
    Rec - current item, depends from Reader, can be object, array or Xml record

    Please note that Convert function should return value (may be example from Examples Explorer not so good to clear correct using of the Convert). You should convert existing value which passed to the Convert (if value is presented) or build new value from 'rec' values and return that new value

    2. Please note that if you set SerializationMode="Complex" then whole data will be serialized. IsComplex property of any field is not using in this case. IsComplex is useful when SerializationMode="Simple" but some fields should be serialized as complex. By default, only simple types can be serialized with Simple mode. If you set IsComplex="true" for Field then it will serialized with all properties

    3. Can I choose what field the Editor control will return to the the grid? No, grid uses 'getValue' function to retrieve value. You should use renderer to convert display value

    4. When the user selects one of the combobox's options the data returned to grid is the ValueField. I need to keep the Valuefield and display on grid the displayfield.
    The following example demonstrates this
    https://examples1.ext.net/#/GridPane...Field_Mapping/

    5. What is the purpose of the Mapping/Server Mapping property on the RecordField?
    ServerMapping allows to serialize subproperty without serialization of the parent property

    The following topics should give you more details about ServerMapping and IsComplex
    http://forums.ext.net/showthread.php?threadid=13874-16-1.aspx
    http://forums.ext.net/showthread.php?threadid=19669-17-1.aspx
  8. #8

    RE: [CLOSED] GridPanel Dynamic Editor Fields

    Hi Vlad,

    Thank you so much for taking time to explain me all this.
    Yes, my prepare function was just for demonstration. Does not make sense just passing the values, I know.
    I now got a better understanding about Complex. I had to use IsComplex just for the specific column as you suggested.
    I also had a look at Mapping and though I have not used it for this scenario, I believe I understood its intention.

    Still within this scenario I have a final question, so you can close this thead after.

    I am having some problems to format the Date field.
    If you remember I mentioned earlier that my intention was to define editor agains the cell according to my data "type/v method". So I have one Column "Description" which will accept date, string and even dropdown.

    When I use the Editor for a date column and select on the calendar the date, it correctly displays my selected date on the format I specified. Let's say (d/m/Y). But once I leave the field, it display on the grid something like: "Thu Jan 28 2010 00:00:00 GMT+0000 (GMT Standard Time)". And that is what has been passed through Json and gets saved on Database.

    You mentioned here something that would solve my problem I guess.
    <Renderer Fn="Ext.util.Format.dateRenderer('d M Y')" />
    But I cannot difine renderer for the column because not all data is of type date on that specific column.
    If I try using the above code for the column it throws an exception: "Microsoft JScript runtime error: 'Date.monthNames[...]' is null or not an object".

    I also tried to set renderer only when the data is of type date, something like this:
    e.grid.getColumnModel().setRenderer(e.column,'Ext.util.Format.dateRenderer(\'d M Y\')')
    When I did this, it seems to return the right format however I don't want to set renderer for the column, but for the Cell.
    I don't know if it is possible or if there is another workarround?

    Can you help me please?

    BTW: The format I would like to save on database is something like: yyyy-mm-dd, but the format I would like to display for the user is something like: dd Month YYYY. It is possible?

    Thanks
    Leo







  9. #9

    RE: [CLOSED] GridPanel Dynamic Editor Fields

    Hi,

    You can analyze what record passed to the renderer and use appropriate function
    var myRenderer = function(value, meta, record, rowIndex, colIndex, store){
          var typeRecord = functionToDetermineType(record, rowIndex, colIndex);
          switch(typeRecord){
                 "date":
                          return Ext.util.Format.date(value, "d M Y");
                          break;
                 "money":
                           return Ext.util.Format.usMoney(value);
                         break;
          }
    }
  10. #10

    RE: [CLOSED] GridPanel Dynamic Editor Fields

    Hi Vlad,

    Very close. Nearly what I need.
    I can see that the date now is displaying correctly on the grid and also on the editor.
    Let's say, the date is showing: 15 Jan 2010.
    The problem is when I save to the database it always save something like: 2010-01-15T00:00:00.

    I can't figure out where the date gets messed. Sorry, I am still struggling with this.
    The only thing I know it has nothing to do with database as after send it throgh Json I can see it is already wrong. Even before. I got the impression it is when the Editor passes it to the grid.

    The renderer you presented seems to work perfectly, thanks a lot.
    I need to ask you where should I always look for the signatures of the functions in order to known which objects values I can catch?

    For instance, intead of:

     function(value)
    To use:

     function(value, meta, record, rowIndex, colIndex, store)
    My question is just to be able to look at the documentation and avoid disturbing you with silly questions. So there is a documentation where I should find it? Is it on ExtJs docs?

    Thanks
    Leo
Page 1 of 2 12 LastLast

Similar Threads

  1. Replies: 0
    Last Post: Aug 14, 2012, 9:14 AM
  2. [1.0] The row editor fields disappear as resizing column width
    By thchuong in forum 1.x Legacy Premium Help
    Replies: 4
    Last Post: Mar 21, 2011, 8:12 AM
  3. Replies: 18
    Last Post: Apr 14, 2010, 2:00 PM
  4. Replies: 2
    Last Post: Feb 09, 2010, 6:51 PM
  5. Dynamic fields
    By Wtower in forum 1.x Help
    Replies: 2
    Last Post: Apr 20, 2009, 5:57 PM

Posting Permissions