使用jqGrid 4.4.0从属选择下拉列表,根据其他列值动态地从dataUrl获得第二次下拉加载

时间:2012-10-05 14:32:26

标签: asp.net asp.net-mvc-3 jqgrid

在网格中,我有一个国家下降,一个省/州下降。当用户选择国家/地区下拉菜单时,我需要将列表加载到其行中当前所选国家/地区的省/州。

我使用dataUrl从服务器(使用MVC 3,.Net)获取我的列表。我在网格列中编写了代码来定义dataInit editoption以更改dataUrl以包含我当前的国家ID。但是,似乎在dataInit事件发生之前调用了dataUrl。

为了进一步复杂化,我创建了一个基本网格视图,在整个应用程序中重复使用。这是必需的,因为我们在应用程序中有30-60个不同的网格。因此,每个网格的用户只定义列,它们的类型,编辑类型,格式等。基本网格视图只是动态生成jqgrid(它使用Vs.Net的MVC 3 frmaework中的RAZOR视图引擎编写)。

在我的razor代码(basegrid)中,每个select类型列都被定义为具有依赖列,我生成dataInit函数的代码以获取该值并更新dataUrl以获取列的定义。

我的结论:

看来我的省/州列的dataInit方法是在调用dataUrl之后调用的(即在我调用服务器获取列表之后)。如果这是dataInit的正常行为,我需要一个不同的列事件方法。

需求:

1)我不能使用标准网格'BeforeEditCell'事件,因为我可能有多个选择,这可能取决于其他列。同样,我的basegrid的用户将在运行时确定依赖关系。 (剃刀代码遍历每一列并生成网格语法)。

2)我想在调用url进行加载之前修改dataUrl。我不想执行加载列表的调用

3)我想避免将列表加载到javascript数组中。所以必须使用dataUrl。

以下是声明内容的片段。我已经删除了其他列,因为它们遵循更简单的设置,但在脚本中类似。

jQuery("#gridList").jqGrid({
    url: '/Home/HonourAwardGridData',
    datatype: "json",
    colNames: [
    'Country',
    'Province / State',
        ],
    colModel: [
{
name: 'Country',
index: 'Country',
width: 90,
sortable: true,
editable: true,
editrules: {
        edithidden: false,
required: false    },
        hidden: false,
                    edittype: 'select',
                    editoptions: {
                    dataEvents: [
                                 { type: 'change', fn: function(e) { $("#gridList").jqGrid("saveCell", saveRow, saveCol); } },
                                ],
                    dataUrl: '/Common/GetCountryValues?pageId=HonourAward',
                    buildSelect: BuildLookupEntitySelect
                    },
},
{
name: 'ProvinceState',
index: 'ProvinceState',
width: 90,
sortable: true,
editable: true,
editrules: {
        edithidden: false,
required: false    },
        hidden: false,
                    edittype: 'select',
                    editoptions: {
                    dataEvents: [
                                 { type: 'change', fn: function(e) { $("#gridList").jqGrid("saveCell", saveRow, saveCol); } },
                                ],
                    dataUrl: '/Common/GetProvinceValues?pageId=HonourAward&countryId={0}',
                        dataInit: function(elem) {
                                      var myGrid = $('#gridList');
                                      var selRowId = mygrid.jqGrid('getGridParam', 'selrow');
                                      var depColName = 'Country';
                                      var depColValue = mygrid.jqGrid('getCell', selRowId, depColName);
                                      var newDataUrl = '/Common/GetProvinceValues?pageId=HonourAward&countryId={0}';
                                      newDataUrl = newDataUrl.replace("{0}", depColValue);

                                      $("#grid").jqGrid('setColProp', depColName, {dataUrl: newDataUrl}); 
                                  },
                    buildSelect: BuildLookupEntitySelect
                    },
}
    ],
    rowNum: 200,
        cellEdit: true,
        cellSubmit: 'remote',
        cellurl: '/Home/EditHonourAwardGridData',
    multiselect: true,
    grouping: false,
    jsonReader: {
        root: "rows", //array containing actual data
        page: "page", //current page
        total: "total", //total pages for the query
        records: "records", //total number of records
        repeatitems: false,
        id: 'RecordId' //index of the column with the PK in it
    },
    toppager: true,
    shrinkToFit: false,
    rownumbers: false,
    autowidth: true,
    height: 'auto',
    autoencode: true,
    altRows : true,
    pager: '#gridPager',
    viewrecords: true,
    sortable: false, 
    afterEditCell: function (id, name, val, IRow, ICol) { 
            saveRow = IRow; 
            saveCol = ICol; 
        }
});
jQuery("#gridList").jqGrid('navGrid', '#gridPager', { search: false,
                                                      edit: true,
                                                      add: false,
                                                      del: false,
                                                      editfunc: function(id) { 
                                                            var row = jQuery("#gridList").jqGrid('getRowData', id);
                                                            var dialogTitle = 'Honours and Career Awards' + ' - ' + row['Name'];
                                                            LoadReportUpdateView('HonourAwardUpdate', dialogTitle, row.RecordId);
                                                      },
                                                      addfunc: function() { 
                                                            LoadReportAddView('HonourAwardAdd', 'Honours and Career Awards' + ' - Add New');
                                                      }
                                                    })
                          .navButtonAdd('#gridPager', {
                              caption: "Columns",
                              onClickButton: function () {
                                  ChooseColumns("#gridList", 'HonourAward', 'Select columns for Honours and Career Awards grid');
                              },
                              position: "last"
                          });
});

提前感谢您提供任何帮助或方向。

1 个答案:

答案 0 :(得分:0)

在查看jqGrid代码之后,当使用dataUrl填充选择列时,代码将始终首先调用url来加载。如果成功,则绑定其事件。如果定义则调用dataInit然后绑定所有声明的'dataEvents'。因此,在调用dataUrl之前不可能更改它。

如果jqGrid在调用url之前执行'dataInit'会很好,但是这可能会导致编辑中的bigs敲门。

我的解决方法分为两个步骤。

1)声明的初始dataUrl被定义为调用parm值为-1的服务器(我们快速返回一个空选择。

2)在dataInit方法中,我手动调用带有动态值(country的当前值)的'modified'url,然后调用buildSelect defined方法将json结果转换为选择列表。 (注意:当你看到'@'用于C#代码注入的RAZOR语法时)

var myGrid = $('#gridList');
var selRowId = myGrid.jqGrid('getGridParam', 'selrow');
var depColName = '@column.PrimaryDependentColumnName';
var depColValue = myGrid.jqGrid('getCell', selRowId, depColName);
var newDataUrl = '@html.Raw(@column.SelectLoaderUrl)';
newDataUrl = newDataUrl.replace("-1", depColValue);

$.get(newDataUrl, function(data) {
    var values = BuildLookupEntitySelectJSON(data);
    var htmlValue = $(values).html();
    $(elem).empty();
    $(elem).append(htmlValue);
});

我更喜欢'preloadUrl'事件在调用之前更改Url,因为它会使事情变得更容易和更有效。

侨!

吉姆