1

Quick background: I'm updating existing code to separate event handlers from html objects and, in an onload function I'm then assigning all necessary handlers.

$('input[name^="interactiveElement_"]').each(function() {
    var fieldName = "interactiveElement_";
    var elementNumber = $(this).attr("name").substring(fieldName.length,$(this).attr("name").indexOf("_",fieldName.length));
    var subElementNumber = $(this).attr("name").substring((fieldName+itemNumber+'_').length,$(this).attr("name").lastIndexOf('_'));
    var rowNumber = $(this).attr("name").substring($(this).attr("name").lastIndexOf('_')+1);

    $(this).on("click.custNamespace", function() {
        updateThisElementsMetadata(elementNumber, subElementNumber, rowNumber);
        updatePreview(elementNumber);
    });
});

Now for the hard part. In this interface, users will be able to trigger clones of existing elements. These clones need to have some of their handler arguments updated to new values.

Before separating out the events, I was doing that with this:

var regex = /([^0-9]+[0-9]+[^0-9a-zA-Z]+[0-9]+[^0-9a-zA-Z]+)([0-9]+)([^0-9]+)?/g; 
$(element).attr("onclick",
                $(element)
                    .attr("onclick")
                    .replace(regex, "$1"+newValue+"$3"));

and so on for each possible event these elements could have.

But, now using jQuery's on(event, handler) I no longer have visibility to what the handler is.

I've tried this (following this question - Get value of current event handler using jQuery):

jQuery._data(element).events.click[0].handler 

But, this returns the function with variable names not values.

function () {
    updateThisElementsMetadata(elementNumber, subElementNumber, rowNumber);
    updatePreview(elementNumber);
}

Where I would have hoped for:

function () {
    updateThisElementsMetadata(1, 2, 1);
    updatePreview(1);
}

Looking in the console log I see that jQuery._data(element).events.click[0] has the values in handler => < function scope > => Closure but it doesn't seem like there is dot notation to access that, or even an array that I can dynamically cycle through.

If you tell me this isn't possible, I could change all the functions' args to just be $(this) and parse out the necessary values from it in each function, or I guess I could have a helper function... but if I could keep a similar setup to what was there it would ease other dev's learning curve.

Final Solution

To reduce duplicate code, I created a Javascript function/object that parses out necessary info from name/id tag (instead of data- attributes to reduce redundant info). Whenever an event handler is triggered it will first parse out the necessary values and then run the function w/ them.

$('input[name^="interactiveElement_"]').on("click.custNamespace", function() {
    var inputField = inputFieldClass(this);
    updateThisElementsMetadata(inputField.elementNumber, inputField.subElementNumber, inputField.rowNumber);
    updatePreview(inputField.elementNumber);
});


var inputFieldClass = function(field) {
    var fieldIdentity = $(field).attr("name") === undefined ?  $(field).attr("id") :  $(field).attr("name");
    var fieldName = fieldIdentity.substring(0,fieldIdentity.indexOf("_")),
        elementNumber = fieldIdentity.substring(fieldName.length + 1,fieldIdentity.indexOf("_",fieldName.length + 1)),
        subElementNumber = fieldIdentity.substring((fieldName+'_'+elementNumber+'_').length,fieldIdentity.lastIndexOf('_')),
        rowNumber = fieldIdentity.substring(fieldIdentity.lastIndexOf('_')+1);

    return {
        fieldName : fieldName,
        elementNumber : elementNumber,
        subElementNumber : subElementNumber,
        rowNumber : rowNumber,
        getInputName : function () {
            return this.name + "_" + this.elementNumber + "_" + this.subElementNumber + "_" + this.rowNumber;
        }
    };
};
2
  • "I could change all the functions' args to just be $(this) and parse out the necessary values from it in each function" - do that, you'll be doing the other devs a favor. Actually, you don't need any args at all, this is automatically available in the handlers. Moreover, you can bind all handlers at once, or delegate a single handler to a common ancestor. Commented Jul 13, 2013 at 3:45
  • Yes, you are probably right. In regards to this arg, I think, I have to explicitly set the function to accept it when for example: somefucntion() in a foreach calls anotherfunction(), where anotherfunction() is also called in a handler. Or, I'm I wrong in assuming the foreach doesn't pass this to another function? Commented Jul 14, 2013 at 20:32

1 Answer 1

1

What I was suggesting in the comments was something like this:

$('input[name^="interactiveElement_"]').on("click.custNamespace", function() {

    var fieldName = "interactiveElement_";
    var elementNumber = $(this).attr("name").substring(fieldName.length,$(this).attr("name").indexOf("_",fieldName.length));
    var subElementNumber = $(this).attr("name").substring((fieldName+itemNumber+'_').length,$(this).attr("name").lastIndexOf('_'));
    var rowNumber = $(this).attr("name").substring($(this).attr("name").lastIndexOf('_')+1);

    updateThisElementsMetadata(elementNumber, subElementNumber, rowNumber);
    updatePreview(elementNumber);
});

Also, instead of parsing everything from the element's name, you could use data- attributes to make it cleaner (e.g. data-element-number="1", etc.).

Sign up to request clarification or add additional context in comments.

1 Comment

This is pretty similar to what I ended up doing last night. I'll post what I did as part of my question above. While this doesn't necessarily answer the question of dynamically changing values in an event handler, I think the key answer here is that changing data must either be in either name/id or in data- attributes, since those values can be changed dynamically.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.