1

I have a lot of troubles with jQuery validate plugin and the only way I could work around it it was by using the .submitHandler property and do some tricks inside it.

On of which is checking if the parent of the trigger it's a fieldset and if it has an data-submit-handler attribute it will execute whatever I send there.

It would look something like this :

<fieldset data-submit-handler="SITE.Products.QA.Bindings.post">

In which case the SITE.Products.QA.Bindings.post would be an function. The issue is that I have no clue how to parse that string from the data attribute as an object and not as a string so I can execute the function that I reference to. Is there a way to do it ?

Roland
  • 9,321
  • 17
  • 79
  • 135
  • I do not have the same question, I'm not aware of the object as the above question describes. I can only send the string through – Roland Jun 07 '13 at 13:22
  • So, you don't have a reference to the object at all? `SITE` is not a variable? – Felix Kling Jun 07 '13 at 13:23
  • At the point that the submit handler is handled, no, it comes before all my code, it's part of the plugin manipulation – Roland Jun 07 '13 at 13:24
  • Then I guess you have to provide more information about the context. I cannot imagine how you'd want to call a method if you cannot access the object. – Felix Kling Jun 07 '13 at 13:25
  • Imagine that when the handler it's called, the `SITE` property it's not yet available, so I cannot send it when parsing that string as a reference. I hope I'm more clear, but I guess that `window` could be my ref ? – Roland Jun 07 '13 at 13:30
  • Well, you have to parse the string once `SITE` is available, either locally or globally. Of course, you cannot access the property if it does not exist, but then there is no point in parsing the attribute. – Felix Kling Jun 07 '13 at 13:31
  • Yeah, that does make sense .... I'll try an async binding of that handler then, so I can have the `SITE` available at that point – Roland Jun 07 '13 at 13:32
  • I have voted to close as it does seem, if I do the call async, as the other answer – Roland Jun 07 '13 at 13:36

1 Answers1

1

You can use a helper that will resolve it:

// convert string representation of object in to object reference:
// @p: object path
// @r: root to begin with (default is window)
// if the object doesn't exist (e.g. a property isn't found along the way)
// the constant `undefined` is returned.
function getObj(p, r){
    var o = r || window;
    if (!p) return o;                      // short-circuit for empty parameter
    if(typeof p!=='string') p=p.toString();// must be string
    if(p.length==0) return o;              // must have something to parse
    var ps = p.replace(/\[(\w+)\]/g,'.$1') // handle arrays
              .replace(/^\./,'')           // remove empty elements
              .split('.');                 // get traverse list
    for (var i = 0; i < ps.length; i++){
        if (!(ps[i] in o)) return undefined; // short-circuit for bad key
        o = o[ps[i]];
    }
    return o;
}

// couple extensions to strings/objects

// Turns the string in to an object based on the path
// @this: the string you're calling the method from
// @r: (optional) root object to start traversing from
String.prototype.toObject = function(r){
    return getObj(this,r);
};

// Retrieves the supplied path base starting at the current object
// @this: the root object to start traversing from
// @s: the path to retrieve
Object.prototype.fromString = function(p){
    return getObj(p,this);
};

So, example usage:

window.foo = {
    bar: {
        baz: {
            hello: 'hello',
            world: function(){
                alert('world!');
            }
        }
    },
    list: [
        {item: 'a'},
        {item: 'b'},
        {item: 'c'}
    ]
};

var a = 'foo.bar.baz.hello';
console.log(getObj(a));    // hello
console.log(a.toObject()); // hello

var b = 'foo.bar.baz.world';
console.log(getObj(b)());  // world

var c = 'baz.hello';
console.log(getObj(c, foo.bar)); // hello
console.log(foo.bar.fromString(c)); // hello
console.log(c.toObject(foo.bar)); // hello

var d = 'foo.list[1].item';
console.log(getObj(d)); // b
Brad Christie
  • 100,477
  • 16
  • 156
  • 200