Search code examples
jqueryautocompletejqgridfree-jqgrid

jqGrid 4.10 autocomplete doesn't complete all fields + inline editing focus is not changing to a new row


Firstly: I have the following column with autocomplete:

{name:'ISRC',index:'isrc.ISRC', width:100,align:"left",editable:true,
    edittype:'text',
    editoptions:{
        dataInit:function (elem) {
            var sel_row_id = $grid.jqGrid ('getGridParam', 'selrow');
            if (sel_row_id === undefined || sel_row_id === null) {sel_row_id="jqg1";}

            $(elem).autocomplete({
                source: "xtras/search_isrc.php",
                dataType: "json",
                minLength: 2,
                select: function(event, ui) {
                    console.log("EditOptions - "+sel_row_id);
//                              $("#"+sel_row_id+"_id").val(ui.item ? ui.item.isrc_ID : "");
                    $("#"+sel_row_id+"_ISRC").val(ui.item.ISRC);
                    $("#"+sel_row_id+"_Track_Name").val(ui.item.Track_Name);
                    $("#"+sel_row_id+"_Track_Time").val(ui.item.Track_Time);
                    $("#"+sel_row_id+"_ArtistName").val(ui.item.ArtistName);
                    $("#"+sel_row_id+"_Writer").val(ui.item.Writer);
                    $("#"+sel_row_id+"_Publisher").val(ui.item.Publisher);
                    $("#"+sel_row_id+"_TrackPLineYear").val(ui.item.TrackPLineYear);
                    $("#"+sel_row_id+"_TrackPLineInfo").val(ui.item.TrackPLineInfo);
                    $("#"+sel_row_id+"_isrc_id").val(ui.item.isrc_ID);
                    var ffs = ui.item.isrc_ID;
                    console.log("ffs - "+ffs);
                },
                change: function(event, ui) {
                    if (ui.item) {
                        $("#"+sel_row_id+"_ISRC").val(ui.item.ISRC);
                        $("#"+sel_row_id+"_Track_Name").val(ui.item.Track_Name);
                        $("#"+sel_row_id+"_Track_Time").val(ui.item.Track_Time);
                        $("#"+sel_row_id+"_ArtistName").val(ui.item.ArtistName);
                        $("#"+sel_row_id+"_Writer").val(ui.item.Writer);
                        $("#"+sel_row_id+"_Publisher").val(ui.item.Publisher);
                        $("#"+sel_row_id+"_TrackPLineYear").val(ui.item.TrackPLineYear);
                        $("#"+sel_row_id+"_TrackPLineInfo").val(ui.item.TrackPLineInfo);
                        $("#"+sel_row_id+"_isrc_id").val(ui.item.isrc_ID);
                    }
                }
            });
            $('.ui-autocomplete').css('zIndex',1000); // if autocomplete has misalignment so we are manually setting it 

            if(sel_row_id != 'jqg1'){
                $(elem).css({'border':'1px solid red','background-color':'#e8b7cf'});
            }
        }
    }
},
...
{name:'isrc_ID',index:'isrc.isrc_ID', hidden:true, width:50, sortable:true, editable:true},

ffs puts in console correct id I also have inline editing set on doubleClick:

ondblClickRow: function (rowid) {
    console.log('ondblClickRow - '+rowid);

    var savedRows = $grid.jqGrid("getGridParam", "savedRow");
    $grid.jqGrid("setSelection", rowid);

    if (savedRows.length > 0 && savedRows[0].id !== rowid) {
        // cancel editing of another row is editing
        // don't cancel on double click on the current editing
        $grid.jqGrid("restoreRow", savedRows[0].id);
    }
    if (savedRows.length === 0) {
        $grid.jqGrid("editRow", rowid, editOptions);
    } 
}

I only was able to make autocomplete work after I forced the row selection on this line $grid.jqGrid("setSelection", rowid);

The autocomplete PHP:

$sql = "select * from isrc where Track_Name REGEXP '[[:<:]]($q)[[:alnum:]]' or ISRC REGEXP '[[:<:]]($q)[[:alnum:]]' GROUP BY ISRC;"; 
$rsd = mysqli_query($GLOBALS["___mysqli_ston"], $sql); 
while($data = mysqli_fetch_array($rsd)) { 

    $row_array['value'] = $data['ISRC']; 
    $row_array['label'] = $data['ISRC'].' - '.$data['Track_Name'].' - '.$data['ArtistName'].' - '.$data['Track_Time'].' - '.$data['TrackPLineInfo'];

    $row_array['ISRC'] = $data['ISRC'];   
    $row_array['Track_Name'] = $data['Track_Name'];
    $row_array['ArtistName'] = $data['ArtistName']; 
    $row_array['Track_Time'] = $data['Track_Time'];
    $row_array['Writer'] = $data['Writer']; 
    $row_array['Publisher'] = $data['Publisher']; 
    $row_array['TrackPLineYear'] = $data['TrackPLineYear']; 
    $row_array['TrackPLineInfo'] = $data['TrackPLineInfo']; 
    $row_array['isrc_ID'] = $data['isrc_ID'];   

} 

