Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Retrieve data from handsontable to Struts2 Action via JSON not working

I am using struts2-json plugin to generate JSON data and Ajax to populate table (handsontable) with data from that JSON (according to the source).

Now, I need to retrieve data from table to Struts2 Action using Ajax by JSON. First I've implemented populating table with data passed by JSON from Struts2 Action to Handsontable, that was quite easy and it works. But why save do not work as you can see in attached code below?

As I see in a firebug the POST is sent and in debug the request is retrieved in my JSONSaveAction action but the field data is not being populated with JSON data, why? Data shouldn't be binded to java object automatically by struts2-json plugin? What am I doing wrong?

In handsontable part the function handsontable.getData() is responsible for getting whole data from table. So I am using it like this but without success:

$.ajax({
        url: "../json/saveJSONDataAction.action",
        data: {data: handsontable.getData()}, //returns all cells' data
        dataType: 'json',
        type: 'POST',
        success: function (res) {
            if (res.result === 'ok') {
                $console.text('Data saved');
            }
            else {
                $console.text('Save error');
            }
        }
    });

The function handsontable.getData() really retrieve all data what I checked but instead of that the data is not binded to java object List<Report> data in my JSONSaveAction action. Do you know why?

Here is screenshot with my table and firebug info after POST request: enter image description here

Action sending JSON to handsontable (working fine):

@ParentPackage("json-default")
@Action(value="getJSONDataAction")
@Result(name="success", type="json")
public class JSONDataAction extends ActionSupport {
    private static final long serialVersionUID = 1L;

    private List<Report> data = new ArrayList<Report>();

    public JSONDataAction(){
        data.add(new Report(1, "Chris", true, "2008-01-01", "orange"));
        data.add(new Report(2, "Kate", false, "2013-03-03", "blue"));
        data.add(new Report(3, "Blade", true, "2013-05-03", "black"));
        data.add(new Report(4, "Zack", false, "2013-01-01", "yellow"));
    }

    public String execute() {
        return SUCCESS;
    }

    public List<Report> getData() {
        return data;
    }

    public void setData(List<Report> data) {
        this.data = data;
    }
}

JSON which is sent to populate table generated automatically:

{"data":[
    {"active":true,"color":"orange","date":"2008-01-01","id":1,"name":"Chris"},
    {"active":false,"color":"blue","date":"2013-03-03","id":2,"name":"Kate"},
    {"active":true,"color":"black","date":"2013-05-03","id":3,"name":"Blade"},
    {"active":false,"color":"yellow","date":"2013-01-01","id":4,"name":"Zack"}]
}

Action retrieving data from table via JSON (not working):

Here the field List<Report> data is always null, is not populated with data from JSON :(

@ParentPackage("json-default")
@Action(value="saveJSONDataAction")
@Result(name="success", type="json")
public class JSONSaveAction extends ActionSupport {
    private static final long serialVersionUID = 1L;

    private List<Report> data;

    public JSONSaveAction(){
    }

    public String execute() {
        try {
            JSONObject jsonData = (JSONObject) JSONSerializer.toJSON(data);
            String name = jsonData.getString("name");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return SUCCESS;
    }

    public List<Report> getData() {
        return data;
    }

    public void setData(List<Report> data) {
        this.data = data;
    }
}

Report class:

public class Report {
    private int id;
    private String name;
    private boolean active;
    private String date;
    private String color;

    //getters and setters
}

Load & Save data into and from table via JSON:

<div id="spreadsheet">
    <p>
        <button type="button" name="load">Load</button>
        <button type="button" name="save">Save</button>
    </p>
</div>
<div id="console" class="console"></div>

<script>
    var $container = $("#spreadsheet");
    var $console = $("#console");
    var $parent = $container.parent();
    $container.handsontable({
        startRows: 4,
        startCols: 20,
        rowHeaders: true,
        colHeaders: true,
        contextMenu: true,
        columns: [
            {data: "id", type: 'text'},
            {data: "name", type: 'text'},
            {data: "active", type: 'checkbox'},
            {data: "date", type: 'date'},
            {data: "color",
                type: 'autocomplete',
                source: ["yellow", "red", "orange", "green", "blue", "gray", "black", "white"]
            }
        ]
    });
    var handsontable = $container.data('handsontable');

    $parent.find('button[name=load]').click(function () {
        $.ajax({
            url: "../json/getJSONDataAction.action",
            dataType: 'json',
            type: 'GET',
            success: function (res) {
                handsontable.loadData(res.data);
                $console.text('Data loaded');
            }
        });
    });

    $parent.find('button[name=save]').click(function () {     
        $.ajax({
            url: "../json/saveJSONDataAction.action",
            data: {data: handsontable.getData()}, //returns all cells' data
            dataType: 'json',
            type: 'POST',
            success: function (res) {
                if (res.result === 'ok') {
                    $console.text('Data saved');
                }
                else {
                    $console.text('Save error');
                }
            },
            error: function () {
                $console.text('Save error.');
            }
        });
    });
</script>

Please help me how to retrieve data from table to java object correctly, because it really blocked me. I do not know what I am doing wrong...

Big thanks for any input!

like image 475
Roman Avatar asked May 21 '13 17:05

Roman


2 Answers

I've fixed it.

1: In struts.xml add:

<interceptor-ref name="json">
    <param name="enableSMD">true</param>
</interceptor-ref>

2: In Ajax request add:

contentType: 'application/json'

3: Change JSON format which is automatically bad formatted by handontable. There were in JSON some characters like: %5B %5D %7B %7D %22 instead of: [ ] { } "

I've replaced them by own fixedEncodeURI() function:

var data = '{"data":' + fixedEncodeURI(JSON.stringify(handsontable.getData())) + '}';
$.ajax({
    url: "../json/saveJSONDataAction.action",
    data: data, //returns all cells' data
    dataType: 'json',
    contentType: 'application/json',
    type: 'POST',
    success: function (res) {
    }
  });

function fixedEncodeURI (str) {
    return encodeURI(str).replace(/%5B/g, '[').replace(/%5D/g, ']').replace(/%7B/g, '{').replace(/%7D/g, '}').replace(/%22/g, '"');
}
like image 54
Roman Avatar answered Oct 21 '22 20:10

Roman


I've not looked at your code thoroughly, but at first look it seems that you are erasing the data collection when you create a new one with that new ArrayList<Report>() in your Action. Just leave alone the declaration private List<Report> data;.

like image 41
Armaggedon Avatar answered Oct 21 '22 19:10

Armaggedon