Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Changing a jqGrid text column's editable property based on results of an autocomplete in another column

Tags:

jquery

jqgrid

I am using jqGrid 4.4.0 with inline editing. For the sake of this question, my grid has four columns: an ID column (SomeGridRowId), a text column with a jQuery autocomplete (Autocomplete), a single character text column (SingleChar), and a hidden boolean column (CanEditSingleChar). I need to enable or disable editing of the single character column based on the value of the CanEditSingleChar column. I've got this working on existing rows using onSelectRow and setColProp, but for some reason I cannot get it to behave correctly on newly inserted rows. If I add a new row and select a value from the autocomplete, the SingleChar column is always not editable. I've stepped through the Javascript using the Chrome and IE developer tools; the column values and properties are getting set properly, but the SingleChar column's editable property does not reflect this.

I apologize for the gigantic code snippet, but I don't want to leave anything out.

$("#coolGrid").jqGrid({
    url: '@Url.Action("GetCoolGridData")',
    postData: {
        someId: function () { return $("#someId").val(); },
        otherStaticArg: function () { return 1; }
    },
    datatype: 'json',
    mtype: 'POST',
    loadonce: true,
    cellsubmit: 'clientArray',
    editurl: 'clientArray',
    scroll: true,
    pager: $("#coolGridPager"),
    rowNum: 200,
    sortname: 'SomeGridRowId',
    sortorder: 'asc',
    viewrecords: true,
    height: '100%',
    colNames: ['SomeGridRowId', 'CanEditSingleChar', 'Autocomplete', 'SingleChar'],
    colModel: [
        { name: 'SomeGridRowId', index: 'SomeGridRowId', hidden: true },
        { name: 'CanEditSingleChar', index: 'CanEditSingleChar', hidden: true }, 
        {
            name: 'Autocomplete',
            index: 'Autocomplete',
            width: 220,
            editable: true,
            edittype: 'text',
            editoptions: {
                dataInit: function (elem) {
                    $(elem).autocomplete({
                        source: '@Url.Action("GetSomeGridAutocomplete")',
                        minLength: 2,
                        select: function (event, ui) {
                            var rowId = getRowId($(this));
                            if (ui.item) {
                                $("#coolGrid").jqGrid('setCell', rowId, 'CanEditSingleChar', ui.item.CanEditSingleChar, '', '');
                                $("#coolGrid").jqGrid('setCell', rowId, 'Autocomplete', ui.item.label, '', '');
                                setSingleCharEditMode(rowId);
                            }
                        }
                    });
                }
            }
        },
        {
            name: 'SingleChar',
            index: 'SingleChar',
            width: 10,
            editable: true,     //default to true, most are editable
            edittype: 'text'
        }
    ],
    onSelectRow: function (clickedRow) {
        if (clickedRow && clickedRow != $.coolGridLastSelectedRow) {
            $("#coolGrid").jqGrid('saveRow', $.coolGridSelectedRow, false, 'clientArray');
            $.coolGridLastSelectedRow = clickedRow;
        }
        setSingleCharEditMode($.coolGridLastSelectedRow);
        $("#coolGrid").jqGrid('editRow', $.coolGridLastSelectedRow, true);
    },
    afterInsertRow: function (rowid, rowdata, rowelem) {
        if (rowid == 'new_row') {       //shown solely for completeness, pretty sure this is not the problem
            var newRowIndex = $("#coolGridNewRowIndex").val();
            if (!newRowIndex)
                newRowIndex = 1;
            var newRowId = rowid + "_" + newRowIndex;
            $("#new_row").attr('id', newRowId);
            newRowIndex++;
            $("#coolGrid").val(newRowIndex);
            $("#coolGrid").jqGrid('setSelection', newRowId, true);
        }
    }
});
$("#coolGrid").jqGrid('navGrid', '#coolGridPager',
{
    add: false,
    del: false,
    edit: false,
    search: false,
    beforeRefresh: function () {
        $("#coolGrid").jqGrid('setGridParam', { datatype: 'json' });
    }
});
$("#coolGrid").jqGrid('inlineNav', '#coolGridPager',
{
    edit: false,
    add: true,
    addtext: "Add",
    save: false,
    cancel: false,
    restoreAfterSelect: false,
    addParams: {
        position: 'last',
        addRowParams: {
            keys: true
        }
    }
});

And the setSingleCharEditMode function:

function setSingleCharEditMode(rowid) {
    var rowData = $("#coolGrid").jqGrid('getRowData', rowid);
    if (rowData.CanEditSingleChar === "false") {
        $("#coolGrid").jqGrid('setColProp', 'SingleChar', { editable: false });
    } else {
        $("#coolGrid").jqGrid('setColProp', 'SingleChar', { editable: true });
    }
}

I've tried a whole slew of stuff, rifled through a pile of other SO questions, googled like mad....all to no avail. I've resorted to pulling my hair out. How can I control the editable property of one column after an autocomplete select on another column, all on a new row?

EDIT
I've got a working example up here, finally. If you add a row and then select either of the "Atypical *" in the Autocomplete column, you can reproduce this behavior.

like image 525
AJ. Avatar asked Jun 26 '12 21:06

AJ.


1 Answers

Without an actual example it is hard to tell why newly added rows can not be edited. Also, it is quite hard to put together a simple working example myself (e.g. on jsfiddle or jsbin) due to jqGrid and other dependencies.

A few questions after looking through your code that might help (or might be nothing new to what you already tried):

  • addRow - How do you add a row, using the addRow function? Does everything else "jqGrid related" work with the newly added rows, i.e. does it get initialized properly? I had some issues with that kind of problem using datatables.

  • Correct / unique row id? - Have you checked that the rowid is unique for new rows and that your code is executed with the correct one (i.e. the id from the new row)? Did you put console.log statements into setSingleCharEditMode to see what's going on (just to be sure, you said that you already stepped through the code)?

    You might be setting the editable property of a cell in another row (Thinking about it: this can't be it, as the cell should be editable by default and the explicitely set to not being editable by your code.). Change the color of the row together with the editable property to easily see which cell/row is being worked on.

  • Working by default? - As the default value of editable is true: have you tried disabling setSingleCharEditMode and see that the cell is editable by default? Maybe the problem isn't your evaluation but the adding of the row itself?

  • Correct type? - In setSingleCharEditMode you test the column value for strict equality with the string "false". Are you sure that the values have the same type for existing and new lines (should be, as they are strings and get parsed through the same jqGrid code: getRowData)? I guess you already have console.logged extensively in that function to see what is going on with the passed id and the comparison that sets the editable property‽

Hope this helps a little to find the problem. As I said, it's really hard to debug without a working example. You might want to put one up somewhere.

[Edit after working example]

First thing I see is, that if you select "Atypical Manic Disorder" in an existing editable row, the same behaviour applies. Also: adding editable rows (Bipolar something) works. This does not seem to be a problem of "new row" vs. "existing row". More like a problem with editable rows that get changed to not editable.

My guess is that this is happening:

  1. You are adding a new row, column SingleChar is editable by default, so the <input> is shown.
  2. You evaluate the server response and set the column to editable : false in the autocomplete select handler.
  3. You deselect the row and jqGrid reverts all then editable rows, so it doesn't touch SingleChar, because it thinks that SingleChar does not need to be reset to its initial state..

Am I making sense?

Try setting editable to false after jqGrid reset the row or removing the <input> yourself.

like image 82
Wolfram Avatar answered Nov 29 '22 15:11

Wolfram