2

I'm experiencing a problem when I attempt to use the .change() event on select lists, using the jQuery .toChecklist plugin.

My page contains a number of select lists, which are changed to CheckLists, using jQuery.

Consider the following Javascript snippet:

for (var i=0;i<5;i++)
{
  var selectListId = 'selectList' + i;

  // Assume this line represents the outputting on a 
  // standard select list

  // Convert to Checklist
  $("#" + selectListId).toChecklist();
  $("#" + selectListId).change
  (
    function ()
    {
      alert("SelectListId: " + selectListId);
    }
  );
}

For each iteration of this loop, I output a multi-select list, convert it to Checklist, and then add the .change() handler.

However, when the page renders (visually, everything is fine), choosing an option from ANY of the lists gives the alert text of "SelectListId: selectList4" (ie. the last list id of the loop). Thus it appears that each invocation of .change() globally replaces the change handler.

Does anyone know how to change the code so that each checklist has its own change handler (so that the first change handler would output "SelectListId: selectList0", etc).

Thanks,

Crollster
  • 2,751
  • 2
  • 23
  • 34

2 Answers2

1

Try pulling the change function out of the loop. I also added a line that adds a class to each list. The new change function references the lists by the class and will know which is actively being changed via this.

for (var i = 0; i < 5; i++) {

    var selectListId = 'selectList' + i;

    $("#" + selectListId).toChecklist();
    $("#" + selectListId).addClass('newChecklist');
}

$('.newChecklist').change(function() {
    alert( $(this).attr('id') );
});
wdm
  • 7,121
  • 1
  • 27
  • 29
  • This does work, and would be a good approach in most cases, so I've marked it as the accepted answer, however the simplicity of my example code snippet in this instance has worked against me, as I'm not able to work outside of the loop (since I don't know how many checklists I have and what their Id's would be, as there would be other controls output as well). :) – Crollster Jun 01 '11 at 01:30
1

So, after a lot of head scratching, I've found a work-around for this issue. While concatenating strings together in the anonymous function behaves in an unexpected manner, quoting the whole line of code and wrapping it in an eval statement produces the required results.

Thus, instead of writing, as above:

$("#" + selectListId).change
(
  function ()
  {
    alert("SelectListId: " + selectListId);
  }
)

You would need to write this instead:

eval('$("#' + selectListId + '").change(function (){alert("SelectListId: ' + selectListId + '");});');

This may not be the best approach, but it works, and for now that's good enough! :-)

Crollster
  • 2,751
  • 2
  • 23
  • 34
  • Be careful when using eval, there are several security and performance issues. http://stackoverflow.com/questions/86513/why-is-using-javascript-eval-function-a-bad-idea – wdm Jun 01 '11 at 02:01