openpsa / jsgrid

Fork of last jqGrid version before license change
http://openpsa.github.io/jsgrid/
Other
28 stars 12 forks source link

grid not updating when editing #106

Closed bchr02 closed 9 years ago

bchr02 commented 9 years ago

I am using datatype json to pull data from back-end server and doing edits like this:

$.extend(true, $.jgrid.edit, {
    recreateForm: true,
    url: "./test.php",
    mtype: "POST",
    editData: {route:'edit'},
});

What I realized is that searching wouldn't work with this configuration unless I use loadonce: true. So I enabled that but now whenever I make an edit the grid does not update with the changes. On the other hand the server does get updated.

I created a demo site here: http://www.tesllc.aero/temp/jqgrid/

This is what the php page looks like. It's just to demonstrate the issue.

<?php

header('Content-Type: application/json');

$route = $_POST["route"];

$json = '[{
        "CQD_AUTO_KEY": "id0",
        "COMPANY_NAME": "Company 0",
        "COMPANY_REF_NUMBER": "ref 1",
        "SALESPERSON_NAME": "Brad",
        "PN": "2135s42354f"
    }, {
        "CQD_AUTO_KEY": "id1",
        "COMPANY_NAME": "Company 1",
        "COMPANY_REF_NUMBER": "ref 1",
        "SALESPERSON_NAME": "Brad",
        "PN": "2135s42354f"
    }, {
        "CQD_AUTO_KEY": "id2",
        "COMPANY_NAME": "Company 1",
        "COMPANY_REF_NUMBER": "ref 1",
        "SALESPERSON_NAME": "Brad",
        "PN": "2135s42354f"
    }, {
        "CQD_AUTO_KEY": "id3",
        "COMPANY_NAME": "Company 3",
        "COMPANY_REF_NUMBER": "ref 1",
        "SALESPERSON_NAME": "Brad",
        "PN": "2135s42354f"
    }, {
        "CQD_AUTO_KEY": "id4",
        "COMPANY_NAME": "Company 4",
        "COMPANY_REF_NUMBER": "ref 1",
        "SALESPERSON_NAME": "Brad",
        "PN": "2135s42354f"
    }, {
        "CQD_AUTO_KEY": "id5",
        "COMPANY_NAME": "Company 5",
        "COMPANY_REF_NUMBER": "ref 1",
        "SALESPERSON_NAME": "Brad",
        "PN": "2135s42354f"
    }, {
        "CQD_AUTO_KEY": "id6",
        "COMPANY_NAME": "Company 5",
        "COMPANY_REF_NUMBER": "ref 1",
        "SALESPERSON_NAME": "Brad",
        "PN": "2135s42354f"
    }, {
        "CQD_AUTO_KEY": "id7",
        "COMPANY_NAME": "Company 0",
        "COMPANY_REF_NUMBER": "ref 1",
        "SALESPERSON_NAME": "Steve",
        "PN": "2135s42354f"
    }, {
        "CQD_AUTO_KEY": "id8",
        "COMPANY_NAME": "Company 1",
        "COMPANY_REF_NUMBER": "ref 1",
        "SALESPERSON_NAME": "Steve",
        "PN": "2135s42354f"
    }, {
        "CQD_AUTO_KEY": "id9",
        "COMPANY_NAME": "Company 1",
        "COMPANY_REF_NUMBER": "ref 1",
        "SALESPERSON_NAME": "Steve",
        "PN": "2135s42354f"
    }, {
        "CQD_AUTO_KEY": "id10",
        "COMPANY_NAME": "Company 3",
        "COMPANY_REF_NUMBER": "ref 1",
        "SALESPERSON_NAME": "Steve",
        "PN": "2135s42354f"
    }, {
        "CQD_AUTO_KEY": "id11",
        "COMPANY_NAME": "Company 4",
        "COMPANY_REF_NUMBER": "ref 1",
        "SALESPERSON_NAME": "Steve",
        "PN": "2135s42354f"
    }, {
        "CQD_AUTO_KEY": "id12",
        "COMPANY_NAME": "Company 5",
        "COMPANY_REF_NUMBER": "ref 1",
        "SALESPERSON_NAME": "Steve",
        "PN": "2135s42354f"
    }, {
        "CQD_AUTO_KEY": "id13",
        "COMPANY_NAME": "Company 5",
        "COMPANY_REF_NUMBER": "ref 1",
        "SALESPERSON_NAME": "Steve",
        "PN": "2135s42354f"
    }]';

