1

I have a code for jqGrid with custom "editFunc" that opens my own jQuery-UI Panel to edit the data.

It saves the data without problems, but I can't get jqGrid to be updated with new data automatically using "$("#blog-posts").trigger("reloadGrid");" It doesn't work from "editFunc". The code is below. Not sure how to fix it. What I'm doing wrong here?

Another way I thought about is to do not do a full jqGrid reload, but update only the edited data. How to update a successfully edited jqGrid row with sucessfuly changed record data "manually" from editFunc, without reloading all records?

Here is my jqGrid config:

<table id="blog-posts">
</table>
<div id="blog-posts-nav">
</div>
<div id="edit-blog-post">
</div>
<script type="text/javascript">

    function wireUpForm(dialog, updateTargetId, updateUrl) {
        $('form', dialog).submit(function () {
            $.ajax({
                url: this.action,
                type: this.method,
                data: $(this).serialize(),
                success: function (result) {
                    // Check whether the post was successful
                    if (result.success) {
                        // Close the dialog
                        $(dialog).dialog('close');
                        // reload doesn't work if called from here
                        $("#blog-posts").trigger("reloadGrid");
                    } else {
                        // Reload the dialog to show model errors
                        $(dialog).html(result);
                        // Setup the ajax submit logic
                        wireUpForm(dialog, updateTargetId, updateUrl);
                    }
                }
            });
            return false;
        });
    }

    $('#blog-posts').jqGrid({
        url: 'http://localhost:24533/Admin/BlogPosts',
        datatype: "json",
        colModel: [
        { name: 'id', index: 'id', label: 'Post ID', width: 55 },
        { name: 'enabled', index: 'enabled', label: 'Enabled', width: 60, editable: true, edittype: "checkbox", editoptions: { value: "Yes:No"} },
        { name: 'slug', index: 'slug', label: 'Slug', width: 300, editable: true, editoptions: { style: "width:300px;"} },
        { name: 'header', index: 'header', label: 'Header', width: 300, editable: true },
        { name: 'HtmlTitle', index: 'HtmlTitle', label: 'HTML Title', width: 300, editable: true },
        {name: 'created', index: 'created', label: 'Created', width: 100, editable: true },
        { name: 'lastUpdate', index: 'lastUpdate', label: 'Last Update', width: 100 }
    ],
        rowNum: 10,
        rowList: [10, 20, 30],
        pager: '#blog-posts-nav',
        sortname: 'id',
        viewrecords: true,
        sortorder: "desc",
        caption: "Blog Posts",
        height: 210,
    });
    $('#blog-posts').jqGrid('navGrid', '#blog-posts-nav',
        {
           editfunc: function (rowid) {
                var element = $(this);
                // Retrieve values from the HTML5 data attributes of the link
                var dialogId = '#edit-blog-post';
                var dialogTitle = 'Dialog Title';
                var updateTargetId = '#container-to-update';
                var updateUrl = 'http://localhost:24533/Admin/BlogPostEdit/';
                // Load the form into the dialog div
                $(dialogId).load('http://localhost:24533/Admin/BlogPostEdit?id=' + rowid, function () {
                    $(this).dialog({
                        modal: false,
                        resizable: true,
                        minWidth: 650,
                        minHeight: 300,
                        height: $(window).height() * 0.95,
                        title: dialogTitle,
                        buttons: {
                            "Save": function () {
                                // Manually submit the form
                                var form = $('form', this);
                                //alert('1');
                                $(form).submit();
                                $("#blog-posts").trigger("reloadGrid");
                                //alert('2');
                            },
                            "Cancel": function () {
                                //alert($("#blog-posts"));
                                //$("#blog-posts").trigger("reloadGrid");
                                //alert($("#blog-posts").getCell(2,2));
                                //alert($("#blog-posts").getGridParam('caption'));
                                $("#blog-posts").trigger("reloadGrid");
                                //alert(element.serialize());
                                //element.trigger("reloadGrid");
                                //alert(element.attr('id'));
                                //$(this).dialog('close');
                            }
                        }
                    });

                    wireUpForm(this, updateTargetId, updateUrl);
                });

                return false;
            },

        { height: 280, reloadAfterSubmit: true }, // edit options
        {width: 600, reloadAfterSubmit: true, top: 100, left: 300, addCaption: 'Add Blog Post' }, // add options
        {reloadAfterSubmit: true }, // del options
        {} // search options
    );


    $('.wysiwyg').livequery(function () {
        $(this).wysiwyg();
    });

</script>

UPDATE: The problematic line of code is

 $(dialogId).load('http://localhost:24533/Admin/BlogPostEdit?id=' + rowid, function () {

After you do jQuery.load() the jqGrid's programmatic reload binding call trigger("reloadGrid") doesn't work anymore. The only way to reload the data that works after you do jQuery.load() is the reload button in the toolbar. I still don't know how to fix it.

UPDATE2 (solution): The problem was in HTML returned from jQuery.ajax() it was a full HTML page with HTML head and body tags. After server side started to return only the form jqGrid reload started to work.

Zelid
  • 6,905
  • 11
  • 52
  • 76

1 Answers1

1

I think the problem exist because you use $(form).submit(). What you probably want to do is to send data from the form to the server and refresh the data in the grid after the server processed the form submittion.

The $(form).submit() will be used in the case that your page consist mostly from the form. In the case you submit the data and the page will be refreshed. What you probably really want to do you can implement with respect of $.ajax with type: 'POST' parameter or with respect of its simplified form $.post. You can set the submit event handler (or click handler if you rename the type of the button) and inside the handler you can send the data to the server per $.ajax manually. In the case you can use success handler to reload the grid. Inside of submit event handler you can get the form data with $(form).serialize() and you should return false to prevent standard submitting of the form. See here an example. You should don't forget to define name attribute to all fields of the form which you want send to the server (see here).

I don't know exactly which relationship has the form to the grid data, but one more possible option which you have is to use postData parameter of jqGrid. See here for more details.

Community
  • 1
  • 1
Oleg
  • 220,925
  • 34
  • 403
  • 798
  • $.post doesn't help here. I tried to put "$("#blog-posts").trigger("reloadGrid");" instead of "$(this).dialog('close');" to a cancel function of jQuery-UI panel. There are no refreshes in that case, and jqGrid reload didn't work too. – Zelid Aug 16 '11 at 13:24
  • @user118657: I suppose that you try to refresh the grid data **before** the submit is processed on the server. I wrote in my answer what you can do to fix the problem. You don't included the code of `wireUpForm` so it is absolutely unclear which relation has the form data to the grid and it's unclear why you use `$.dialog` instead of the standard jqGrid edit form. One more remark: you should remove `http://localhost:24533` prefix from all URLs and use relative paths. – Oleg Aug 16 '11 at 13:40
  • I don't use the standard jqGrid edit form because I use ASP.NET MVC3 validation and model binding on the server side, because of it I need to use a special HTML markup in the form that is done using MVC3 HTML helpers. I'm adding the full source code right now. – Zelid Aug 16 '11 at 13:57
  • @user118657: you main problem could be because you placed **many** calls of `$("#blog-posts").trigger("reloadGrid")` in you code. If one call will be too early and the corresponding ajax call will be pending all other `reloadGrid` request will be **not quiet and just discarded** till the previous request are finished. You should have `reloadGrid` in `success` handler of `ajax` inside of `submit`. Other `reloadGrid` calls from `"Save"` and `"Cancel"` should be *removed*. I suppose that the `reloadGrid` immediately after `$(form).submit()` is your main problem. – Oleg Aug 16 '11 at 15:20
  • @user118657: By the way you can easy implement any kind of server side validation in standard jqGrid form. The server receive the new data and it can validate the data and use any error HTML code in the response in the case error message will be shown to the user. You can use [errorTextFormat](http://www.trirand.com/jqgridwiki/doku.php?id=wiki:form_editing#events) to decode the server response in case of error and to customization the message displayed to the user. See [here](http://stackoverflow.com/questions/5103424/jqgrid-forms-server-validations-and-custom-error-messages/5103844#5103844). – Oleg Aug 16 '11 at 15:26
  • I removed all calls to "reloadGrid" beside the on in ajax success, but it didn't help. I can do reload the grid by any link javascript handler outside the jqGrid, but it never works inside jqGrid. I still don't know the reason.. – Zelid Aug 16 '11 at 15:39
  • I used "Tamper Data" and found that `$("#blog-posts").trigger("reloadGrid");` doesn't do any GET requests to the server when used inside jqGrid declaration or external fucntion called from jqGrid declaration code. – Zelid Aug 16 '11 at 15:47
  • Also tried to put breakpoints inside `}).bind('reloadGrid', function (e, opts) {` in jqGrid source code - the breakpoints never getting activated. But when I do refresh manually through the toolbar - breakpoints are activated without problems. – Zelid Aug 16 '11 at 16:10
  • @Oleg let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/2540/discussion-between-user118657-and-oleg) – Zelid Aug 16 '11 at 16:20
  • @user118657: I never use `jQuery.load`. Instead of that I load the HTML fragment with `jQuery.ajax` and use `jQuery.html` to place the results to the page. Moreover I never place ` – Oleg Aug 16 '11 at 22:59