views:

912

answers:

3

Suppose Items and ItemTypes have numeric primary keys ItemID and ItemTypeID. Each Item is assigned an ItemType.

I have a JQGrid to edit Items. When not in edit mode, I would like to see the name of the ItemType, not the ItemTypeID:

    TYPE       | TITLE
    -----------+--------------------
    Category A | Item 1
    Category A | Item 2
    Category B | Item 3
    Category B | Item 4

In edit mode, I want to see a dropdown that displays the ItemType text, but that returns the ItemTypeID to the server.

Here's what I have so far (using the ASP.NET wrapper for JQGrid):

<trirand:jqgrid id="Grid1" runat="server" ... >
    <columns>
        <trirand:jqgridcolumn datafield="ItemID" editable="false" visible="false" width="50" primarykey="true" />
        <trirand:jqgridcolumn datafield="ItemTypeID" editable="true" edittype="DropDown" editorcontrolid="ItemTypes" />
        <trirand:jqgridcolumn datafield="Title" editable="true" sortable="true" />
        ...
    </columns>
</trirand:jqgrid>
<asp:sqldatasource runat="server" id="ItemTypesDatasource" connectionstring="<%$ ConnectionStrings:Main %>" selectcommand="Select ItemTypeID,Title from ItemTypes order by Title" />
<asp:dropdownlist runat="server" id="ItemTypes" datasourceid="ItemTypesDatasource" datavaluefield="ItemTypeID" datatextfield="Title" />

The problem is that when not in edit mode, it displays the numeric ItemTypeID, rather than the text labels:

    TYPE       | TITLE
    -----------+--------------------
    100123     | Item 1
    100123     | Item 2
    100124     | Item 3
    100124     | Item 4

Is there any way to have JQGrid respect the distinction between DataValueField and DataTextField? (Either using the jQuery API or the ASP.NET plugin.)

A: 

Herb, the problem is that you are using the datafield="ItemTypeID". You have to change it to something like CategoryTitle.

Here is also an example http://www.trirand.net/examples/editing_data/edit_types/default.aspx

João Guilherme
Please reread the question - this doesn't really help. The problem is that I want to store the ID (e.g. ItemTypeID) but display the name (e.g. Title)
Herb Caudill
A: 

Found a good solution here: http://www.trirand.net/forum/default.aspx?g=posts&amp;t=168

The idea is to handle the CellBinding event on the grid, and look up the text corresponding to the ID that the cell contains.

protected void JQGrid1_CellBinding(object sender, Trirand.Web.UI.WebControls.JQGridCellBindEventArgs e)
   {
      if (e.ColumnIndex == 1) // index of your dropdown column
      {
         e.CellHtml = LookupText(e.CellHtml);
      } 
   }

The implementation of LookupText will depend on your situation; you might look through the column's EditValues (e.g. 1:One;2:Two;3:Three), or you might look it up in your data.

I've wrapped all of this logic into a custom column class (in VB.NET) that also populates the dropdown based on a SQL command you give it.

Public Class JqGridDropDownColumn
    Inherits Trirand.Web.UI.WebControls.JQGridColumn

    Private _SelectCommand As String
    '' /* The SQL command used to populate the dropdown. */
    '' /* We assume that the first column returned contains the value (e.g. BudgetID)  and the second column contains the text (e.g. Title). */
    Public Property SelectCommand() As String
        Get
            Return _SelectCommand
        End Get
        Set(ByVal value As String)
            _SelectCommand = value
        End Set
    End Property

    Private _DropDownNullText As String
    Public Property DropDownNullText() As String
        Get
            Return _DropDownNullText
        End Get
        Set(ByVal value As String)
            _DropDownNullText = value
        End Set
    End Property

    Private WithEvents Grid As JQGrid
    Private DropDownValues As DataTable

    Sub Init(g)
        Grid = g
        DropDownValues = ExecuteDataset(cs, CommandType.Text, Me.SelectCommand).Tables(0)
        DropDownValues.PrimaryKey = New DataColumn() {DropDownValues.Columns(0)}
        Me.EditValues = BuildEditValues(DropDownValues)
    End Sub

    '' /* Builds a string of the form "1:One;2:Two;3:Three" for use by the EditValues property. */
    '' /* This assumes that Table consists of two columns corresponding to the Value (e.g. BudgetID) and Text (e.g. Title), in that order. */ 
    Protected Function BuildEditValues(ByVal Table As DataTable) As String
        Dim Result As String = ""
        If Not String.IsNullOrEmpty(Me.DropDownNullText) Then
            Result = String.Format(":{0}", Me.DropDownNullText)
        End If
        For Each Row As DataRow In Table.Rows
            If Len(Result) > 0 Then Result &= ";"
            Result &= Row(0) & ":" & Row(1)
        Next
        Return Result
    End Function


    Private Sub Grid_CellBinding(ByVal sender As Object, ByVal e As Trirand.Web.UI.WebControls.JQGridCellBindEventArgs) Handles Grid.CellBinding
        '' /* Display the text (e.g. Title) rather than the value (e.g. BudgetID) */
        If Grid.Columns(e.ColumnIndex) Is Me Then
            e.CellHtml = LookupText(e.CellHtml)
        End If
    End Sub

    Private Function LookupText(ByVal Value As String) As String
        Dim MatchingRow As DataRow = DropDownValues.Rows.Find(Value)
        If MatchingRow IsNot Nothing Then
            Return MatchingRow(1) '' /* Column 1 is assumed to contain the text */
        Else
            Return ""
        End If
    End Function
End Class

You just need to call DropdownColumn.Init(MyGrid) on this column from the Grid's init event. Hope this helps someone.

Herb Caudill
+1  A: 

For those who use javascrpt, not the asp.net wrapper,the javascript way is using formatter and unformatter:

column model :

editoptions:{value:'1:Type1;2:Type2;3:Type3;4:Type4;5:Type5'}, formatter:showTextFmatter, unformat:unformatShowText,

my formatter, you should write your own like follows:

    function showTextFmatter (cellvalue, options, rowObject)   
    {  
       var vts={};
       if(options.colModel.editoptions.values==undefined)
       {
           vtStr = options.colModel.editoptions.value.split(';');
           for(var i =0;i<vtStr.length;i++)
           {
              kv = vtStr[i].split(':');
              vts[kv[0]]=vtStr[i]; 
           }
           options.colModel.editoptions.values = vts;
       }
       return options.colModel.editoptions.values[cellvalue];   
    }   
    function  unformatShowText (cellvalue, options)   
    { 
       return cellvalue.split(':')[0];  
    }  
Bili