if ($route == 'edit') {

    echo("{}");

} else if ($route == 'load') {

    echo($json);

} else {

    echo("{}");

}

?>
bouks commented 9 years ago

I've tested your demo. When i edit and save a row, the server return an "application/json" content type header, but the content is not json, it is the string "success".

For editing, i personnaly return the changed datas from server in the ajax response and implement afterSubmit where i check the returned datas and validate them and setRowData to be sure the datas in the grid are not wrong datas.

Like this kind of thing :

afterSubmit: function (jqXHR, rowId) {
    var response = JSON.parse(jqXHR.responseText);
    if (response.error ===  'true') {
        alert(response.message);
        return([false]);
    }
    doSomeThings();
    grid.jqGrid('setRowData', response.id, response);
    doOtherThings();
    return([true]);
}
bchr02 commented 9 years ago

why won't reloadAfterSubmit:true cause the grid to reload?

bouks commented 9 years ago

Maybe because you set loadonce:true.

bchr02 commented 9 years ago

regarding your comment about why the content is not jon. I forgot to hit save on my demo php. sorry. I have saved it now.

I am not looking to validate the returned data. I simply want the grid to reload.

take a look at this: http://www.trirand.com/blog/?page_id=393/help/reloading-grid-after-submittingeditadddelete

that is what is happening to me. But why can't we fix this so I don't have to do what they are recommending?

bchr02 commented 9 years ago

I had to set loadonce to true so that multipleSearch:true would work. I don't want to implement server side filtering.

bchr02 commented 9 years ago

with multipleSearch:true and loadonce:false, searching would not work. I think that is because it would try to post to the server and wait for a response with the filtered data. But I don't want to do the filtering on the server.

bouks commented 9 years ago

I have a grid with multiplesearch:true and loadonce:false. It works perfectly.

I don't understand. Do you want loadonce or not ??? Do you want to search on the server or on local data ?

bchr02 commented 9 years ago

I pull the grid from the server. When I edit the data I want it to save to server and reload the grid from the server When I search I want it to be local.

bchr02 commented 9 years ago

I had to set loadonce to false so that when I search it would be local. Is there another way to make the search be local and keep loadonce to false?

bouks commented 9 years ago

Why would you like to reload the grid after editing ? It takes much network and server ressources...

bouks commented 9 years ago

What you want can be done by a reloadGrid in afterSubmit...

bchr02 commented 9 years ago

I don't want to have to reload the grid after editing. If the API allows it I would prefer:

pull grid from server when editing have it save to server and update the client grid so the changes are visible. when I search I want it to be local.

Can you please explain how I would accomplish this?

bouks commented 9 years ago

I asked @flack many times to implement that loadonce should be automatically set to false at 00:00 when the night is full moon. He never did it.

I gave you 2 solutions. If you don't want them, i can't do anything more for you. Maybe others can help you.

bchr02 commented 9 years ago

Thanks for helping me.

Like you said, I don't want to have to reload the grid after editing, this is not efficient. So if there is a way around that, I am all ears.

bchr02 commented 9 years ago

I don't want to have to do this:

afterSubmit: function (response, postdata) {
    $("#grid").jqGrid('setGridParam',{datatype:'json'}).trigger('reloadGrid');
    $("#grid").jqGrid('setGridParam',{datatype:'local'}); // need this to be local so searching stays local
    return([true]);
}
bouks commented 9 years ago

You can do that:

https://github.com/openpsa/jsgrid/issues/106#issuecomment-73275933

bchr02 commented 9 years ago

so if my original data from the server looks like this:

