1

I have hit a bit of a brick wall here. The previous developer on my current project decided to construct the entire front facing portion of this app using one behemoth JS file, with almost no html being used for the page structure at all. So essentially all of the content and structure on the app is dynamically generated.

I have learned to live with this 18k+ line JS file, but I have finally hit a bit of a road block. I need to find a specific element among an array of other elements with className .grid_elm and I need to trigger a click event on it.

Current HTML:

<div id="grid">
   <div id="gridMask">
      <div id="mCSB_1"> /*Auto-Generated by a Scrollbar Plugin*/
         <div class="mCSB_conatiner"> /*Auto-Generated by a Scrollbar Plugin*/
            <div class="holder">
               <div class="grid_elm"></div>
               <div class="grid_elm"></div>
               <div class="grid_elm"></div>
               <div class="grid_elm"></div>
            </div>
         </div>
      </div>
   </div>
</div>

Problem:

The #grid is refreshed with new elements whenever the user selects an option from the auto-suggest search box. I need to then loop through each of the .grid_elm elements and find a specific one based on it's child elements, and then trigger a click on that particular .grid_elm - but I have no idea how to do this since there is no specific element to propagate the event from. I can't really subscribe each of the .grid_elm elements to a custom event, and then trigger the custom event when the elements were added to #grid because the trigger would either happen on all of the .grid_elm elements, or none since it likely needs something more specific to trigger against. If I do this:

$("#grid").on("click",'.grid_elm",function(){
   $(".grid_elm").each(function(){
      console.log($(this));
   })
})

I can get at the list of elements because the event is fired from a specific element, but if I try to loop through each of the elements when a custom event is fired, I get nothing:

$("#grid").on("custom",".grid_elm",function(){
   $.each($(".grid_elm"),function(){
      console.log($(this));
   })
})

//"custom" Event is fired after grid refreshes with new content
$(".grid_elm").trigger("custom");

Even if I subscribe and fire the event directly on #grid without any reference to .grid_elm and then try to loop through it's children, I still get nothing. I feel like I am missing something pretty rudimentary about custom event handling.

Ryan McCoy
  • 484
  • 1
  • 7
  • 11

1 Answers1

2

This seems to work ok with this jsfiddle:

http://jsfiddle.net/KEMrX/ It has the following javascript:

$("#grid").on("custom",".grid_elm",function(){
   $.each($(".grid_elm"),function(){
      console.log($(this));
   })
})

//"custom" Event is fired after grid refreshes with new content
$(".grid_elm").trigger("custom");

and the HTML code:

<div id="grid">
   <div id="gridMask">
      <div id="mCSB_1"> 
         <div class="mCSB_conatiner"> 
            <div class="holder">
               <div class="grid_elm"></div>
               <div class="grid_elm"></div>
               <div class="grid_elm"></div>
               <div class="grid_elm"></div>
            </div>
         </div>
      </div>
   </div>
</div>

If you look at the console after you run it, you'll see your .grid_elm elements properly printed out.

Most likely you're having problems with the generated content, and not with the custom event handling. When is the #grid element created? When do you run the code that attaches the event on the #grid element?

Edit: The important part is: the code that attaches the event should happen directly after the code that creates(and appends) the #grid element onto the page. Otherwise, the expression $("#grid") will return an empty array, and the .on() function will NOT run on anything.

Russell Santos
  • 411
  • 2
  • 8
  • I think you might be right here, as it looks like the function I am calling to update the grid with new `.grid_elm` elements is possibly injecting the entire `#grid` again, which would mean that when I subscribe the grid element on page load to the event, the newly inject `#grid` also needs to be subscribed somehow? Should I attach the event listener on an element higher up the DOM tree? Maybe even the body? I will try this and let you know what happens! – Ryan McCoy Jun 30 '13 at 03:48
  • Attaching the event listener on an element higher up the DOM tree *should* work. If that does not work, you may need to re-subscribe the event to the #grid element when it is injected. – Russell Santos Jun 30 '13 at 04:14
  • It turns out that my event subscription is working, even after the new elements are injected into the `#grid` - but when my custom event fires and triggers the callback, apparently those elements are not ready? I got around this by adding a timeout before starting my loop through the elements, but there has to be a more graceful way than that? Seems tacky and I can already see where this could get inconsistent as all hell – Ryan McCoy Jun 30 '13 at 04:56
  • What do you mean when you said the elements are not ready? Usually those timeout fixes work only when AJAX calls are involved. Is this the case? Are the elements only created after an AJAX call? – Russell Santos Jun 30 '13 at 05:50
  • The call is made using node.js, but the information is being drawn from the server yes. sorry I forgot to mention that, I didn't think it was relevant because to be completely honest, the way this app is set up is horribly convoluted and to explain what was happening BEFORE my jquery code was executing would have been too difficult to explain here haha. I am not going to post up my answer because the way I fixed this is too specific to this app's structure, and it hardly can be considered a "fix" in my book. Instead I will accept yours because what you mentioned pointed me towards the problem. – Ryan McCoy Jul 01 '13 at 07:47