JQGrid: Dropdown for selecting items from a foreign table - DataValueField vs DataTextField
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 开发者_StackOverflow中文版| 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.)
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];
}
Found a good solution here: http://www.trirand.net/forum/default.aspx?g=posts&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, 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
精彩评论