Implement a DataCell template and EditCell template on the same Grid column WITHOUT a server template

This post has 7 replies

Not Ranked
Posts: 8
esqmo Posted: Wed Aug 12, 2009 @ 9:26 AM
Basically I want to do this
Q10122 - HOWTO: Implement a DataCell template and EditCell template on the same Grid column

but without using a GridServerTemplate because its really slow and I dont actually need anything from the server. Bascially I want a column in my Grid to be text normally but when you edit it the text becomes a combo box. But I dont want to waste time talking to the server just to get a combo box im going to fill client side anyway.

So far ive been using a ClientTemplate

<ClientTemplates>
   <ComponentArt:ClientTemplate ID="ComboBox1_Template">
       ## mytest(DataItem) ##
   </ComponentArt:ClientTemplate>
</ClientTemplates>

this almost works but when the user stops editing the 'editing' text stays.

I keep feeling like there could be a better way to do this! Is there an easy way to get combo boxes to appear (remember im filling the entire table client side!)

Thanks very much for your help!
Not Ranked
Posts: 8
esqmo Posted: Thu Aug 13, 2009 @ 2:19 AM
All I really need is a way to find which row (if any) is currently being edited. Is there any Client-side way of doing this?
Not Ranked
Posts: 8
esqmo Posted: Thu Aug 13, 2009 @ 4:00 AM
Right ive solved it. I copied the \live_demos\demos_control-specific\grid\features\editing_dataClientMode\ code and changed it to



<Columns>
  ...
  <ComponentArt:GridColumn DataField="DEPJobID" AllowSorting="true" HeadingText="DEP Job ID" DefaultSortDirection="Descending" Align="Left" Width="70" ForeignTable="DDLTable" ForeignDataKeyField="ID" ForeignDisplayField="Value"/>
  ...
</Columns>


The ForeignTable,ForeignDataKeyField and ForeignDisplayField get the dropDownList content from a table specified server side.

And created an empty table on the server with the following code



DataTable DDLTable = new DataTable("DDLTable");

DataSet dsSrc = new DataSet();
dsSrc.Tables.Add(dt);
dsSrc.Tables.Add(DDLTable);

Grid1.DataSource = dsSrc;


This all works and without causing a postback.
Top 10 Contributor
Posts: 6,473
hwan Posted: Thu Aug 13, 2009 @ 9:25 AM
Thanks for posting your solution.

However, I'm pretty sure that EditCell server templates do not require a postback to be used, if that was the original issue you faced.
Not Ranked
Posts: 8
esqmo Posted: Fri Aug 14, 2009 @ 3:47 AM
Well when I use the ServerTemplate the grid pauses for about 2 seconds and then refreshes itself, then Load event is called. This looks like a Postback, is there anyway to get rid of the pause/refresh?
Top 10 Contributor
Posts: 6,473
hwan Posted: Wed Aug 19, 2009 @ 3:47 PM
If you're still interested in using the EditCell server template approach, post the code you were using. It sounds like the client template or CustomEditSetExpression is very slow/resource intensive.
Not Ranked
Posts: 8
esqmo Posted: Thu Aug 20, 2009 @ 4:12 AM

In the end I went for using only the ClientTemplates. I used the edit templates that come with some of the demo apps and set EditOnClickSelectedItem="false" so that I could get the currently edited row (a property that would be nice to add to the Grid) like so

  <a href="#" onclick="return edit_onclick('## DataItem.get_index() ##');">Edit</a>
  | <a href="#" onclick="return delete_onclick('## DataItem.get_index() ##');">Delete</a>
</ComponentArt:ClientTemplate>
<ComponentArt:ClientTemplate ID="EditCommandTemplate">
  <a href="#" onclick="update_onclick('## DataItem.get_index() ##')">Update</a> |
  <a href="#" onclick="iEditRow = -1; GrdJobsOnDPM.editCancel();">Cancel</a>
