سؤال

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.

هل كانت مفيدة؟

المحلول

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".

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top