2

I am using Form Editing and Inline Editing in my grid (jqGrid 4.5.2). When I have an editable column and then open up the form, I do see the HTML code instead of the value. The screenshot shows what I mean.

jqGrid with HTML code

If no field is editable in the corresponding row, all is fine. I have read somewhere, I shall not use Form and Inline editing together, but only remember vaguely. However, actually all is working fine, except in this particular situation.

Can I reset the whole row to readonly (text) before I create the Form Editing display? Any other solutions?

-- Edit 1: Oleg's answer ---

I have checked / debugged into function restoreInline() and noticed two things:

  1. I do not have consecutive row ids, but something like 1,2,4,9 (my DB primary keys). They are unique, but some numbers are missing in between. As a result the condition if ($t.p.savedRow[i].id == rowid) is not fulfilled and restoreRow not called at all. Can't I have such gaps in the ids? Never noticed an issue with that before.
  2. I did a crosscheck with the first row and id "1". In this case $($t).jqGrid('restoreRow',rowid) is called, but I still see the "HTML code" in my field.

-- Edit 2 --

Have explicitly called jqGrid('restoreRow',rowid) in beforeShowForm, but with no success.

Community
  • 1
  • 1
Horst Walter
  • 13,663
  • 32
  • 126
  • 228
  • 1
    I still suppose that you have id duplicate problems. If you have grid with rowid=1, then You can try to use `$("*[id=1]")` or `$("*[id='1']")` instead of `$("#1")`. The value of `$("#1").length` is always <=1, but `$("*[id=1]")` will get you all elements on the page which has `id="1"`. So in case if there are exists more as one elements having `id="1"` you get with `$("*[id=1]")` **all** the elements and `$("*[id=1]").length` could be larger as 1. – Oleg Jul 10 '13 at 17:04
  • 1
    for example I answered recently on the question where reload of the grid don't worked after opening and closing of Add/Edit form. The problem was that the user used the same id value for the grid (``) and the name of the column. After opening the Add/Edit form new `` element was created with the same id like `
    ` of grid. So all inserting of rows in grid don't worked more because one tried insert `` as children in `` of hidden form. I want just emphasize that **id duplicate problems will be created mostly indirectly**.
    – Oleg Jul 10 '13 at 17:12
  • 1
    [The answer](http://stackoverflow.com/a/509965/315935) contains not perfect, but very good code to detect id duplicate problems. – Oleg Jul 10 '13 at 17:15
  • Very good hint, I was focusing more on the original data rather than the DOM id, maybe accidentally containing duplicates. Unfortunately still not found the root cause, the mentioned code (detecting duplicates) did not show anything. Also had a grid header with a similar name (Id), but changing its value did not helper either. But I will closely monitor the situation and might find the reasons. Will crosscheck with some other grids (tbd) in the same app. – Horst Walter Jul 10 '13 at 18:21
  • If you post the demo which reproduces the problem (inclusive some test data with ids 1,2,4,9 like you wrote before) I could examine the demo. If you have an URL online I can take a look too. In any way if `$(this).jqGrid('restoreRow',rowid)` inside of `beforeShowForm` don't restore editing line that you have some problems with ids. – Oleg Jul 10 '13 at 18:26

2 Answers2

2

Form editing should call internal restoreInline (see its code here) which calls restoreRow for the row before initializing of editing form. The function will be called (see the line) directly after beforeInitData. So if you need save the row instead of discarding of the data for example you can do this inside of beforeInitData callback.

I suppose that you have some id duplicates in the grid. So the call of restoreRow don't restored the data. Another possible reason could be a bug in jqGrid, but you have to debug your code to see why restoreInline function will be not called in your case or why it don't restore the rows.

Oleg
  • 220,925
  • 34
  • 403
  • 798
  • Will check and report back after some time, duplicate ids I can most likely rule out, let's see what debugging will uncover. Thanks so far! – Horst Walter Jul 09 '13 at 12:33
  • Updated above, think it is the right idea, but somehow confuses me. – Horst Walter Jul 10 '13 at 11:06
  • @HorstWalter: Array `$t.p.savedRow` contains the list of rowids of rows which are editing with respect of inline editing. So the condition `if ($t.p.savedRow[i].id == rowid)` means: "if the current row (where form editing started) is editing with respect of inline editing". I can't give you more tips because you posted almost no information: no JavaScript code, no input data (with ids 1,2,4,9), no testcase. If you don't solve the problem yourself you should append your question with more information. – Oleg Jul 10 '13 at 18:28
1

This happens (sometimes) when inline (row or cell) editing is used in jqGrid. The implementation I used is https://github.com/free-jqgrid/jqGrid.

What happens is that the editor control is not cleared inside the "td" tag of the cell in the underlying "table" used by jqGrid. The cell will still show the entered/edited value once, but when the cell is entered again (clicked, tabbed, arrow keys, etc.), the text in the newly injected editor control will be the content (innerHTML?) of the "td" tag - which is the previous editor control HTML. This is what I see when this happens in both the grid and the HTML:

Showing Ghost editor - td innerHTML with previous editor HTML

Note that this HTML is the TOP 2nd cell shown in the image, with the "ghost" editor in the cell.

<td role="gridcell" style="text-align: center; color: black; background-color: white;" aria-describedby="Grid_Col2" class="editable-cell" title="" tabindex="0">
   <input type="text" autocomplete="off" maxlength="9" id="93_Col2" name="Col2" role="textbox" style="width: 100%; box-sizing: border-box;">
</td>

I cannot confirm "why", but I was able to resolve this by using setTimeout(). I know, I know... :-( It seems to have something to do with the "navigation" div element (header element) of the grid snapping focus back to it - I guess if the currently selected control doesn't have the "edited" CSS (and the header cannot be edited...), it won't/can't fully remove the input control?

The setTimeout() was put in the "afterEditCell" override (see code block below).

I also gained stability by having empty implementations of the most of the cell editing override functions:

afterEditCell: function (rowid, cellname, value, iRow, iCol) {
    let rawInput = $("#" + this.id + " tbody>tr:eq(" + iRow + ")>td:eq(" + iCol + ") input, select, textarea");
    rawInput.select();
    rawInput.focus();

    setTimeout(() => {
        //TODO: I hate this, but not able to determine why focus goes back to the keyboard
        //      navigation DIV instead of the cell being edited. So, we have to force it. :(
        //      This may have something to do with the "trick" to process keydown on non-input
        //      elements: https://github.com/free-jqgrid/jqGrid/blob/master/js/grid.celledit.js line 530
        rawInput.focus();
    }, 100);
},
afterRestoreCell: function (rowid, value, iRow, iCol) {
    console.log("afterRestoreCell: (" + iRow + ", " + iCol + ") " + value);
},
afterSaveCell: function (rowid, cellname, value, iRow, iCol) {
    //console.log("afterSaveCell: (" + iRow + ", " + iCol + ") " + value);
},
beforeEditCell: function (rowid, cellname, value, iRow, iCol) {
    //console.log("beforeEditCell: (" + iRow + ", " + iCol + ") " + value);
},
beforeSaveCell: function (rowid, cellname, value, iRow, iCol) {
    //console.log("beforeSaveCell: (" + iRow + ", " + iCol + ") " + value);
    return value;    // note that this is required here!
},
beforeSubmitCell: function (rowid, cellname, value, iRow, iCol) {
    //console.log("saving cell with value:" + value);
}