jQgrid下拉菜单不在表单编辑中填充数据

时间:2012-03-03 15:30:08

标签: javascript json jquery jqgrid edit

所以我浪费了一整天跟踪数据,但无法找到解决方案,所以发布在这里。 以下是我的 js 代码。

<script type="text/javascript">
jq(function() {
        jq("#Grid").jqGrid({
            url:'/indyaah/crud.htm',
            datatype: 'json',
            mtype: 'GET',
            colNames:['User Id','User Name','Book Id','Book Name'],
            colModel:[
                {name:'userId',index:'userId', formatter: 'select', stype: 'select',edittype: 'select',editoptions:{value:Users()},editable:true, editrules:{required:true,edithidden:true},searchoptions:{sopt: ['eq','ne','le','ge']},hidden:true},
                {name:'userName',index:'userName', width:100,editable:false},
                {name:'bookId',index:'bookId', formatter: 'select', stype: 'select',edittype: 'select',editoptions:{value:Books()},editable:true, editrules:{required:true,edithidden:true},searchoptions:{sopt: ['eq','ne','le','ge']},hidden:true},
                {name:'BookName',index:'BookName', width:100},
                ],
            postData: { 
            },
            rowNum:5,
            altRows:true,
            hiddengrid:true,
            rowList:[5,10],
            height: "100%",
            autowidth: true,
            rownumbers: true,
            pager: '#pager',
            sortname: 'userId',
            viewrecords: true,
            sortorder: "asc",
            caption:"Details",
            emptyrecords: "Empty records",
            loadonce: false,
            autowidth:true,
            loadComplete: function() {
            },
            jsonReader : {
                root: "rows",
                page: "page",
                total: "total",
                records: "records",
                repeatitems: false,
                cell: "cell",
                id: "id"
            }
        });
        function Users()
        {
            jq.getJSON('/indyaah/readUsers.htm', function(data) {
            var len = data.rows.length;
            for ( var i = 0; i < len; i++) {
                if(i===0) html += '' + data.rows[i].userId + ' : \'' + data.rows[i].userName + '\',' ;
                else if(i===len-1) html +=  data.rows[i].userId + ' : \'' + data.rows[i].userName + '\'' ;
                else html += data.rows[i].userId + ' : \'' + data.rows[i].userName + '\',' ;
            }   
            });
            return html;
        }
        function Books()
        {
            jq.getJSON('/indyaah/readBooks.htm', function(data) {
            var len = data.rows.length;
            for ( var i = 0; i < len; i++) {
                if(i===0) html += '{\'' + data.rows[i].bookId + '\':\'' + data.rows[i].name + '\',\n' ;
                else if(i===len-1) html += '\''+ data.rows[i].bookId + '\':\'' + data.rows[i].name + '\'}' ;
                else html += '\''+ data.rows[i].bookId + '\':\'' + data.rows[i].name + '\',\n' ;
            }
            });
            return html;
        }
        jq("#Grid").jqGrid('navGrid','#pager',
                {edit:false,add:false,del:false,search:true},
                { },
                { },
                { }, 
                { 
                    sopt:['eq', 'ne', 'le', 'ge', 'cn', 'bw', 'ew'],
                    closeOnEscape: true, 
                        multipleSearch: true, 
                        closeAfterSearch: true },
                {width:500}
        );      
        jq("#Grid").navButtonAdd('#pager',
                {   caption:"Add", 
                    buttonicon:"ui-icon-plus", 
                    onClickButton: add,
                    position: "last", 
                    title:"", 
                    cursor: "pointer"
                } 
        );

        jq("#Grid").navButtonAdd('#pager',
                {   caption:"Edit", 
                    buttonicon:"ui-icon-pencil", 
                    onClickButton: edit,
                    position: "last", 
                    title:"", 
                    cursor: "pointer"
                } 
        );

        jq("#Grid").navButtonAdd('#pager',
            {   caption:"Delete", 
                buttonicon:"ui-icon-trash", 
                onClickButton: delete,
                position: "last", 
                title:"", 
                cursor: "pointer"
            } 
        );

        jq("#btnFilter").click(function(){
            jq("#Grid").jqGrid('searchGrid',
                    {multipleSearch: true, 
                        sopt:['eq']}
            );
        });


        jq("#Grid").jqGrid('filterToolbar',{stringResult: true,searchOnEnter : true, defaultSearch:"cn"});

    });
</script>

两个Jsons都有以下格式(我只显示了3-4列,但分别有8和10),

