Transtale jquery event's this to a function parameter

I have been wondering about a particular case when using jQuery's this on events.

Lets say we have the following function:

function myPrint(randomString){
  console.log(randomString);
}

And we want to bind it to an input's change event using jQuery, in a way that it will print the input's content every time it changes.

It could be done like this:

$('input').change(function(){
  myPrint(this.value);
})

Suppose we now want to bind myPrint in the same way to several other inputs. The first version would look like this:

$('input1').change(function(){
  myPrint(this.value);
})
$('input2').change(function(){
  myPrint(this.value);
})
.
.
.
$('inputN').change(function(){
  myPrint(this.value);
})

But this would violate DRY, as we are repeating the same anonymous function over and over again. A simple way to adress this issue would be declaring a local handler function:

function handler(){
  myPrint(this.value);
}
$('input1').change(handler);
$('input2').change(handler);
.
.
.
$('inputN').change(handler);

But this would require the handler function.

So, my question is: Is there a way to eliminate the need to use all of the anonymous functions without declaring another function like handler?

I tried to use bind like this:

$('input1').change(myPrint.bind(null, this.value));

But it won't work as this is not inside the scope of the event, thus not referring to the input.


edit: This question is not really about jQuery's options, it's about the translation from this to a parameter to another function without the need to declare a helper function.

Answers


Nope.

You have to have a function for each callback, and if you want to pass parameters in to a function within the callback, it needs a wrapper callback.

However, in this particular case, you can do this:

$('input1, input2, input3, inputN').change(function() {
    myPrint(this.value);
});

The parameter you pass to $() works just like CSS selectors, so, just like CSS selectors, you can comma-separate multiple selectors to group them all together.

If you want to use the same function for multiple events, you can use bind and pass space-delimited event names:

$('input1').bind('change click', function() {
    myPrint(this.value);
});

you can use jquery like this :

$("input").each( function() { this.change( function () { alert("a"); } ) } );

Well you can select multiple input in 1 selector and then call you function :

$('input1, input2, input3').change(function(){
    myPrint(this.value);
})

translation from this to a parameter to another function without the need to declare a helper function.

Well, since bind doesn't do it and there are no other native functions like this, we need a custom helper function. However, we can create that with functional programming instead of using a function expression.

Notice that you still should create a single handler only which you bind to all the elements, instead of creating new handlers for every element. Whether you do that by using a variable to store it, or whether you call .change() on a collection of all the elements, doesn't matter.

Function.prototype.methodize = function() {
    // http://api.prototypejs.org/language/Function/prototype/methodize/
    var f = this;
    return function() {
        return f.call(null, this);
    };
};
Function.prototype.map = function(g) {
    // function composition
    var f = this;
    return function() {
        return g(f.apply(this, arguments));
    };
};
Object.get = function(p) {
    return function(v) { return v[p]; };
};

Now you can use

var handler = Object.get("value").map(myPrint).methodize();

Need Your Help

Loading image dynamically from Applet

java image applet appletviewer

I have the following Applet code to load an image.