[{
        "CQD_AUTO_KEY": "id0",
        "COMPANY_NAME": "Company 0",
        "COMPANY_REF_NUMBER": "ref 1",
        "SALESPERSON_NAME": "Brad",
        "PN": "2135s42354f"
    }, {
        "CQD_AUTO_KEY": "id1",
        "COMPANY_NAME": "Company 1",
        "COMPANY_REF_NUMBER": "ref 1",
        "SALESPERSON_NAME": "Brad",
        "PN": "2135s42354f"
    }, {
        "CQD_AUTO_KEY": "id2",
        "COMPANY_NAME": "Company 1",
        "COMPANY_REF_NUMBER": "ref 1",
        "SALESPERSON_NAME": "Brad",
        "PN": "2135s42354f"
    }, {
        "CQD_AUTO_KEY": "id3",
        "COMPANY_NAME": "Company 3",
        "COMPANY_REF_NUMBER": "ref 1",
        "SALESPERSON_NAME": "Brad",
        "PN": "2135s42354f"
    }, {
        "CQD_AUTO_KEY": "id4",
        "COMPANY_NAME": "Company 4",
        "COMPANY_REF_NUMBER": "ref 1",
        "SALESPERSON_NAME": "Brad",
        "PN": "2135s42354f"
    }, {
        "CQD_AUTO_KEY": "id5",
        "COMPANY_NAME": "Company 5",
        "COMPANY_REF_NUMBER": "ref 1",
        "SALESPERSON_NAME": "Brad",
        "PN": "2135s42354f"
    }, {
        "CQD_AUTO_KEY": "id6",
        "COMPANY_NAME": "Company 5",
        "COMPANY_REF_NUMBER": "ref 1",
        "SALESPERSON_NAME": "Brad",
        "PN": "2135s42354f"
    }, {
        "CQD_AUTO_KEY": "id7",
        "COMPANY_NAME": "Company 0",
        "COMPANY_REF_NUMBER": "ref 1",
        "SALESPERSON_NAME": "Steve",
        "PN": "2135s42354f"
    }, {
        "CQD_AUTO_KEY": "id8",
        "COMPANY_NAME": "Company 1",
        "COMPANY_REF_NUMBER": "ref 1",
        "SALESPERSON_NAME": "Steve",
        "PN": "2135s42354f"
    }, {
        "CQD_AUTO_KEY": "id9",
        "COMPANY_NAME": "Company 1",
        "COMPANY_REF_NUMBER": "ref 1",
        "SALESPERSON_NAME": "Steve",
        "PN": "2135s42354f"
    }, {
        "CQD_AUTO_KEY": "id10",
        "COMPANY_NAME": "Company 3",
        "COMPANY_REF_NUMBER": "ref 1",
        "SALESPERSON_NAME": "Steve",
        "PN": "2135s42354f"
    }, {
        "CQD_AUTO_KEY": "id11",
        "COMPANY_NAME": "Company 4",
        "COMPANY_REF_NUMBER": "ref 1",
        "SALESPERSON_NAME": "Steve",
        "PN": "2135s42354f"
    }, {
        "CQD_AUTO_KEY": "id12",
        "COMPANY_NAME": "Company 5",
        "COMPANY_REF_NUMBER": "ref 1",
        "SALESPERSON_NAME": "Steve",
        "PN": "2135s42354f"
    }, {
        "CQD_AUTO_KEY": "id13",
        "COMPANY_NAME": "Company 5",
        "COMPANY_REF_NUMBER": "ref 1",
        "SALESPERSON_NAME": "Steve",
        "PN": "2135s42354f"
    }]

and I am update id13 of column CQD_AUTO_KEY

what exactly should the response look like so that it would work with the below?

grid.jqGrid('setRowData', response.id, response);
flack commented 9 years ago

I have not looked into this yet, but I think it may be related to the problem described here: https://github.com/openpsa/jsgrid/issues/46#issuecomment-71087211

@bouks Did you get a chance to look at the remote demo and the reloadGrid problem? I think it is the same issue as what is described here, i.e. the datatype is changed to local after initial load because loadonce is true, and thus reloadGrid won't fire the request because of some conflict between your autodetection changes and what we've merged from Oleg.

bouks commented 9 years ago
[{
        "CQD_AUTO_KEY": "id0",
        "COMPANY_NAME": "Company 0",
        "COMPANY_REF_NUMBER": "ref 1",
        "SALESPERSON_NAME": "Brad",
        "PN": "2135s42354f"
    }]

and

grid.jqGrid('setRowData', response.CQD_AUTO_KEY, response);

assuming CQD_AUTO_KEY is defined as "id" option in the grid.

bchr02 commented 9 years ago

