0

I have the Trirand MVC jqGrid package, but I'm sure this question counts for jqGrid as a whole. I have a column bound to an Id:

new JQGridColumn
    {
        DataField = "PaymentSchemeId",                                           
        HeaderText = "Payment Scheme",
        DataType = typeof(ParkadePaymentScheme),
        Searchable = true,
        SearchToolBarOperation = SearchOperation.IsEqualTo,
        SearchType = SearchType.DropDown,
        SearchControlID = WidgetNames.DropDownSearchPaymentScheme,
        Editable = true,
        EditType = EditType.DropDown,
        EditorControlID = WidgetNames.DropDownEditPaymentScheme
    },

in my GridModel (view model for the grid). When in display mode, the grid displays the value of PaymentSchemeId, as expected. In edit mode, it shows a dropdown with all the payment schemes, and after selecting one, shows that one's name instead of Id, but I think that is just by side effect.

How do I set up the column to bind and store the PaymentSchemeId value while displaying the PaymentSchemeName property value?

The script rendered by the grid is rather long, but I'm including it all for fear of redacting out something meaningful.

jQuery(document).ready(function () {
    jQuery('#IndexGrid').jqGrid({
        url: '/Parkade/IndexDataRequest?jqGridID=IndexGrid',
        editurl: '/Parkade/EditRow?jqGridID=IndexGrid&editMode=1',
        mtype: 'GET',
        datatype: 'json',
        page: 1,
        colNames: ["Edit Actions", "Id", "Name", "Payment Scheme", "Active?", "Remarks"],
        colModel: [{
            "search": false,
            "sortable": false,
            "formatoptions": {
                "editbutton": true,
                "delbutton": true,
                "keys": true
            },
            "width": 50,
            "formatter": "actions",
            "name": "",
            "index": ""
        }, {
            "searchoptions": {
                "searchhidden": true
            },
            "index": "Id",
            "hidden": true,
            "key": true,
            "name": "Id"
        }, {
            "stype": "select",
            "editable": true,
            "index": "Name",
            "searchoptions": {
                "value": ":All;Brooklyn Mall:Brooklyn Mall"
            },
            "name": "Name"
        }, {
            "editoptions": {
                "value": "3:Pay on Entry;1:Pay on Exit;2:Pay on Foot"
            },
            "editable": true,
            "stype": "select",
            "edittype": "select",
            "searchoptions": {
                "value": ":All;Pay on Foot:Pay on Foot"
            },
            "name": "PaymentSchemeId",
            "index": "PaymentSchemeId"
        }, {
            "editoptions": {
                "value": "True:Yes;False:No"
            },
            "editable": true,
            "stype": "select",
            "edittype": "select",
            "searchoptions": {
                "value": ":All;True:True"
            },
            "name": "IsActive",
            "index": "IsActive"
        }, {
            "width": 300,
            "index": "Remarks",
            "searchoptions": {
                dataInit: function (el) {
                    setTimeout(function () {
                        var ec = 'AutoCompleteRemarks';
                        if (typeof (jQuery(el).autocomplete) !== 'function') alert('JQAutoComplete javascript not present on the page. Please, include jquery.jqAutoComplete.min.js');
                        jQuery(el).autocomplete(eval(ec + '_acid'));
                    }, 200);
                }
            },
            "editable": true,
            "name": "Remarks"
        }],
        viewrecords: true,
        scrollrows: false,
        prmNames: {
            id: "Id"
        },
        headertitles: true,
        autowidth: true,
        pager: jQuery('#IndexGrid_pager'),
        loadError: jqGrid_aspnet_loadErrorHandler,
        rowNum: 20,
        rowList: [10, 20, 30],
        editDialogOptions: {
            "recreateForm": true,
            errorTextFormat: function (data) {
                return 'Error: ' + data.responseText
            },
            editData: {
                __RequestVerificationToken: jQuery('input[name=__RequestVerificationToken]').val()
            }
        },
        addDialogOptions: {
            "recreateForm": true,
            errorTextFormat: function (data) {
                return 'Error: ' + data.responseText
            },
            editData: {
                __RequestVerificationToken: jQuery('input[name=__RequestVerificationToken]').val()
            }
        },
        delDialogOptions: {
            "recreateForm": true,
            errorTextFormat: function (data) {
                return 'Error: ' + data.responseText
            },
            delData: {
                __RequestVerificationToken: jQuery('input[name=__RequestVerificationToken]').val()
            }
        },
        searchDialogOptions: {
            "multipleSearch": true,
            "recreateForm": true,
            "resize": false
        },
        viewRowDialogOptions: {},
        jsonReader: {
            id: "Id"
        },
        sortorder: 'asc',
        height: '85%',
        viewsortcols: [false, 'vertical', true]
    }).navGrid('#IndexGrid_pager', {
        "edit": false,
        "add": true,
        "del": false,
        "search": true,
        "refresh": true,
        "view": false,
        "position": "left",
        "cloneToTop": true
    }, jQuery('#IndexGrid').getGridParam('editDialogOptions'), jQuery('#IndexGrid').getGridParam('addDialogOptions'), jQuery('#IndexGrid').getGridParam('delDialogOptions'), jQuery('#IndexGrid').getGridParam('searchDialogOptions'), jQuery('#IndexGrid').getGridParam('viewRowDialogOptions')).bindKeys();

    function jqGrid_aspnet_loadErrorHandler(xht, st, handler) {
        jQuery(document.body).css('font-size', '100%');
        jQuery(document.body).html(xht.responseText);
    };
    jQuery('#IndexGrid').filterToolbar({
        "searchOnEnter": false
    });
});

