JEditable, how to handle a JSON response?
Asked Answered
B

4

15

Right now, the server response I'm working with sends back a JSON response like this:

{"status":1}

After saving, jeditable places the actual response: {"status":1} on the page. Anyway to get around this issue?

Barthel answered 8/2, 2010 at 18:5 Comment(1)
The 'value' variable in the callback, described in Felipe's answer, holds the server response. So you can do whatever you want with it in the callback. I used my server's JSON response to fill in the displayed text on the page for the user, and also to determine other changes on the page.Muff
G
23

A better solution is to post-process the returned json data before it hits the page.

Suppose your server returns the following json string:

{ "status": 1, "result": "value to be displayed", "other": "some other data" }

and you would like to process the "status" and "other" fields, and display the "result" field in the jeditable input field.

Add the following 2 lines to jquery.jeditable.js:

(around line 95):

var intercept = settings.intercept || function(s) {return s; };

(around line 350, right after " success : function(result, status) {"

result = intercept.apply(self,[result]);

Then, in your own code, do something like the following:

$(some_field).editable(
 '/some_url_on_your_server',
 {
     indicator : "<img src='/images/spinner.gif'>",
     tooltip: "Click to edit.",
     indicator: "Saving...",
     onblur: "submit",
     intercept: function (jsondata) {
         obj = jQuery.parseJSON(jsondata);
         // do something with obj.status and obj.other
         return(obj.result);
     },
     etc.

This allows you do cool stuff like having your server convert abbreviations to full strings etc.

Enjoy!

Gabriel answered 6/1, 2011 at 4:54 Comment(4)
Blows my mind that this doesn't exist in the plugin by default. Thanks for your help.Booster
Agreed: it should be in the plugin as it's extremely handy for a bunch of use cases.Gabriel
+1 @relipse The page is appelsiini.net/projects/jeditable which states Mika Tuupola. This answer is super neat and I have put it into place, unfortunately one is stuck at the their current version. Sort of like link-only answers are useful now but not so useful later.Sika
I don't think this is the best answer anymore. You don't need to edit the source code to parse a json response. (Maybe the source code has changed since this answer? ) You can just use the callback as in Felipe's answer. The value in the callback refers to the server response, NOT the submitted form content (as the author's site misstates)!Muff
L
12

There's a simple way of doing this by using the callback. .editable() converts any response to a string, so the response has to be converted to a JSON variable. The values can then be retrieved and then written using a '.text()' method. Check the code:

$("#myField").editable("http://www.example.com/save.php", { 
    submit    : 'Save',
    cancel    : 'Cancel',
    onblur    : "ignore",
    name      : "sentText",
    callback : function(value, settings) {
        var json = $.parseJSON(value);
        $("#myField").text(json.sentText);
    }
});
Lomasi answered 8/5, 2013 at 3:14 Comment(4)
This is a great solution, where I don't have to edit the JEditable script, thx.Jarid
I was going to say that I don't see how this would work. In the callback, value refers to the submitted value, not the response. But I just tested it and value IS the return value NOT the submitted value! On the jeditable page (appelsiini.net/projects/jeditable), it says "Value contains submitted form content." which is incorrect! (Also, by the way, you have an extra quote after save.php that is messing up your code markup.)Muff
Great solution without a hack!Deduct
You can target the field to update as $(this).text(json.sentText); and that will allow this to be a more generic binding across fields.Welbie
S
2

This is how I handled the json response.

First, set the datatype using ajaxoptions. Then, handle your data in the callback function. Therein, this.revert is your original value.

oTable.$('td:eq(3)').editable('/admin/products/add_quantity_used', {
    "callback" : function(sValue, y) {
        var aPos = oTable.fnGetPosition(this);          
        if($("#dialog-message").length != 0){
            $("#dialog-message").remove();
        }
        if(!sValue.status){
        $("body").append('<div id="dialog-message" style="display:none;">'+sValue.value+'</div>');
        $( "#dialog-message" ).dialog({
            modal: true,
            buttons: {
                Ok: function() {
                    $( this ).dialog( "close" );
                }
            }
        }); 
        if(this.revert != '')
            oTable.fnUpdate(this.revert, aPos[0], aPos[1]);
        else 
            oTable.fnUpdate("click to edit", aPos[0], aPos[1]);
      }else
        if(sValue.status)
            oTable.fnUpdate(sValue.value, aPos[0], aPos[1]);


    },
    "submitdata" : function(value, settings) {
        return {
            "data[users_to_products][users_to_products_id]" : this.parentNode.getAttribute('id'),
            "column" : oTable.fnGetPosition(this)[2]                
        };
    },
    "height" : "30px",
    "width" : "30px",
    "maxlength" : "3",
    "name" : "data[users_to_products][quantity_used]",
    "ajaxoptions": {"dataType":"json"}
}).attr('align', 'center');
Saidel answered 6/9, 2012 at 23:16 Comment(1)
Welcome to StackOverflow. Please keep in mind, that punctuation and proper capitalization helps tremendously when reading posts.Juvenility
B
0

So the solution I came up with is similar to what madcapnmckay answered here.

var editableTextArea = $('.editable-textarea');
        editableTextArea.editable(submitEditableTextArea, {
    type      : 'textarea',
    cancel    : 'Cancel',
    submit    : 'Save',
            name            : editableTextArea.attr('id'),
            method      : 'post',
            data            : function(value, settings) {
                                        return $.fn.stripHTMLforAJAX(value);
                                    },
            event     : "dblclick",

    onsubmit    : function(value, settings) {
                //jquery bug: on callback reset display from block to inline
                $('.btn-edit').show(0, function(){$(this).css('display','inline');});
              },
    onreset     : function(value, settings) {
                //jquery bug: on callback reset display from block to inline
                $('.btn-edit').show(0, function(){$(this).css('display','inline');});
              }
  });

Then the url function is

function submitEditableTextArea(value, settings) { 
                        var edits = new Object();
                        var result = $.fn.addHTMLfromAJAX(value);
                        edits[settings.name] = [value];
                        var returned = $.ajax({
                            type            : "POST",
                            data            : edits,
                            dataType    : "json",
                            success     : function(_data) {
                                var json = eval( _data );
                                if ( json.status == 1 ) {
                                    console.log('success');
                                }
                            }
                        });
                        return(result);
                    }
Barthel answered 8/2, 2010 at 21:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.