{
page: 1
records: 5
rows: [
        0: {displayName:ABC, password:null, userName:123, userId:1,…}
        1: {displayName:DEF, password:null, userName:456, userId:2,…}
        2: {displayName:GHI, password:null, userName:789, userId:3,…}
        3: {displayName:JKL, password:null, userName:234, userId:4,…}
        4: {displayName:MNO, password:null, userName:548, userId:5,…}
        5: {displayName:PQR, password:null, userName:968, userId:6,…}
]
}

{
page: 1
records: 5
rows: [
        0: {displayName:ABC,  bookName:123, bookId:1,…}
        1: {displayName:DEF,  bookName:456, bookId:2,…}
        2: {displayName:GHI,  bookName:789, bookId:3,…}
        3: {displayName:JKL,  bookName:234, bookId:4,…}
        4: {displayName:MNO,  bookName:548, bookId:5,…}
        5: {displayName:PQR,  bookName:968, bookId:6,…}
]
}

我的编辑/添加表单看起来像this 请注意,在编辑/添加中,我只使用服务器在Json中发送的一些值。!

所以基本上问题是网格加载完美但是一旦我尝试添加或编辑, 选择框为空。 当我在firebug中调试时,Controller会发送数据,但它没有加载到网格中。

那么,我在这里失踪了什么?

1 个答案:

答案 0 :(得分:4)

问题的原因很明显,但解决方案并不容易,因为jqGrid并不真正支持从服务器加载formatter: 'select'editoptions.value的使用。我试着描述问题的根源并描述解决方法。

第一个问题是$.getJSON工作异步。因此,如果将调用Users()Books(),则将从函数返回undefined值。顺便说一下,html变量在代码中确实是未定义的。

我可以建议一些解决当前问题的方法。

您只需从列定义中删除edittype: 'select', editoptions: {value: Users()}, editable: trueedittype: 'select' ,editoptions: {value: Books()}, editable: true即可。您可以在相应的success来电的$.getJSON处理程序中设置设置:

jq("#Grid").jqGrid({
    ...
});
jq.getJSON('/indyaah/readUsers.htm', function (data) {
    var len = data.rows.length, i, html = '', item;
    for (i = 0; i < len; i++) {
        item = data.rows[i];
        if (i !== 0) {
            html += ',';
        }
        html += item.userId + ":'" + item.userName + "'";
    }
    jq("#Grid").jqGrid('setColProp', 'userId', {
        edittype: 'select',
        editoptions: {value: html},
        editable: true
    });
});
jq.getJSON('/indyaah/readBooks.htm', function (data) {
    ...
    jq("#Grid").jqGrid('setColProp', 'bookId', {
        edittype: 'select',
        editoptions: {value: html},
        editable: true
    });
});

在打开“添加”或“编辑”表单时,editoptions.value的正确值已经在colModel中,并且应该正确显示选择。

在填充网格主体之前,您仍然需要使用formatter: 'select'来填充需要editoptions.value 的问题。你写道网格填充正确。我认为这意味着对'/indyaah/readUsers.htm'和'/indyaah/readBooks.htm'的请求由服务器''/ indyaah / crud.htm'回答。我发现它很危险。

所以我建议你在jqGrid中使用第一个datatype: 'local'选项。它将阻止网格加载。您应该设置datatype: 'json'并在之后调用jq("#Grid").trigger("reloadGrid") colModel的所有选择(两个选择)都已加载。相应的实现很容易。例如:

var filledSelects = 0,
    $grid = jq("#Grid");
    fillSelectWithData = function (data, colName, idProp, nameProp) {
        var len = data.rows.length, i, html = '', item;
        for (i = 0; i < len; i++) {
            item = data.rows[i];
            if (i !== 0) {
                html += ',';
            }
            html += item[idProp] + ":'" + item[nameProp] + "'";
        }
        $grid.jqGrid('setColProp', colName, {
            edittype: 'select',
            editoptions: {value: html},
            editable: true
        });
    },
    loadGridIfRequired = function () {
        filledSelects++;
        if (filledSelects > 1) {
            $grid.jqGrid('setGridParam', {
                datatype: 'json'
            }).trigger('reloadGrid');
        }
    };

$grid.jqGrid({
    url:'/indyaah/crud.htm',
    datatype: 'local'
    ...
});
jq.getJSON('/indyaah/readUsers.htm', function (data) {
    fillSelectWithData(data, 'userId', 'userId', 'userName');
    loadGridIfRequired();
});
jq.ajax('/indyaah/readBooks.htm', function (data) {
    fillSelectWithData(data, 'bookId', 'bookId', 'user');
    loadGridIfRequired();
});

以上所有代码都未经过测试,但我希望它能够正常运行(可能是在修复小错误之后)。