3

Given a jqGrid populated with local data and created with the option of idPrefix:"custTable" , all the generated rows get the prefix in the html id i.e. custTableRow_1 custTableRow_2 etc. Does this idPrefix'ed version of the id need to be passed in to the jqGrid methods, if so which ones?

for example to delete a row with deleteRowData does it need the prefixed id? how about setRowData or addRowData? when adding after row x it seems to need the prefixed for the srcrowid parameter. How about multiselect rows?

If I delete a row using the prefixed id of the row it disappears from the display but when I reload the grid the delete item shows up again in the grid, like it wasn't removed. This doesn't happen when idPrefix is not used.

thanks for any help.

claya
  • 1,920
  • 1
  • 18
  • 32

1 Answers1

4

The option idPrefix was introduced to hold ids on the HTML page unique even you have on the page the ids like the rowids loaded from the server. Typical example is two grids with the data loaded from the server. Let us you have two tables in the database where you use IDENTITY or AUTOINCREMENT in the definition of the PRIMARY KEY. In the case the primary key will be generated automatically in the table and will be unique inside the table, but there are not unique over the tables. So if you would use the primary keys as ids of the grids and place on one page two grids you can have id duplicates.

To solve the problem you can use idPrefix: "a" as additional option in the first grid and use idPrefix: "b" in the second grid. In the case locally jqGrid will uses everywhere ids with the prefix, but the prefix will be cut if the ids will be sent to the server.

So you will see locally in all callbacks (events) and in all methods (like setRowData, addRowData etc) the ids with the prefix, but on the server side the ids the prefixes will be removed immediately before sending to the server.

I recommend you additionally to read another answer about the restrictions in the ids which I posted today.

UPDATED: I looked through the code which you posed on jsfiddle and found some clear bugs in your code. You current code

1) use wrong algorithm to generate id of the new row. For example the following code

// generic way to create an animal    
function newAnimal(collection, defaults) {
    var next = collection.length + 1;
    var newpet = {
        id : next,
        name: defaults.name + next,
        breed: defaults.breed
    };
    return newpet;
}

use collection.length + 1 for the new id. It's wrong if you allows to delete the items. By adding of two items, deleting one from there and adding new item one more time follows to id duplicates. Instead of that it's more safe to use some variable which will be only incremented. You can use $.jgrid.randId() for example which code is very simple.

2) you call addRowData with adding a prefix manually (see dogsPrefix+newdog.id below). It's wrong because jqGrid adds the prefix one more time to the rows.

// add dog button actions    
$('#dogAddAtEnd').click(function() {
    var newdog = newAnimal(dogs, dogDefaults);
    dogs.push(newdog);
    dogAdded();        
    dogsTable.jqGrid('addRowData', dogsPrefix+newdog.id, newdog);
});

Probably there are more problems, but at least these problems can explain the problems which you described.

UPDATED 2: I examined new demo which you posted. It has still the lines

grid.jqGrid('addRowData', newanimal.id, newanimal,
            "after", prefix+ followingId);

and

dogsTable.jqGrid('addRowData', dogsPrefix+newdog.id, newdog);

which must be fixed to

grid.jqGrid('addRowData', newanimal.id, newanimal,
            "after", followingId);

and

dogsTable.jqGrid('addRowData', newdog.id, newdog);

Nevertheless I tested the demo after the changes and found bugs in code of addRowData, delRowData and setRowData. The problem are in the line of the delRowData and the same line of setRowData

var pos = $t.p._index[rowid];

can be fixed to the following

var id = $.jgrid.stripPref($t.p.idPrefix, rowid), pos = $t.p._index[id];

Inside of addRowData I suggest to include the line

var id = rowid; // pure id without prefix

before the line

rowid  = t.p.idPrefix + rowid;

of addRowData. Another tow lines of addRowData

lcdata[t.p.localReader.id] = rowid;
t.p._index[rowid] = t.p.data.length;

should be changed to

lcdata[t.p.localReader.id] = id;
t.p._index[id] = t.p.data.length;

where unprefixed id will be used.

The modified code of you demo which uses the fixed version of jquery.jqGrid.src.js you can test here.

