views:

893

answers:

1

Hello!

I am making a very minimalistic calendar plugin for the website with jQuery. I have not had much expirience with it, so I was following plugin tutorial. I have two <a> links that should change month, but unfortunately they do so only once and then both of them stop working. I suspect I have put events to a wrong place.

Sorry for quite messy code it is just a blueprint yet.

Here is the javascript.

(function($){    
    $.fn.extend({
     jSimpleCalendar : function(currentDate)
     {


      return this.each(
       function()
       {    

        obj = $(this);

        result = renderCalendar(currentDate); 

        obj.html(result);

                                        // Event handlers
        $('#JQSCMonthPrev').click(function ()
        {
         currentDate.setMonth(currentDate.getMonth() - 1);
         result = renderCalendar(currentDate);

         obj.html(result);

        });
                                        $('#JQSCMonthNext').click(function ()
        {
         currentDate.setMonth(currentDate.getMonth() + 1);
         result = renderCalendar(currentDate);

         obj.html(result);

        });

       });



      function renderCalendar(date)
      {
       // Get the calendar
       calendar = createMonthArray(date);

       // Build xhtml
       var result = '<table class="jQSCTable">';    

       result += '<thead><tr><td colspan=4><a href="#" id="JQSCMonthPrev">&lt;</a> <a href="">' + getMonthNames()[date.getMonth()] + '</a> <a href="#" id="JQSCMonthNext">&gt;</a></td>';
       result += '<td colspan=3><a href="#" id="JQSCYearPrev">&lt;</a> <a href="">' + date.getFullYear() + '</a> <a href="#" id="JQSCYearNext" >&gt;</a></td></tr></thead><tbody>';


       for(i=0;i<(calendar.length);i++)
       {
        result += '<tr>';
        for (a=1; a<=7; a++)
        {
         result += '<td>';
         if(calendar[i][a]!='N')
         {
          result += '<a id="JQSCLink' + calendar[i][a] + '">' + calendar[i][a] + '</a>';
         }
         result += '</td>';
        }
        result += '</tr>';
       }
       result += '</tbody></table>'; 

       return result;   

      }; 

      function createMonthArray(date)
      {
       // Get first day of month
       date.setDate(1);

       // Make callendar
       var calendar = new Array();

       // Fill empty shit from previous month
       for(i=0;i<date.getDay()-1;i++)
        calendar.push('N');

       // Get number of days
       var numberOfDays = getNumberOfDaysMonth(date);

       //Fill the rest
       for(i=1;i<numberOfDays+1;i++)
        calendar.push(i);    

       // Get number of end days
       var endDays = calendar.length % 7 - 1;

       //Fill the empty stuff at the end
       for(i=0;i<7-endDays;i++)
        calendar.push('N');   



       //Slice to seven pieces
       var slicedCalendar = new Array();
       var week = 0;
       slicedCalendar[0] = new Array();
       for(i=1;i<calendar.length;i++)
       {
        slicedCalendar[week][i-week*7] = calendar[i-1];
        if (((i%7)==0)&&(i!=0))
        {
         week++;
         slicedCalendar[week] = new Array();
        }
       }
       return slicedCalendar.splice(0, week);

      };  

      function getNumberOfDaysMonth(date)
      {
       var minDays = 28;
       var dateFound = false;   
       var oldMonth = date.getMonth();
       var workDate = new Date(date.getYear(), date.getMonth(), 1);

       while (!dateFound)
       {
        workDate.setDate(minDays+1);    
        var newMonth = workDate.getMonth();//new month date 

        if (newMonth != oldMonth)//if the month has changed
         dateFound = true;
        else
         minDays++;
       }

       return minDays;   

      } 

      // Month names
      function getMonthNames() 
      {
       var month = Array();
       month[0] = 'January';
       month[1] = 'February';
       month[2] = 'March';
       month[3] = 'April';
       month[4] = 'May';
       month[5] = 'June';
       month[6] = 'July';
       month[7] = 'August';
       month[8] = 'September';
       month[9] = 'Octorber';
       month[10] = 'November';
       month[11] = 'December';

       return month;
      }  

     }
    });   
})(jQuery);

Here is html test.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"&gt;
<html xmlns="http://www.w3.org/1999/xhtml"&gt;
    <head>
     <script type="text/javascript" src="js/jquery-1.3.2.min.js"></script>
     <script type="text/javascript" src="js/jSimpleCalendar.js"></script>
     <script type="text/javascript">
        $(document).ready(function(){
         $("#calendar").jSimpleCalendar(new Date());
        });
     </script>
    </head>
    <body>
     <div id="calendar">
     </div>  
    </body>
</html>
+4  A: 

Seems like what's happening is the HTML is being rewritten when you click the first time. When this happens, the click events are no longer bound to the hrefs since the older elements were removed from the DOM.

You could put the click events into it's own function and call the function after rebuilding the calendar or use event delegation. For this, append the click event on the #calendar div and track which element was clicked.

http://www.learningjquery.com/2008/03/working-with-events-part-1

Dhana
If this is the case, could also use the 'live' event: http://docs.jquery.com/Events/live
dalbaeb
Thanks a lot, that's what I thought )
freiksenet