</ComponentArt:ClientTemplate>
<ComponentArt:ClientTemplate ID="InsertCommandTemplate">
  <a href="#" onclick="iEditRow = -1; GrdJobsOnDPM.editComplete();">Insert</a> |
  <a href="#" onclick="iEditRow = -1; GrdJobsOnDPM.editCancel();GrdJobsOnDPM.Page(0);">Cancel</a>
</ComponentArt:ClientTemplate>
function edit_onclick(index) {
  iEditRow = index;
  GrdJobsOnDPM.edit(tblJobsOnDPM.getRow(index));
}

function delete_onclick(index) {
  if (confirm("Are you sure you want to permanently delete " + arr_File_Info[index].getName() + "?")) {
    //no row being edited any more
    iEditRow = -1;
    arr_File_Info[index].deleteFile();
    deleteRow(index);
  }
}

Now iEdit row is the currently edited row!

Now I have a rather lengthy combo box template which allows me to have full control over the properties of the combo box inside!

<ComponentArt:ClientTemplate ID="DictatorDDLTemplate">
  ## ddlTemplate("Dictator", DataItem, GrdJobsOnDPM_columns.Access, arrAccessCode) ##
</ComponentArt:ClientTemplate>
<ComponentArt:ClientTemplate ID="CompanyDDLTemplate">
  ## ddlTemplate("Company", DataItem, GrdJobsOnDPM_columns.Company, arrCompanyID) ##
</ComponentArt:ClientTemplate>
<ComponentArt:ClientTemplate ID="WorkTypeDDLTemplate">
  ## ddlTemplate("WorkType", DataItem, GrdJobsOnDPM_columns.WorkType, arrWorkType) ##
</ComponentArt:ClientTemplate>
function ddlTemplate(ddlID, DataItem, column, ddlList) {
  var curValue = DataItem.getMemberAt(column).get_value();
  var curRow = DataItem.get_index(); 

  if (curRow == iEditRow) {
    var id = getId(curValue);
            
    //if this is the row currently being
    //edited then put a combo box here
    var retStr = '<select id="ddl' + ddlID + '" class="ddlInput" ' +
      'style="width: ' + (tblJobsOnDPM.get_columns()[column].get_width() - 3) + 'px" ' + '>\n';

    //add the options
    var bAddedSelectedOption = false;
                
    for (var i = 0; i < ddlList.length; i++) {

      retStr = retStr + '<option id="' + ddlList[i].id + '"';
      //select the correct option
      if (id == ddlList[i].id) {
        bAddedSelectedOption = true;
        retStr = retStr + ' selected="selected"';
      }
        retStr = retStr + '>' + ddlList[i].toString() + '</option>\n';
    }
    //if the current item isn't in the list then add it
    if (!bAddedSelectedOption) {
      retStr = retStr + '<option id=' + id + ' selected="selected">' + curValue + '</option>\n';
    }
    return retStr + '</select>\n';
  } else {
    //this row is not being edited so just display its value
    return curValue;
  }
}
function update_onclick(index) {
  iEditRow = -1;
  var curRow = tblJobsOnDPM.getRow(index);

  var ddlDictator = $get("ddlDictator");
  var ddlCompany = $get("ddlCompany");
  var ddlWorkType = $get("ddlWorkType");

  GrdJobsOnDPM.beginUpdate();

  curRow.setValue(GrdJobsOnDPM_columns.Access, ddlDictator[ddlDictator.selectedIndex].value);
  curRow.setValue(GrdJobsOnDPM_columns.Company, ddlCompany[ddlCompany.selectedIndex].value);
  curRow.setValue(GrdJobsOnDPM_columns.WorkType, ddlWorkType[ddlWorkType.selectedIndex].value);
  GrdJobsOnDPM.editComplete();
            
  GrdJobsOnDPM.endUpdate();
}
This all works very quickly and allows me to apply my own style to the combo boxes. The previous method didnt select the current selected option automatically, this does.

Top 10 Contributor
Posts: 6,473
hwan Posted: Tue Aug 25, 2009 @ 12:29 PM
This is quite nice! Thanks for posting it.

p.s. You can use Grid's undocumented EditingId to get the clientId of the currently edited row.
Page 1 of 1 (8 items)