I will post my bug report to trirand later to inform the developer of the jqGrid. I hope that soon the bug fix will be included in the main code of jqGrid.

Additionally I recommend you to use $.jgrid.stripPref method to strip prefixes from the rowids. For example the function

//general delete selected 
function deleteSelectedAnimal(list, grid, prefix)
{
    var sel = grid.jqGrid('getGridParam', 'selrow');
    if (sel.length)
    {
        var gridrow = sel;  

        //get the unprefixed model id
        var modelid = gridrow; 
        if (prefix.length !== 0)
        {
           modelid = modelid.split(prefix)[1];     
        }                
        // make it a numeric
        modelid = Number(modelid);

        //delete the row in the collection  
        list = RemoveAnimal(list, modelid);

        //delete the row in the grid
        grid.jqGrid('delRowData', gridrow);
    }
}

from your demo can be rewritten to the following

//general delete selected
function deleteSelectedAnimal(list, grid)
{
    var sel = grid.jqGrid('getGridParam', 'selrow'),
        gridPrefix = grid.jqGrid('getGridParam', 'idPrefix');
    if (sel !== null)
    {
        //delete the row in the collection
        // ??? the gogs list will be not modified in the way !!!
        list = RemoveAnimal(list, $.jgrid.stripPref(gridPrefix, sel));

        //delete the row in the grid
        grid.jqGrid('delRowData', sel);
    }
}

I am not sure that the line list = RemoveAnimal(list, $.jgrid.stripPref(gridPrefix, sel)); or the function RemoveAnimal do what you want, but it's not a problem which connected with jqGrid.

One more small remark about your code. You use already in the objects which you add to the grid the id property. It's the same name as defined in the localReader.id. In the case the data from the id property will be used as id attribute of the grid rows (<tr>). The local data parameter will save the id additionally to other properties which are build from the name property of the items of colModel. So I see no sense to define hidden column

{ key: true, name: 'id', align: 'left', hidden: true }

How you can see on the demo all stay works exactly as before if you remove id column from the grids which you use.

UPDATED 3: As promised before I posted the corresponding bug report here.

Community
  • 1
  • 1
Oleg
  • 220,925
  • 34
  • 403
  • 798
  • thanks yes that is the exact use case (multiplegrids) I am using this idPrefix for, I'm glad it is available. But for my local data type grids do I need to set the data: param again before doing any reloadgrid triggers (say after new search/filter criteria) with current array if edits adds/deletes were made. or does the grid itself keep track and update its internal array upon add/deletes? – claya Mar 15 '12 at 03:56
  • I seem to get different results when I'm triggering reload grid when there is a idPrefix set after having deleted some items... But reload seems ok if idPrefix is not set. – claya Mar 15 '12 at 07:35
  • @claya: `idPrefix` is relative new feature. If you think that it works in some methods not like expected please post the full test case. I don't full understand why you use `idPrefix` with *local* data. You can directly use as the rowids the unique values. Isn't so? An example would be clear many things. – Oleg Mar 15 '12 at 08:05
  • I created a jsFiddle example that illustrates the issue see http://jsfiddle.net/tirams/WDe3A/ the steps to reproduce are in the js panel comments. IF you do the steps the deleted item comes back on reload but if you set the for for use of idprefix to false the same code the deleted item doesn't reappear on reload. – claya Mar 16 '12 at 23:21
  • also I believe id attributes must begin with a letter ([A-Za-z]) anyway – claya Mar 16 '12 at 23:30
  • sorry I tried to create a quick example on jsfiddle to represent the problem since I cannot post our actual product code. So in haste the id calc bug you pointed out was included. note that my original question was whether the addDataRow, xXXDataRow calls take the id with or without the prefix included. Your answer as I understood it was to "in all methods (like setRowData, addRowData etc) the ids with the prefix," was for caller to include the prefix. Its still not clear because the issue still happens. – claya Mar 19 '12 at 08:26
  • I simplified the code here http://jsfiddle.net/tirams/2sX9V/ using a unique id for each entry and not using prefix in the addDataRow problem still happens – claya Mar 19 '12 at 08:31