1

I've got a calendar on the sidebar of every page and am attempting to load it with ajax and have partially succeeded.

Currently I can load either the next or the previous month once and only once and then it loads a new page with just the calendar visible. Trying to go back with the calendar loads nothing but on second click returns to the original page. Am stuck and have no idea how to fix this. Used this gist as a starter (everything else I tried didn't work).

Added a screencast where you can see it load correctly the first time but not the second https://www.screenr.com/SqON

My template code looks like this.

Sidebar Template

<article>

    <div id="cal_container">
        {embed="embeds/full_calendar"}
    </div>

</article>

Embedded Template

{exp:channel:calendar channel="events" dynamic="yes" show_future_entries="yes" switch="calendarToday|calendarCell" year="" month=""}

  <table class="calendarBG table" border="0" cellpadding="6" cellspacing="1" summary="My Calendar" id="calendar">


    <tr class="calendarHeader">
        <th>
            <div class="calendarMonthLinks">
              <a href="{previous_path='/embeds/full_calendar'}" id="prev" rel="#cal_container">&lt;&lt;</a>
            </div>
        </th>
        <th colspan="5">
            <center>{date format="%F %Y"}</center>
        </th>
        <th>
            <div class="calendarMonthLinks">
                <a class="calendarMonthLinks" href="{next_path='/embeds/full_calendar'}" id="next" rel="#cal_container">&gt;&gt;</a>
            </div>
        </th>
    </tr>

    {calendar_rows}
        {row_start}<tr>{/row_start}

        {if entries}
            <td class='{switch} calEntry' align='center'>

        {!-- 
        // need to use embed in order to get this to work
        // with structure and page_url variable
        --}             
                {embed="embeds/_calendar_entry"
                    day="{day_number}"
                    entry_id="{entries}{entry_id}{/entries}"
                    }
            </td>
        {/if}

        {if not_entries}
            <td class='{switch}' align='center'>{day_number}</td>
        {/if}
        {if blank}
            <td class='calendarBlank'>{day_number}</td>
        {/if}
        {row_end}</tr>{/row_end}
    {/calendar_rows}
  </table>

{/exp:channel:calendar}

And javascript inside scripts.js

$(function(){ 

  $('#prev, #next').on('click', function(e){ // catch the click, and bind that click-event to the variable "e"
    e.preventDefault(); // stop the event from firing (so user doesn't get forwarded to the actual link)

    var elem = $(this),
      link = elem.attr('href'),
      target = elem.attr('rel');

    $.get(link, function(data){ // do a GET-request
      $('#cal_container').html(data); // put the results in the target-element
    });

  });

});

Changed the javascript to the following (shorter) and it works exactly the same as the first including not going more than one month

$(document).ready(function() {
  $('#prev, #next').on('click', function(e){ // catch the click, and bind that click-event to the variable "e"
    e.preventDefault(); // stop the event from firing (so user doesn't get forwarded to the actual link)

    $('#cal_container').load($(this).attr('href') + ' #calendar');
  });
});
  • any error messages in the firebug console? – erwinheiser Aug 19 '14 at 17:28
  • No errors in the console. – CreateSean Aug 19 '14 at 17:32
  • What if you move the click handler to the wrapping div? $('#cal_container').on('click', '#prev, #next', function(event) { event.preventDefault(); /* Act on the event */ }); – erwinheiser Aug 19 '14 at 20:54
  • Erwin - that worked perfectly. If you make that an answer, I'll mark it accepted. Not sure why it works, but I'm happy. Thank you. – CreateSean Aug 20 '14 at 13:58
2

Move the click handler to the wrapping div.

    $('#cal_container').on('click', '#prev, #next', function(event) {
       event.preventDefault(); /* Act on the event */ 
}); 

Has to do with the original event handler in your code not being passed to the dynamically inserted html. There's a good explanation found here: http://toddmotto.com/attaching-event-handlers-to-dynamically-created-javascript-elements/ and in the jquery docs for the .on method here: http://api.jquery.com/on/

By moving the click handler to an element that's unchanged in your original html (i.e. #cal_container) you can work around it.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.