First
First

Reputation: 117

Generate event handlers in a loop

I wrote code like this:

for (i = 0; i < html.length; i++) {
  $p("#panel").append("<div id='flip_sector_"+section+"' style='padding: 5px;text-align: left;background-color: white;'>"+html[i].sector_name+"</div><div id='panel_sectors_"+section+"' style='padding:5px;text-align: left;background-color:white;display: none;'>sectors</div>");
  // $p("#flip_sector_"+html[i].id+"").click(function(){
  // $p("#panel_sectors_"+html[i].id+"").slideToggle("slow");});
  // console.log(html[i].id);
  section++;
  console.log(section);
}

var sectionJs = 0;
// for (i = 0; i < html.length; i++) {
  $p("#flip_sector_" + sectionJs + "").click(function() {
    $p("#panel_sectors_" + sectionJs + "").slideToggle("slow");
    sectionJs++;
  });
  // console.log(html[i].id);
// }

In this code I get from back-end using AJAX JSON. The html variable is JSON data that I parse and put in a div with id $p("#panel") using append().

Then I need for each flip_sector_" + sector dynamically create a slideToggle(). But I cannot create the same ids in

append("<div id='flip_sector_" + section + "' style='padding: 5px;text-align: left;background-color: white;'>" + html[i].sector_name + "</div><div id='panel_sectors_" + section + "' style='padding:5px;text-align: left;background-color:white;display: none;'>sectors</div>")

and in

$p("#flip_sector_"+sectionJs+"").click(function(){
  $p("#panel_sectors_"+sectionJs+"").slideToggle("slow");sectionJs++;

});

Can you help me?

Upvotes: 0

Views: 60

Answers (1)

Rory McCrossan
Rory McCrossan

Reputation: 337560

The manner you're attempting to do this by - incremental id attributes - is an anti pattern.

A much better solution would be to use common classes on all the elements to group them within a single event handler. You can then use DOM traversal to find the related elements. Try this:

var $p = jQuery;
var html = [
  { sector_name: 'foo' }, 
  { sector_name: 'bar' },
  { sector_name: 'fizz' }
];

for (i = 0; i < html.length; i++) {
  $p("#panel").append('<div class="flip_sector">' + html[i].sector_name + '</div><div class="panel_sector">sectors</div>');
}

$p(".flip_sector").click(function() {
  $p(this).next('.panel_sector').slideToggle("slow");
});
.flip_sector {
  padding: 5px;
  text-align: left;
  background-color: white;
}

.panel_sector {
  padding: 5px;
  text-align: left;
  background-color: white;
  display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="panel"></div>

Also note the use of the classes in the CSS to move the styling rules out of the HTML code.

Upvotes: 1

Related Questions