"assuming CQD_AUTO_KEY is defined as "id" option in the grid."

that's done using the key property of colmodel, correct?

meh-uk commented 9 years ago

That works as per http://openpsa.github.io/jsgrid/configuration/colModel.html#-key-

bouks commented 9 years ago

@flack he doesn't want to reload the grid.

@bchr02 i don't use the key option. I talked about the "id" option in jsonReader option.

bchr02 commented 9 years ago

@bouks so id needs to be defined like so?

jsonReader : {
     ...
    id: "CQD_AUTO_KEY"
},
bouks commented 9 years ago

I made a mistake, the response should be :

{
        "CQD_AUTO_KEY": "id0",
        "COMPANY_NAME": "Company 0",
        "COMPANY_REF_NUMBER": "ref 1",
        "SALESPERSON_NAME": "Brad",
        "PN": "2135s42354f"
    }

without the []. :)

Yes for the id

flack commented 9 years ago

@bouks hm, this comment sounds like he does: https://github.com/openpsa/jsgrid/issues/106#issuecomment-73302961. Sure, it's not by calling reloadGrid explicitly, but reloadAfterSubmit should do at least something similar

bouks commented 9 years ago

@flack https://github.com/openpsa/jsgrid/issues/106#issuecomment-73304358

bouks commented 9 years ago

@flack excuses. bad link. This one : https://github.com/openpsa/jsgrid/issues/106#issuecomment-73306585

flack commented 9 years ago

@bouks yes, I get that. And I also think the solution you offered is better suited for the @bchr02's purposes than what he originally wanted to do. But it still seems to me that there might be something wrong with reloadAfterSubmit, which should have worked (albeit inefficiently)

flack commented 9 years ago

to be more specific:

So the posted config should have worked. Or am I missing something?

bouks commented 9 years ago

Oleg implemented "opts.fromServer" parameter in reloadGrid. So i think these lines should maybe add the parameter ?

flack commented 9 years ago

Hm, from reading the code it seems like a sensible solution, because that's how jqgrid 4.7 used to work. But I haven't made any actual tests, so don't take my word for it :-)

BTW: What do you think about changing the default for reloadAfterSubmit to false? In some cases, it might be useful to reload the entire grid after update (for example, if your backend changes the posted values or does server-side rendering), but by default, we might just write the posted data back to the row, the logic for it seems to be already there in https://github.com/openpsa/jsgrid/blob/master/dist/jsgrid-0.1.0.js#L8412-L8416

meh-uk commented 9 years ago

Sounds better.

bouks commented 9 years ago

Sounds good. I could remove all my hacks :) But before setting it to false, i think we should find why was it setted to true for default value.

bouks commented 9 years ago

Just one thing, the last part of jsgrid you mention apparently does not let the possibility of returning server side qualified "error" from the server. So if not, we should implement this.

https://github.com/openpsa/jsgrid/blob/master/dist/jsgrid-0.1.0.js#L8378-L8391

bchr02 commented 9 years ago

thanks everyone for your help. Especially @bouks I got it working.

To me when having the ($.jgrid.edit) set with a url, there should still be a property that we could use to specify whether the jsgrid function should update the row locally, so one doesn't need to program this in manually unless they want to. What do you guys think?

Here is what it could look like:

$.extend(true, $.jgrid.edit, {
    url: "/update.php",
    mtype: "POST",
    localUpdate: true
});
bchr02 commented 9 years ago

just to clarify; the server side should still get the update but when localUpdate is set to true jsgrid will update the row locally as well.

bouks commented 9 years ago

I think it's better to review and change the actual functionning of datatype... like i said in other issues than add others many "scotch" options.

bouks commented 9 years ago

@bchr02 When saving to server, it's better to repopulate the row with datas from the server than the "local" form. It can prevent data corruption in database by seeing it immediatly.

bchr02 commented 9 years ago

@bouks My first impression when you mentioned this was that it would add unnecessary overhead. But after having implemented it and thinking about it, I now agree with you that it's better to repopulate from the server.

For others who try to make use of jsgrid, it would probably be good if we added some comments about this in the API documentation and included your example https://github.com/openpsa/jsgrid/issues/106#issuecomment-73275933 and samples of how the data should be returned from the server.