2

I am building a webpage having infinite scroll using waypoints.js with backend as Django.The problem is, my jquery and ajax functions are not working on newly generated content while they are working with content on first page. **EDIT:-**I am updating my code so that it will be easier to undertsand my question.

<div class="infinite-container">
  {%if result %}
  {% for c in result %}
  <div class="infinite-item">
    <img class="likebutton" value="{{c.id}}" id="{{c.id}}" src="{%static "/images/icons/renameheart.png" %}" />
    <div class="LikeCount" id="LikeCount{{c.id}}">{{c.totallikes}}{%if c.totallikes|add:0 == 1%} Like{% elif c.totallikes|add:0 == 0  %} Like {% else %} Likes{% endif %}</div>
  </div>
   {% endfor %}
  {% if result.has_next %}<a class="infinite-more-link" href="?page={{ result.next_page_number }}"></a><div class="loading">loading...</div>{% endif %}
    {% endif %}

</div>
 <script type="text/javascript">
var infinite = new Waypoint.Infinite({
  element: $('.infinite-container')[0],
  onBeforePageLoad: function () {
    $('.loading').show();
  },
  onAfterPageLoad: function ($items) {
    $('.loading').hide();
  }
});

 $(document).ready(function(){
    $('.likebutton').click(function(){
        var id=$(this).attr('value');
        var csrftoken = $("[name=csrfmiddlewaretoken]").val();
        var datat={'id':id};
        $.ajax({
            type:"POST",
            url:"/like/",
            data:datat,
            headers:{
                "X-CSRFToken": csrftoken
            },
            success:function(data){
                if (data.condition==="Liked"){
                    $('#'+id).attr("src","/static/images/icons/renameheart.png");
                }
                if (data.condition==="Unliked"){
                    $('#'+id).attr("src","/static/images/icons/heart.png");
                }
                var likecon=$('#LikeCount'+id);
                likecon.empty();
                if (data.likes > "1"){
                     likecon.text(data.likes+" Likes");
                }else{
                     likecon.text(data.likes+" Like");
                }
            }
        });
    });


});

Now suppose if every page contains 5 entries, then my jquery and ajax functions are working on first 5 entries only.

Gagan
  • 367
  • 1
  • 4
  • 18
  • 1
    Have you tried adding the event listeners to the newly created entries? – p14z Mar 20 '19 at 15:51
  • @Pedro yes, actually my event listeners get rendered along with entries as they are distinguishable by their id which inturn depends on id of that content in database – Gagan Mar 20 '19 at 15:57
  • http://imakewebthings.com/waypoints/api/refresh-all/ states that if changes are made to the DOM, you need to take manual action? – James Addison Mar 20 '19 at 16:14
  • where is the ajax call? xD – Sigdev Mar 20 '19 at 16:22
  • Not sure what you mean @Gagan on your answer to @Pedro. If your jquery has for example a function `$('.some-class').on('click', function(){...})` this code will only run once when your page is loaded. Adding more '.some-class' elements to the DOM will not attach the 'click' event listener by itself. you need to add the event listeners manually after waypoint loaded the new items. Where's the code where you add the event listeners? – dirkgroten Mar 20 '19 at 16:23
  • So in `onAfterPageLoad` you should attach your events to each item in `$items`. – dirkgroten Mar 20 '19 at 16:28
  • @dirkgroten you are right.My all functions are of the type you mentioned in your comments. Can you please explain how can i manually attach to new items – Gagan Mar 20 '19 at 16:28
  • I don't know exactly what you are returning, but keeping the above example, something like `$items.find('.some-class').on('click', function() {...})` would attach a click even to '.some-class' divs inside each item. You'll want to define the function() separately so as to not repeat the same code twice. Easiest is to set a breakpoint in your browser inside `onAfterPageLoad` and use the console to inspect `$items` to understand how to do it correctly. – dirkgroten Mar 20 '19 at 16:32

1 Answers1

2

This is exactly what onAfterPageLoad is for, to make sure any javascript you run on the elements that were in the original page you can also run on the newly added elements:

var performClickEvent = function(event) {
    ...
}

$(document).ready(function(){
     $('.likebutton').on('click', performClickEvent)
}

onAfterPageLoad: function($items) {
    $('.loading').hide();
    $items.each(function() {
        $(this).find('.likebutton').on('click', performClickEvent);
    }
}

where performClickEvent is the function you also attach as click handler to your $('.likebutton') divs on document ready.

dirkgroten
  • 20,112
  • 2
  • 29
  • 42
  • set a breakpoint on the line $(this).find... to see inspect $(this) and $items. I changed it to use `each` so you can set a breakpoint. Also check for any js errors in the console. – dirkgroten Mar 20 '19 at 17:08
  • Nothing appears on console which means that this function is not accessed by .likebutton – Gagan Mar 20 '19 at 17:27
  • Now it is rendering items repeating two times.Out of which , on first element function is accessible while on second it's not. – Gagan Mar 20 '19 at 17:32
  • but $('.loading').hide() works, so if you set a breakpoint there, at least you'll be able to see what's in $items. As I said, I'm not sure how $items is structured so you might have to access the buttons differently. – dirkgroten Mar 20 '19 at 17:34
  • Sorry,it's my fault.I wrote waypoint function two times.Now it's working as expected.Thanks a lot – Gagan Mar 20 '19 at 17:36