null
null

Reputation: 3517

Deserializing JSON from local storage to Fabric JS object - JSON created from form data

I'm using Fabric js for a project I'm working on and encountering a few difficulties. My aim is to allow a user to enter details into a form. The form will then be turned into a JSON object and stored using local storage.

Upon pressing submit the user is taken to a new page where the JSON is retrieved and objects are created.

I'm having difficulty with the latter part. Getting the information from the form into JSON is working fine, various tests show that the output is as it should be.

When creating the object there are problems, the object is showing on the canvas as a simple border with corners, it can be moved and selected but all other attributes such as size and colour are lost. I think it's because of how the JSON is being deserilized. I've searched for a solution but yet to find one, any help is hugely appreciated.

Sample code:

This is my test instance that creates an object as expected:

var a = {
    type: "rect",
    left:200,
    top:110,
    fill:'red',
    width:80,
    height:50
};

The same as above but from the local storage:

[Log] From JSON:    {"type":"rect","top":"110","left":"200","fill":"red","height":"50","width":"80"} (sim.html, line 135)

To get the data I'm using:

var test = localStorage.getItem("Number1");
console.log("From JSON: " +test);

var obj = JSON && JSON.parse(test) || $.parseJSON(test);
console.log(obj.type +"-"+ obj.left);

When a is added in the below method it works yet obj does not. The main difference I can see if the quotations but I'm not sure if that is the issue and if so how to remove it simply.

Function to iterate over and render objects:

    fabric.util.enlivenObjects([circle1, obj], function(objects) {
    var origRenderOnAddRemove = canvas.renderOnAddRemove;
    canvas.renderOnAddRemove = false;

    objects.forEach(function(o) {
        canvas.add(o);
    });
    canvas.renderOnAddRemove = origRenderOnAddRemove;
    canvas.renderAll();
});

Many thanks for any help.

Upvotes: 0

Views: 1189

Answers (1)

Pointy
Pointy

Reputation: 413737

I think you can modify your "serialize" routine so that it converts appropriate inputs to numbers:

$.fn.serializeObject = function() {
    var o = {};
    var a = this.serializeArray();
    $.each(a, function() {
        var value = this.value || '';
        if (/^\d+$/.test(value))
          value = +value;

        if (o[this.name] !== undefined) {
            if (!o[this.name].push) {
                o[this.name] = [o[this.name]];
            }
            o[this.name].push(value);
        } else {
            o[this.name] = value;
       }
    }} );
    return o;
};

That looks for input values that look like numbers and converts them. (It only looks for integers; if you wanted to also test for numbers with decimal fractions the regular expression could be modified.)

This isn't the most robust thing in the world, since it's making a fairly big assumption. To be more accurate you'd have to do something like tag your form inputs with a class to identify whether they're supposed to be treated as numeric, and then implement your own serializer to traverse all the inputs.

Upvotes: 1

Related Questions