5
\$\begingroup\$

I wanted an excuse to do some OO JavaScript and I decided to do a JSON editor. It will basically allow you to input JSON and either collapse objects to see other objects better, delete objects (can currently only delete KV pairs), or edit objects. If you give it valid JSON it will output valid JSON.

The editor can be seen here.

This is for testing purposes; just hit load then stock JSON. The JavaScript is here.

One thing I am weary about is the fields in my base object. they are basically global. So I can always do something like

toPretty.json; //

I am thinking I should create some methods in my base object to return a new JSON instead of reading the file directly from the object.

Anyways, tear through this and please reply if you have any suggestions or critiques. It is still a work in progress and just a little fun side project.

var obj = {"widget": { "debug": "on", "window": { "title": "Sample Konfabulator Widget", "name": "main_window", "width": 500, "height": 500 }, "image": { "src": "Images/Sun.png", "name": "sun1", "hOffset": 250, "vOffset": 250, "alignment": "center" }, "text": { "data": "Click Here", "size": 36, "style": "bold", "name": "text1", "hOffset": 250, "vOffset": 100, "alignment": "center", "onMouseUp": "sun1.opacity = (sun1.opacity / 100) * 90;" } }};

function CodeArray(obj) {
    this.items = [];
    this.json = obj;
}

CodeArray.prototype = {
    createHtml: function (json) {
        var tierNum = 0, id = 0, self = this, str = "";
        this.items.length = 0;

        // id corresponds the markup element id
        function addElement(html, id) {
            var element = {}
            element.html = html;
            element.id = id;
            self.items.push(element);
        }
        // TODO: use J templates to add the html into addElement???
        // TODO: fix bug related to variable font width, and bug where if you send it a number it set input size the size is undefined
        function traverse(o) {
            id++;
            tierNum != 0 ? addElement("<li><div class='del'>x</div><ul class=t" + tierNum + " id=" + id + ">", id) : addElement("<ul class=t" + tierNum + " id=" + id + "><div class='del'>x</div>", id);
            for (var key in o) {
                if (typeof o[key] === "object") {
                    if (isNaN(key)) { addElement("<li class='item'><input type='text' class='key' value=" + key + " size=" + key.toString().length + ">: </li>", id); }
                    tierNum++;
                    traverse(o[key]);
                    tierNum--;
                } else {
                    addElement("<li class='item'><input type='text' class='key' value='" + key + "' size=" + key.toString().length + "> : <input type='text' class='val' value='" + o[key] + "' size=" + o[key].length + "><div class='del'>x</div><div class='save'> &#10003; </div></li>", id);
                }
            }
            tierNum != 0 ? addElement("</ul></li>", id) : addElement("</ul>", id);
        }
        traverse(json);
        updateResultsContainer(this.items);
        $("#textJson textarea").text(JSON.stringify(toPretty.json));
    },

    print: function () {
        for (var i = 0; i < this.items.length; i++) {
            console.log(this.items[i].id + " " + this.items[i].html);
        }
    },

    // TODO: delete Lists using list key. 
    deleteItems: function (toDelete) {
        var keys = toDelete.find(".key");
        var vals = toDelete.find(".val");

        function remove(delKey, delVal, o) {
            for (var key in o) {
                if (typeof o[key] === "object") {
                    if (remove(delKey, delVal, o[key])) { return true; }
                } else {
                    if (delKey == key && delVal == o[key]) {
                        delete o[key];
                        return true;
                    }
                }
            }
        }

        for (var i = 0; i < keys.length; i++) {
            remove(keys[i].value, vals[i].value, this.json);
        }

        this.createHtml(this.json);
    },

    convertToJson: function () {
        console.log(JSON.stringify(this.json));
    }
}
\$\endgroup\$
1
\$\begingroup\$

Not bad. Regarding your concerns that toPretty.json is visible from outside object-scope, people typically get around this by using the Module Pattern.

I am thinking I should create some methods in my base object to return a new json instead of reading the file directly from the object.

I'm not following. Which file/object? You appear to pass the JSON object from $.ajax to your constructor, and this is just a plain JavaScript object.

\$\endgroup\$
  • \$\begingroup\$ Thanks for the reply. When I say 'base Object' I was refering to my CodeArray 'class'. So I would do something like this instead. function CodeArray(obj) { this.items = []; this.json = function() { return new json; } } \$\endgroup\$ – user1944367 Jun 5 '13 at 0:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.