2

I have this function which was working:

$('#buttFurniture').click(onFilterCLick);

but then i decided to add some argument to the function and it stopped working:

$('#buttFurniture').click(onFilterCLick(arrOutput, arrFurniture));

full function:

function onFilterCLick(arrFull,arrCurrent) {
    $('#buttFurniture').css("background-color", "#F1F1F1");
    $('#buttCars').css("background-color", "#F1F1F1");
    $('#buttGames').css("background-color", "#F1F1F1");
    $('#buttFurniture').css("color", "black");
    $('#buttCars').css("color", "black");
    $('#buttGames').css("color", "black");

    $(this).css("background-color", "#656565");
    $(this).css("color", "white");

    if (jQuery.inArray(arrCurrent[0], arrFull)) {
        console.log("asdasd");
    }
}
1
  • 2
    Use anonymous function. $('#buttFurniture').click(function() { onFilterCLick(arrOutput, arrFurniture)}); Commented Nov 5, 2015 at 10:48

5 Answers 5

5

The solution: Use bind to assign arguments when passing functions:

 $('#buttFurniture').click(onFilterCLick.bind($('#buttFurniture'), arrOutput, arrFurniture));

Explanation: In javascript, functions are what's known as first class objects - that means they can be passed around as variables, like other primitives (numbers, booleans etc.), but also as arguments to functions.

In this regard, it's important to note a key difference in passing a function as a variable, and invoking a function. For example, consider the following function:

var myFunc = function () {
    return 0;
} 

Now, note the difference between these two statements:

typeof myFunc // "function"
typeof myFunc() // "number"

As you can see, the first is a reference to the function itself, and the second is the invocation of that function - a subtle but key difference.

Your click handler expects a function as it's argument, and NOT a function invocation (or the result of a function being called). That's why you must use bind: bind allows you to pass the function itself, but also gives you the ability to pre-fill the arguments of the function you're passing.

In brief, the bind() function (in your case) takes 3 arguments - the first argument, in every bind() function, is the this parameter - setting this to your selected element is necessary, so that your $(this) invocation has the right context. The other arguments are where you pre-fill the rest of your function's parameters.

Hope this helps!

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

6 Comments

@Tushar I'm not sure of your point. This solves the OPs problem and is neater than wrapping a named function call in an anonymous function (IMO)
@RoryMcCrossan This is not readable and confusing than using anonymous function.
@Jonathan Did you notice that OP is using $(this) inside onFilterCLick function that's why OP is getting problem.
@Jonathan Why to use $('#buttFurniture') instead you can pass an argument then use that to refer this... how about ? onFilterCLick.bind(this, arrOutput, arrFurniture) and inside the function use $(this)
@BhojendraNepal It didn't work because in that scope, this referred to the window object. I edited it to just explicitly call the correct element again. All done now
|
1

You can use the callback function of click event to call another function with parameter.

$('#buttFurniture').click(function () {
    onFilterCLick(arrOutput, arrFurniture)
});

2 Comments

Yes, without clicking #buttFurniture, the button procs 2 times
actually everything is working perfectly with the console, it doesn't proc at all
1

I would recommend to use the .bind(null,func_arguments) method as described by @JonathanBrooks when you don't use the $(this) inside the function definition since this would refer to window object.

However, if you want to select the context as 'this' then I would recommend you to use like this:

function onFilterCLick(elem,arrFull,arrCurrent) {
  //now you can use elem to refer $(this)
  elem.css("background-color", "#656565");
}

And use the anonymous function for the click event like this:

$('#buttFurniture').click(function(){
    onFilterCLick($(this),arrOutput,arrFurniture);
});

A working code example here

Comments

0

It doesn't work because you're calling onFilterCLick(arrOutput, arrFurniture) in $('#buttFurniture').click(onFilterCLick(arrOutput, arrFurniture)); not passing onFilterCLick as handler for click event.

2 Comments

@murloc Tushar gave the answer in the comment
well, it doesn't work that is not the problem.. well I will just have to go around it
0

In case if #buttFurniture is generated after the DOM is ready

function onFilterCLick(arrOutput, arrFurniture) {
    console.log(arguments);
    console.log($(this));
    $(this).toggleClass('red-border');
};

$('#buttFurniture').on('click', function (evt) {
    evt.preventDefault();
    var holder = onFilterCLick.bind(this); 
    holder('argOne', 'argTwo');
});

.bind(this) will override this inside function scope if you want to select same element that you clicked.

UPDATE

I've updated the example, sorry for untested code, here is the fidle also read this article for better bind understanding ;)

This also will work.

var holder = onFilterCLick.bind(this, 'argOne', 'argTwo'); 
holder();

I hope this will help you.

3 Comments

onFilterCLick will be undefined.
did you test your code? this doesn't work. this throws an error undefined
I've updated my answer, now the example should work.

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.