((is_null($___mysqli_res = mysqli_close($conn))) ? false : $___mysqli_res); 

echo json_encode($row_array); 

On Select autocomplete looks exactly as expected (all fields filled in correctly) After submitting to server to add into database I get this:

_REQUEST - 2015-12-02 17:00:13: 
Array
(
    [Catalogue] => 1958
    [ISRC] => GBCQV0200199
    [Disc_Number] => 1
    [Track_Number] => 4
    [is_bonus] => No
    [Track_Name] => Hitch Hiking Woman
    [ArtistName] => Peter Green Splinter Group
    [Track_Time] => 00:00:00
    [Writer] => Turner
    [Publisher] => Bug Music Ltd
    [TrackPLineYear] => 1997
    [TrackPLineInfo] => Snapper Music
    [isrc_ID] => 
    [id] => jqg1
    [copyID] => 
    [oper] => add
)

as you can see [isrc_ID] =>is blank. The only explanation I can think of - it is because this field is hidden.... How do I fix this?

Secondly: jqGrid - on add - if before pressing + to add a line I had any other existing row selected/clicked on - the grid thinks I'm editing the new row [id] => jqg1 instead of adding. Here are my definitions:

var editOptions = {
            keys: true,
            aftersavefunc: function() {
                var $self = $(this);
                setTimeout(function () {
                    $self.trigger("reloadGrid", [{current: true}]);
                }, 50);
            },
            url: "xtras/Records.php"
        },
        gridIdSelector = "#Records",
        pagerIdSelector = "#Records_pager",
        $grid = $(gridIdSelector);

and a pager initiation:

.jqGrid("navGrid", pagerIdSelector, {add: false, edit: false, refreshstate: "current"})
        .jqGrid("inlineNav", pagerIdSelector, { editParams: editOptions, addParams: {addRowParams: editOptions}})
        .jqGrid("navButtonAdd", pagerIdSelector, {
            caption: "",
            title: "Copy selected row",
            id: $grid[0].id + "_ilcopy", 
            buttonicon: "ui-icon-copy",
            onClickButton: function () {
                var $self = $(this), p = $self.jqGrid("getGridParam"), rowData,
                    srcrowid = p.selrow, savedRows = p.savedRow;

                if (srcrowid !== null) {
                    if (savedRows.length > 0) {
                        // cancel editing
                        $self.jqGrid("restoreRow", savedRows[0].id);
                    }
                    rowData = $self.jqGrid("getRowData", srcrowid);
                    rowData.id = "";
                    rowData.Catalogue = "";
                    rowData.copyID = srcrowid;
                    $self.jqGrid("addRow", {
                        initdata: rowData,
                        addRowParams: editOptions 
                    });
                } else {
                    alert("Please select a row to copy");
                    return false;
                }
            }
        });

How do I make sure that on inline edit the previous selection is completely reset?

Sorry I've ran out of ideas why both of these behaviours. If you think you need to see more code - please let me know.


Solution

  • I'm not sure that I full understand the problem, which you describe with Autocomplete, but I suppose you want that the row will be not deselected if it was previously selected. It's behavior of old jqGrid. You can just add the option

    singleSelectClickMode: "selectonly"
    

    which restore the old selection behavior.

    I could see some other problems in your code. Free jqGrid have implemented extension to dataInit callback. It has the second parameter options which has the following helpful properties:

    • rowId with the value like "70"
    • name with the column name as the value, for example "invdate"
    • id with the value like "70_invdate"
    • mode with the value like "edit" or "add"

    Moreover the DOM element elem is already placed on the page and you can use something like $(elem).closets("tr.jqgrow").attr("id") to get the rowid. It's better to use options.rowId of cause as the expression $(elem).closets("tr.jqgrow").attr("id").

    Thus I recommend you to change the beginning of the code

    dataInit:function (elem) {
        var sel_row_id = $grid.jqGrid ('getGridParam', 'selrow');
        if (sel_row_id === undefined || sel_row_id === null) {sel_row_id="jqg1";}
        ...
    }
    

    to

    dataInit: function (elem, options) {
    

    and to use options.rowId instead of sel_row_id below. I have to stress that the assigning sel_row_id="jqg1" is wrong. It could work correctly at the adding of the first row, but it will be definitively wrong in case of adding next rows.

    At the end of the code of dataInit I recommend you to replace

    if(sel_row_id != 'jqg1'){
    

    to

    if (options.mode !== "add") {
    

    UPDATED: I suppose that you need to use editable: "hidden" property instead of editable: true for isrc_ID. You need to change

    $("#" + options.rowId + "_isrc_id").val(ui.item.isrc_ID);
    

    to

    $grid.jqGrid("setCell", options.rowId, "isrc_ID", ui.item.isrc_ID)
    

    because the usage of editable: true for hidden field don't creates any hidden <input> element.

    I introduced the option editable: "hidden" property to provide simple way to send any additional column to the server which is not editable. It's important to mention that the feature editable: "hidden" for inline and cell editing is implemented only in 4.11.0 version of jqGrid. I recommend you to load the current source from GitHub which is identical to 4.11.0, but which contains one important fix additionally. I'll publish 4.11.1 at the end of the week.