0

Have tried looking around, and am getting stuck with one of my dynamic triggers.

I have checked other thread related to this, but seem to have some other code errors that might be causing the suggested .on method to fail.

The code aims to hide/show 2 separate - there are some initial pre-rendered ones, and some loaded dynamically after.

The pre-rendered are fine, the dynamic ones fail.

The Jquery:

   $("div .flipper_link").on("click", function () {

             $(this).parent().find(".contain_content").toggle();
             $(this).parent().find(".card-tags").toggle();

        });

And the dynamically created code:

 <div class="callout_surround">
                        <div class="callout ct_shop">
                            <div class='header-global header-shop'>Shop</div>
                            <div class="flipper_link header-shop"><i class="fi-loop"></i></div>


                            <div class='contain_content' uid="74" data-popup-open="popup-1">
                                <img src='images/someimage.jpg' class='img_cont'/>

                                <div class='tile-text-cont'>

                                    <div class='tile-desc'>
                                        Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut non scelerisque

                                    </div>
                                </div>
                            </div>
                            <div class="card-tags">Some tags etc</div>

                        </div>

                    </div>

I'm fairly new to jQuery, so apologize if I'm using the wrong methods!

Matt Laws
  • 23
  • 6
  • 1
    It's not obvious when you're new to jquery, have a read here: http://stackoverflow.com/questions/203198/event-binding-on-dynamically-created-elements – freedomn-m Mar 20 '17 at 12:10
  • Essentially, when you wire up an event, it only applies to the elements that exist at the time - so if you add more elements, they won't have the event. – freedomn-m Mar 20 '17 at 12:10
  • Possible duplicate of [Event binding on dynamically created elements?](http://stackoverflow.com/questions/203198/event-binding-on-dynamically-created-elements) – freedomn-m Mar 20 '17 at 12:10
  • Try use `$(document).on("click",".flipper_link", function()` – Carsten Løvbo Andersen Mar 20 '17 at 12:12
  • 1
    Even assuming you get this to work, why are you binding click events to div elements? How would a user who can't use a mouse use your page? You should use anchor elements so that keyboard-only users can tab to them and "click" them with the keyboard. – nnnnnn Mar 20 '17 at 12:57

3 Answers3

0

For dynamic HTML use jquery on() method like:

$(document).on("click",".flipper_link", function(){
    // do some thing here
});
Mayank Pandeyz
  • 23,243
  • 3
  • 29
  • 52
0

The selector you are attaching the on click event to can not be dynamic. If you remove that selector and then add it again, this removes the on click event, or any jQuery event.

You have to attach the event to a selector that is there to begin with, and is always there. You can't use one that is dynamically added or it removed at a later time.

Thankfully jQuery's on() method gives us the opportunity to specify a second selector to narrow it down and achieve what you are trying to achieve. Previously live() was used to achieve this, but the new way is faster. If you're using an older version of jQuery, you may need to use live(). Let me know what your version is if this doesn't work.

It is not recommended to use the onclick event within the markup, for many reasons that I will not go in to on here. You can look at stackoverflow.com/questions/12627443/jquery-click-vs-onclick, but .click is deprecated. It is also not recommended to attach the event to the main document, with $(document).on(), for example, as this will fire every time someone clicks on anything on the page.

You'll be placing the event on an initial selector that is not dynamic, then reference your dynamic selector in the second parameter, like so:

$("#non-dynamic").on("click", ".flipper_link", function () {

You will have to add more code to yours, or reference a non-dynamic selector higher up in your markup. Here's a working snippet:

$(document).ready(function() {
    $("#non-dynamic").on("click", ".flipper_link", function () {
      $(this).parent().find(".contain_content").toggle();
      $(this).parent().find(".card-tags").toggle();
    });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="non-dynamic">
<div class="callout_surround">
  <div class="callout ct_shop">
     <div class='header-global header-shop'>Shop</div>
         <a class="flipper_link header-shop">
            <i class="fi-loop">Test Link</i>
         </a>
          <div class='contain_content' uid="74" data-popup-open="popup-1">
             <img src='images/someimage.jpg' class='img_cont'/>
             
             <div class='tile-text-cont'>
                <div class='tile-desc'>
                                        Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut non scelerisque

               </div>
           </div>
        </div>
        <div class="card-tags">Some tags etc</div>
    </div>
</div>
</div>
Community
  • 1
  • 1
adprocas
  • 1,827
  • 1
  • 13
  • 28
  • When that content is dynamic, it fails though – Matt Laws Mar 20 '17 at 12:22
  • Oh, ok. How are you changing it? What exactly is dynamic? – adprocas Mar 20 '17 at 12:23
  • Try that - as long as .callout_surround isn't changing, it should work. – adprocas Mar 20 '17 at 12:24
  • All the data from/including 'callout_surround' divs are appended via a .append(data); method. Anything pre-rendered will work fine, but then break with dynamically added content (hope that's clear enough!) – Matt Laws Mar 20 '17 at 12:28
  • Yes, it breaks for the reasons I stated. You should include that other part of your code, as it is what is causing the problem. I'll edit this to give you a better example of how to do it. – adprocas Mar 20 '17 at 12:30
  • It's because the event observers are removed from dynamic code, or aren't added to the dynamic stuff that is being added with append. So jQuery doesn't know about them after they are dynamically added. To get around this, you need to first add the event observer to a non-dynamic piece. I hope that makes sense. – adprocas Mar 20 '17 at 12:33
  • Just an FYI - I've updated this to be more complete. It is using the recommended way of doing this. The other two answers use non-recommended ways. You can choose what you would like, but my answer is the safest and follows recommendations and best practices for jQuery use. It will also be easier to maintain down the road. – adprocas Mar 21 '17 at 13:17
-1

An easy way to fix it is change your javascript to be:

<script>
function flipValues(div) {
     $(div).parent().find(".contain_content").toggle();
     $(div).parent().find(".card-tags").toggle();
}
</script>

Change your dynamically generated html to have an onclick on the div to flip.

Example:

    <div class="flipper_link header-shop"  onclick="flipValues(this);">
           <i class="fi-loop"></i>
   </div>
Avitus
  • 14,677
  • 6
  • 41
  • 53