The response of the /Parkade/IndexDataRequest?jqGridID=IndexGrid request is:

{"page":1,"total":1,"records":1,"rows":[{"id":"1","cell":["","1","Brooklyn Mall","2","True",""]}],"userdata":{}}

This has a value of 2 for PaymentSchemeId, which I expect, because my entity has an FK to table PaymentScheme, and I store the PK of one of those records in PaymentSchemeId, hence the Id suffix and the whole need for a dropdown. The dropdown is populated server side, as you can see in the JS:

Example, and other relevant code added. I expect the PaymentSchemeId to have an int value, being an Id. I get exactly what I expected. the values for the dropdown are rendered with the column definition as

"editoptions": {
    "value": "3:Pay on Entry;1:Pay on Exit;2:Pay on Foot"

I am extremely close to copying their example verbatim, so please don't as why the GET request has a jqGridID=IndexGrid querystring that is ignored on the controller:

public JsonResult IndexDataRequest()
{
    var gridModel = new ParkadeGridModel();
    JQGridState gridState = gridModel.Grid.GetState();
    Session[SessionKeys.JqGridState] = gridState;
    SetupGrid(gridModel.Grid);
    ViewData["PaymentSchemeId_Data"] = _indexModel.PaymentSchemes;
    return gridModel.Grid.DataBind(_indexModel.Items.AsQueryable());
}

Before you ask:

private void SetupGrid(JQGrid grid, string indexMsg = null)
{
    _indexModel = BuildIndexModel();
    grid.DataUrl = Url.Action("IndexDataRequest");
    grid.EditUrl = Url.Action("EditRow");
    grid.Columns.Insert(0, new JQGridColumn
    {
        EditActionIconsColumn = true,
        EditActionIconsSettings = new EditActionIconsSettings
        {
            SaveOnEnterKeyPress = true
        },
        HeaderText = "Edit Actions",
        Width = 50,
        Searchable = false,
        Sortable = false
    });
    SetupParkadeNameDropDown(grid);
    SetupPaymentSchemeDropDown(grid);
    SetupYesNoDropDown(grid);
}

And:

private void SetupPaymentSchemeDropDown(JQGrid parkadesGrid)
{
    JQGridColumn paymentColumn = parkadesGrid.Columns.Find(c => c.DataField == "PaymentSchemeId");
    if (parkadesGrid.AjaxCallBackMode == AjaxCallBackMode.RequestData)
    {
        var searchList = _indexModel.Items.Select(m => m.PaymentSchemeName).Distinct().Select(l => new SelectListItem { Text = l, Value = l });
        paymentColumn.SearchList = searchList.ToList();
        paymentColumn.SearchList.Insert(0, new SelectListItem { Text = "All", Value = "" });

        var editList = _paymentSchemeRepository.Get().OrderBy(p => p.Name).ToList();
        paymentColumn.EditList = editList.Select(l => new SelectListItem { Text = l.Name, Value = l.Id.ToString() }).ToList();
    }
}

I think I should be using 'selector' as the formatter for this FK column, but I am still trying to figure how to use Trirand's CustomFormatter in my column definition to achieve this, because they haven't bothered to give us a DropDownFormatter option.

ProfK
  • 49,207
  • 121
  • 399
  • 775
  • Could you include JavaScript code generated by Trirand MVC jqGrid? – Oleg Oct 19 '13 at 10:26
  • @Oleg There it is, in all its glory. – ProfK Oct 19 '13 at 11:19
  • By the way, the first column (with `"formatter": "actions"`) seems have an error `"name": ""`. You should give any name like `"act"` to the column. To your main question: which data you return from `url: '/Parkade/IndexDataRequest?jqGridID=IndexGrid'` for `PaymentSchemeId`? Are there texts like "Pay on Entry", "Pay on Exit" and "Pay on Foot" or ids 1, 2, 3? You wrote: "When in display mode, the grid displays the value of PaymentSchemeId, as expected.", but it's unclear *what you expect*. You don't use `formatter:'select'` which seems me strange. – Oleg Oct 19 '13 at 11:35
  • Could you include an example of values if `PaymentSchemeId` in the JSON response from `url: '/Parkade/IndexDataRequest?jqGridID=IndexGrid'` and explain on the example what exactly you expect and what you see instead? – Oleg Oct 19 '13 at 11:37
  • Example, and other relevant code added. I expect the `PaymentSchemeId` to have an `int` value, being an Id. I get exactly what I expected. – ProfK Oct 19 '13 at 16:44

1 Answers1

1

I can't full reproduce your problem, but I recommend you to do two following steps:

  • add any name, for example name: "act" to the definition of the first "Edit Actions" column. jqGrid can't correctly work with columns having "name": "" property in colModel;
  • add formatter: "select" to the properties of the column PaymentSchemeId.

The usage of formatter: "select" will follow that the user will see the Pay on Foot instead of non-understandable id 2. The JSON response from the server should still contains 2, but jqGrid will display the value as Pay on Foot because of usage formatter: "select". The data which will be sent during Add or Edit operation will contains integers (1, 2 or 3) instead of texts chosen by the user ("Pay on Entry", "Pay on Exit", and "Pay on Foot"). So you will works only with integer ids on the server side and the user will see only the corresponding texts. I think it's what you want.

If you want that the user sees only integers then you should use "value": "3:3;1:1;2:2" instead of "value": "3:Pay on Entry;1:Pay on Exit;2:Pay on Foot".

Oleg
  • 220,925
  • 34
  • 403
  • 798
  • Thanks. Thing is, an official Trirand example/demo creates an edit actions column without a name, and I just copied that. That column works fine. My trouble now is to find a way to set that formatter; I'll use jQuery, as the Trirand docs mention no way of doing it server side. – ProfK Oct 20 '13 at 16:26
  • @ProfK: You are welcome! It seems that `JQGridColumn` has child element `Formatter` with the formatter. Like [](http://trirand.net/forum/default.aspx?g=posts&t=1458). MVC seems use some "buitin" formatters (see [here](http://www.trirand.net/aspnetmvc/grid/functionalityformatters)). If you will have problems you can set the `formatter: "select"` using `setColProp` method. See [the answer](http://stackoverflow.com/a/19427444/315935). – Oleg Oct 20 '13 at 17:15