1

Edit formatter action button is placed to jqgrid column:

colModel: [{"fixed":true,"label":" change ","name":"_actions","width":($.browser.webkit == true? 37+15: 32+15)
    ,"align":"center","sortable":false,"formatter":"actions",
"formatoptions":{"keys":true,"delbutton":false,"onSuccess":function (jqXHR) {actionresponse = jqXHR;return true;}
    ,"afterSave":function (rowID) {
    cancelEditing($('#grid'));afterRowSave(rowID,actionresponse);actionresponse=null; }
    ,"onEdit":function (rowID) {
      if (typeof (lastSelectedRow) !== 'undefined' && rowID !== lastSelectedRow)
        cancelEditing($('#grid'));
        lastSelectedRow = rowID;
        }
    }}

New row is added to jqgrid in loadcomplete event

var newRowData = {};
var newRowId = '_empty' + $.jgrid.randId();
$('#grid').jqGrid('addRowData', newRowId, newRowData);

and its id is updated if save action button is clicked:

function aftersavefunc(rowID, response) {
    restoreActionsIcons();
    $('#grid').jqGrid('resetSelection');
    var json = $.parseJSON(response.responseText);
    $("#" + rowID).attr("id", json.Id);
    lastSelectedRow = json.Id; 
    $("#grid").jqGrid('setSelection', lastSelectedRow);
}

After clicking save action button edit action button clicks are ignored. It is not possible to re-enter to edit mode after first editing.

How to fix this so that row can edited by edit button click again after saving ?

Update

I added $(this).focus() as suggested in Oleg answer and also wrapped id change into setTimeout as Oleg recommends in other great answer:

function aftersavefunc(rowID, response) {
    restoreActionsIcons();
    $(this).focus();
    $('#grid').jqGrid('resetSelection'); 
    var json = $.parseJSON(response.responseText);
    setTimeout(function () {
        $("#" + rowID).attr("id", json.Id);
        lastSelectedRow = json.Id;
        $("#grid").jqGrid('setSelection', lastSelectedRow);
    }, 50);
}

Problem persists. The problem may related to row id change since:

  1. It occurs only in last row (where id is changed after save). It does not occur for saved rows where responseText returns same id and row id is actually not changed.
  2. It does not occur if cancel action button is pressed.

Maybe row id needs additional reset id addition to resetSelection or needs updated in somewhere other place also.

Update2

I added code form updated answer to errorfunc and used only english characters and numbers id ids. This allows to click multiple times but introduces additional issue:

extraparam is no more passed. If rowactions() calls are commented out, extraparam is passed with with rowactions calls extraparam is not passed.

I changed jqGrid source code and added alert to rowactions method:

alert( cm.formatoptions);
if (!$.fmatter.isUndefined(cm.formatoptions)) {
  op = $.extend(op, cm.formatoptions);
  }

In first clicks alert outputs 'Object'. In succeeding clicks to Save button it outputs undefined. So for unknown reason formatoptions is cleared.

Remarks to comment:

  1. Absolute url in testcase is not used. Datasource is set to localarray. I verified that testcase works in IE and FF without external url access. For extraparam issue I can create new testcase.

  2. Without image directory buttons are shown in cursor is moved over them. Missing image directory still allows to reproduce the issue.

  3. FormData function is defined in js file.

Since new issue occurs after adding rowactions() calls and does not occur if those calls are removed, this seems to be related to the code proposed in answer.

Andrus
  • 26,339
  • 60
  • 204
  • 378

1 Answers1

1

I suppose that the problem exist because one hide a button which has currently focus. Look at the code from the answer. If one remove the line $(this).focus(); // set focus somewhere one has the same problem as you describes. So I suggest that you just try to set somewhere, for example in restoreActionsIcons the focus to any the table element of the grid after hiding the button having currently the focus. I can't test this, but I hope it will help.

UPDATED: I examined your problem one more time and I hope I can suggest you a solution.

You problem can be divided on two sub-problems. The main your problem is the the changing of the id of the row. So it is not common problem which everybody has.

The problem is that "actions" formatter create onclick functions directly in the HTML code (see for example here):

ocl = "onclick=$.fn.fmatter.rowactions('"+rowid+"','"+opts.gid+"','edit',"+opts.pos+");..."

So the functions will contains the original rowid. To fix the problem you can modify the code fragment of your aftersavefunc inside of setTimeout from

$("#" + rowID).attr("id", json.Id);
lastSelectedRow = json.Id;
$("#grid").jqGrid('setSelection', lastSelectedRow);

to something like the following:

var $tr = $("#" + rowID),
    $divEdit = $tr.find("div.ui-inline-edit"),
    $divDel = $tr.find("div.ui-inline-del"),
    $divSave = $tr.find("div.ui-inline-save"),
    $divCancel = $tr.find("div.ui-inline-cancel");

$tr.attr("id", json.Id);
if ($divEdit.length > 0) {
    $divEdit[0].onclick = function () {
        $.fn.fmatter.rowactions(newId,'grid','edit',0);
    };
}
if ($divDel.length > 0) {
    $divDel[0].onclick = function () {
        $.fn.fmatter.rowactions(newId,'grid','del',0);
    };
}
if ($divSave.length > 0) {
    $divSave[0].onclick = function () {
        $.fn.fmatter.rowactions(newId,'grid','save',0);
    };
}
if ($divCancel.length > 0) {
    $divCancel[0].onclick = function () {
        $.fn.fmatter.rowactions(newId,'grid','cancel',0);
    };
}
lastSelectedRow = json.Id;
$("#grid").jqGrid('setSelection', lastSelectedRow);

The second problem is that you use special characters inside of ids. I found a bug in the $.fn.fmatter.rowactions which need be fixed to support special characters in ids. The problem is that in the line 407 of jquery.fmatter.js the original rowid parameter rid will be changed:

rid = $.jgrid.jqID( rid )

and later everywhere will be used modified id. For example in the id is my.id the encoded version will be my\\.id. It's correct for the most places of the $.fn.fmatter.rowactions code (see here), but it' s incorrect as the rowid parameter of the editRow, saveRow, restoreRow, delGridRow, setSelection and editGridRow (see the lines 433-453). So the code must be fixed to use the original not escaped (not encoded) rid value with which the $.fn.fmatter.rowactions was called.

I think I will post tomorrow the corresponding bug report with the suggestions in the trirand forum.

UPDATED 2: The code $.fn.fmatter.rowactions(newId,'grid','edit',0); which I wrote above is just an example. I took it from the test demo which you send me. You should of course modify the code for your purpose. How you can see for example from the line the second parameter of the $.fn.fmatter.rowactions in the id of the grid which you use: 'grid', 'list' of something like myGrid[0].id. The last parameter should be the index of the column having formatter:'actions' in the colModel. You can use getColumnIndexByName function from the answer on your old question to get the index by column name.

Community
  • 1
  • 1
Oleg
  • 220,925
  • 34
  • 403
  • 798
  • Thank you very much. I implemented change you recommended but problem persists. I updated question and testcase. – Andrus Sep 01 '11 at 09:19
  • @Andrus: I wrote you before in an comment the following tip: if you change the `id` of some row of grid you have to examine at least `selrow` string and `selarrrow` array for the `id` values which you change. If needed you have to update the values immediately after changing row id with `jQuery.attr`. – Oleg Sep 01 '11 at 09:26
  • Thank you. In code provided `$('#grid').jqGrid('resetSelection')` is called before row id change. I looked into resetSelection source code and it looks like it sets selarrow to [] and selrow to null. So I dont understand why those values needs to be examined. – Andrus Sep 01 '11 at 10:17
  • @Andrus: Sorry, I didn't seen the statement. I suppose you should try to reduce the code to create small demo which has the described problem. I still think that you can solve the problem setting the focus, but you should find the place where you have to do this. If I set many breakpoints to debug your testcase the problem disappears (debugger have to set focus), so the problem is difficult to analyse. – Oleg Sep 01 '11 at 10:32
  • Thank you. I created standalone testcase and sent it to you. I do'nt know how to emulate Edit url success event locally, so I moved this code to errorfunc in testcase – Andrus Sep 01 '11 at 15:34
  • 1
    @Andrus: I think I found the reason of your problems. See "Updated" part of my answer. – Oleg Sep 06 '11 at 21:16
  • Thank you very much. First testcase which I sent contains also `extraparam:{_dokdata:FormData}` in actions formatoptions. After adding changes from answer _extraparam is no more passed to Edit controller. How to fix this? Also: Id changing is required if new row is added without grid refresh. This is common requirement. I don't know how to implement this common requirement without changing row id as in my sample. – Andrus Sep 07 '11 at 06:29
  • @Andrus: I don't promise you to find all bugs in your code. I don't make free worldwide support to solve any problems. Your first testcase contains jqGrid having absolute `url`. It can probably work on your computer and only in IE, but it can't work at me. Without `images` directory the testcase display just empty grid. The program has undefined `FormData` variable. I believe that your program have more bugs, but you should solve it yourself. Do you tried to implement the suggestion which I described? Can you now click on "Edit" button? – Oleg Sep 07 '11 at 06:53
  • thank you very much for great answer and comment. I updated question and answered in this update – Andrus Sep 07 '11 at 08:13
  • 2
    @Andrus: I suppose you used wrong index as the last parameter of `$.fn.fmatter.rowactions`. See "Update 2" in my modified answer. – Oleg Sep 07 '11 at 09:01
  • thank you. I used grid and colmodel from testcase . actions is first column so based my understanding its index is 0 always. grid id is grid always. – Andrus Sep 07 '11 at 09:27
  • 1
    @Andrus: Depend on other parameters which you use `multiselect: true`, `rownumbers: true` or `subGrid: true` the index can be 1, 2 or even 3 instead of 0. Do you tried to get the index with respect of `getColumnIndexByName` or just examine the `colModel` **after** the grid is created? You can also just use Developer Tools (started by F12) of Internet Explorer or Google Chrome to examine the grid. I suppose in your grid the index will be 1 or 2 instead of 0. – Oleg Sep 07 '11 at 09:36
  • Thank you very much. I used wrong index. I'm sorry for that. Using getColumnIndexByName solves the issue. Thank you again Oleg, your help is really great. – Andrus Sep 07 '11 at 10:29
  • I removed `setTimeout` and `$('#grid')[0].focus()` calls which you suggested to add. It seems that code works ok without those calls. It it safe to remove them ? – Andrus Sep 07 '11 at 10:38
  • @Andrus: If you have no problem: why should to have the unneeded code? – Oleg Sep 07 '11 at 10:53
  • In 4.4.4 rowactions code uses $(this) and thus rowactions calls used in answer do not work. How to fix this ? – Andrus Mar 24 '13 at 16:04
  • @Andrus: The answer is 1,5 years old. It was about *another* version of jqGrid. I can remind that I posted some suggestions to trirand (see [here](https://github.com/OlegKi/jqGrid/commit/e23c95e281b2eea52f4e1aa36d73b5f83cc91dec)) to rewrite code of formater actions so that renaming of `id` will be more easy. You should post new question where you describe which problem you have with the jqGrid 4.4.4. – Oleg Mar 24 '13 at 16:19
  • @Andrus: See [the commit](https://github.com/tonytomov/jqGrid/commit/e23c95e281b2eea52f4e1aa36d73b5f83cc91dec) Nov 08, 2012. So already version 4.4.2 version should have the modification included. Which version of jqGrid use you? – Oleg Mar 24 '13 at 16:27
  • I upgraded to 4.4.4 It seems that 4.4.4 works OK without this code, I removed it. – Andrus Mar 24 '13 at 21:20
  • @Andrus: It was the goal of [my suggestion](https://github.com/OlegKi/jqGrid/commit/e23c95e281b2eea52f4e1aa36d73b5f83cc91dec). I changed the parameters of `jQuery.fn.fmatter.rowactions` so that it uses `$(this).closest("tr.jqgrow").attr("id")` instead of *static* parameter `opts.gid` which represents the id of row at the moment of creating of last filling of the grid. New version of the code should work correctly even after changing the value of id attribute of the row. – Oleg Mar 24 '13 at 22:01