Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jquery selectors for plain javascript objects instead of DOM elements

I've just started using jquery and I'm really enjoying using selectors. It occurs to me that the idiom would be a very nice way to traverse object trees (e.g., JSON query results). For example, if I have an object like this:

var obj = { 'foo': 1, 'bar': 2,
            'child': { 'baz': [3, 4, 5] }
          };

I would love to be able to write something like $('child baz:last', obj) and get 5. I recognize that chaining wouldn't work, but I'd still love the selection operator. Anyone know if such a beast exists, or what the easiest way would be to write one?

like image 797
brendan Avatar asked Jul 17 '09 16:07

brendan


1 Answers

Here's a proof-of-concept implementation for getting jQuery itself work on objects. Through an object wrapper (FakeNode), you can trick jQuery into using its built-in selector engine (Sizzle) on plain JavaScript objects:

function FakeNode(obj, name, parent) {
    this.obj = obj;
    this.nodeName = name;
    this.nodeType = name ? 1 : 9; // element or document
    this.parentNode = parent;
}

FakeNode.prototype = {
    documentElement: { nodeName: "fake" },

    getElementsByTagName: function (tagName) {
        var nodes = [];

        for (var p in this.obj) {
            var node = new FakeNode(this.obj[p], p, this);

            if (p === tagName) {
                nodes.push(node);
            }

            Array.prototype.push.apply(nodes,
                node.getElementsByTagName(tagName));
        }

        return nodes;
    }
};

function $$(sel, context) {
    return $(sel, new FakeNode(context));
}

And the usage would be:

var obj = {
    foo: 1,
    bar: 2,
    child: {
        baz: [ 3, 4, 5 ],
        bar: {
            bar: 3
        }
    }
};

function test(selector) {
    document.write("Selector: " + selector + "<br>");

    $$(selector, obj).each(function () {
        document.write("- Found: " + this.obj + "<br>");
    });
}

test("child baz");
test("bar");

Giving the output:

Selector: child baz
- Found: 3,4,5
Selector: bar
- Found: 2
- Found: [object Object]
- Found: 3

Of course, you'd have to implement a lot more than the above to support more complex selectors.

BTW, have you seen jLinq?

like image 85
Ates Goral Avatar answered Oct 05 '22 23:10

Ates Goral