0

I'm dynamically creating a table row full of checkboxes using JavaScript in the function populateParameterTr(parameters). In this function, I set an event handler such that when the checkbox is made active, a hidden input field is created in the toggleHidden function.

What I'm having trouble with is trying to call toggleHidden to create these hidden input elements after the checkbox is created, ie not in the event handler. Reason being: I want these hidden input fields when the checkboxes are loaded for the first time. From my understanding calling toggleHidden() results in this pointing to the global scope.

I've had a look at bind,call and apply to see if this will help like below:

toggleHidden(display, parameterContainer).bind(checkbox); 

Can someone advise me if this can be done. I'm looking at this example as an exercise to get my head around using these methods.

Code:

var populateParameterTr = function(parameters) {
   var checkboxes = $('<td></td>');

   for (var i in parameters) {
     var display = parameters[i].display;
     var checkbox = $('<input>').attr({
       //...
     });

     var parameterContainer = $('<div></div>').addClass('parameter').append(checkbox);

     checkboxes.append(parameterContainer);

     toggleHidden(display, parameterContainer).bind(checkbox); 

     checkbox.on('change', toggleHidden(display, parameterContainer));

    }
}

var toggleHidden = function(display, tableDivide) {
   return function() {
     if (this.checked) {
       var hidden = $('<input>').attr({
         //......
       });
       hidden.appendTo(tableDivide);
     } else {
       $(this).siblings("input[type='hidden']").remove();
     }
   };
};
LeDoc
  • 935
  • 2
  • 12
  • 24
  • Note that `bind` doesn't actually alter the original function - it instead returns a new function with the `this` value bound. – James Thorpe Jul 08 '15 at 09:46

1 Answers1

1

.call and .apply directly executes the function with first param is thisArg, the difference between them is .call accepts parme like .call(thisArg, param1, param2....) , but .apply accepts like .apply(thisArg, [param1, param2....]).

.bind returns a new Function, when it executes, it use the first param when you call .bind as thisArg, and if you gives other param, it'll put it directly to the origin function for you, e.g:

var func = function(param1, param2) {
  console.log(param1, param2);
};
var bindFunc = func.bind(null, 1);

bindFunc(2);  // log 1, 2 now

Take above knowledge to examine the code you post:

toggleHidden(display, parameterContainer).bind(checkbox);

It Seems you want to call it, and the this is reference to that checkbox, so you can write:

toggleHidden.call(checkbox, display, parameterContainer);
// or 
toggleHidden.apply(checkbox, [display, parameterContainer]);

Then this part:

checkbox.on('change', toggleHidden(display, parameterContainer));

Here you want to call toggleHidden when checkbox change, as you're listen to checkbox's change event, and the input param should be pre-defined, you can write

checkbox.on('change', toggleHidden.bind(checkbox, display, parameterContainer));

You can get more info from js call() & apply() vs bind()?, mdn-function-bind, mdn-function-call.

Community
  • 1
  • 1
fuyushimoya
  • 9,715
  • 3
  • 27
  • 34