SP2010: jQuery not executing when switching between month-week-day Calendar views

Answered SP2010: jQuery not executing when switching between month-week-day Calendar views

  • Dienstag, 20. September 2011 21:48
     
      Enthält Code

    I start out with a Calendar month view of a Task list.  It's on a new Wiki page that I created via Site Actions > new page.

    I have a jQuery script in a CEWP that will do some modifications to the Calendar month display (most notably remove the crazy "12:00 am - 12:00 am" text!).  However, when switching between any of the month-day-week views, the jQuery does not execute.  I assume the $(document).ready does not fire when switching between calendar views.  

    Would anyone know of an event to which I could bind my code such that it will execute when changing between the three calendar views?

    And, just for the heck of it, I tried window.onfocus() but that doesn't fire either when switching between Calendar views. 

    This is a simplified version of the code I am executing. 

    $(document).ready(function() {
       window.setTimeout(doModifyCal, 150);
    });
    function doModifyCal() {
      // alert("entering doModifyCal");
      var CalData = $('div.ms-acal-rootdiv:eq(1)');
      $("div.ms-acal-time", CalData).remove();            // remove all "12:00 am - 12:00 am" displays
    });
    

    note: the setTimeout() pause was a hint from Marc Anderson that addressed an earlier problem I had with the fact that SP2010 now loads Calendars asynch.  So the document is actually ready before the data has been populated.  But a simple pause took care of that.

    Betty


    Betty Stolwyk

Alle Antworten

  • Freitag, 7. Oktober 2011 07:09
     
     
    You could get the ID of those buttons and add in your script that if you click on the button the script fires to hide the fields via the .click event
    Regards, Marijn Somers|| http://www.beyond-it.be || Twitter: http://twitter.com/marijnsomers || http://marijnsomers.blogspot.com
  • Freitag, 7. Oktober 2011 15:05
     
     Beantwortet Enthält Code

    Hi Marijn,

    Actually I went down that road but ended up mostly scrapping that approach because each of those click events would have to include a pause (setTimeout), for the same reason as my above example - one has to now wait for the data to come back separately (and later) than the rest of the page because of the new asynch nature of the calendar rendering (new to SP2010).  Trying to get the right amount of milliseconds proved to be troublesome - the timing could vary so much - if you have too few milliseconds, the code executes before the data arrives; too many - and you see the flash of the old display before the modified display renders.

    So I was referred to another approach suggested by Mike Smith - http://techtrainingnotes.blogspot.com/2010/06/sharepoint-2010-color-coded-calendars.html

    With his approach, you intercept the page rendering at the point when the data is actually coming back - THEN you execute your code. 

    So that ended up taking care of all the view changes under these circumstances:

    - day-week-month changes via Ribbon buttons
    - day-week-month changes via UI hot spots on the calendar
    - previous/next scrolling using left and right arrows on calendar

    However, it did not fire when clicking on the more/collapse links that display when you have more than three items on a day in the month view.  I went back to the click trigger method with a slight pause (setTimeout) for those circumstances, and that seemed to take care of it.  Although I still see the very slightest flash of old display before the new modified display - even after setting milliseconds to 0.  So I tried that event without the pause, but then the data displayed the default way - not with my modifications. So for now I will live with the little flash of old data.

    Anyhow - here is what I ended up with:

    My goal:

    On an SP2010 Calendar style view of a list: 
      -Remove all 12:00 time displays.  They are incorrect.
       -Remove the 12:00 text from tool tip also.
       -Change item links to go to non-modal Edit form instead of default modal Display form 
        (probably no one else will care about this - but it was part of my user's request)

    I intend to accomplish that by: 

    Changing these three HTML markups:

     

    <DIV style="POSITION: absolute; WIDTH: 119px; HEIGHT: 37px; TOP: 77px; LEFT: 760px" class=ms-acal-item title="12:00 am - 12:00 am bls task tres" _index="0,3">
    
    
    <DIV class=ms-acal-sdiv>
      <DIV class=ms-acal-time>12:00 am - 12:00 am </DIV>
      <DIV class=ms-acal-title>
           <A onclick="EditLink2(this,'WPQ2');return false;" href="/{site}/Lists/Task/DispForm.aspx?ID=74">bls task uno</A>
      </DIV>
    
    
    <DIV class=ms-acal-sdiv>12:00 am 
      <A onclick="EditLink2(this,'WPQ2');return false;" href="/{site}/Lists/Task/DispForm.aspx?ID=75">bls task dos</A>
    </DIV>
    
    

     

    To these HTML markups:

     

    <DIV style="POSITION: absolute; WIDTH: 119px; HEIGHT: 37px; TOP: 77px; LEFT: 760px" class=ms-acal-item title="bls task tres" _index="0,3">
    
    
    <DIV class=ms-acal-sdiv> 
      <DIV class=ms-acal-title>
           <A  href="/{site}/Lists/Task/EditForm.aspx
       ?ID=83&Source=https%3A%2F%2F{site}%2FSitePages%2FBettyTest3.aspx">
           bls task uno
      </DIV>
    
    
    <DIV class=ms-acal-sdiv> 
      <A href="/{site}/Lists/Task/DispForm.aspx?ID=75&Source=https%3A%2F%2F{site}%2FSitePages%2FBettyTest3.aspx">bls task dos</A>
    </DIV>
    
    

    Code:

     

     

    // the "populateCalendarEventLinkIntercept" technique came from Mike Smith:
    // http://techtrainingnotes.blogspot.com/2010/06/sharepoint-2010-color-coded-calendars.html
    // this technique handled all calendar view changes (day-week-month; previous/next) 
    // except the "n more Items" and "collapse" links when more than 3 items are on a month day.
    //
    // the setTimeout technique was suggested by Marc Anderson.
    // it handles the more/collapse scenario
    
    // load our function to the delayed load list
    _spBodyOnLoadFunctionNames.push('populateCalendarEventLinkIntercept');
    
    // hook into the existing SharePoint calendar load function
    function populateCalendarEventLinkIntercept()
    {
    
      if (SP.UI.ApplicationPages.CalendarNotify.$4a)                             // 20111006 pre-SP1 - Office 365
      {
        var OldCalendarNotify = SP.UI.ApplicationPages.CalendarNotify.$4a;
        SP.UI.ApplicationPages.CalendarNotify.$4a = function () 
          {
            OldCalendarNotify();
            doModifyCal();
          }
      }
      if (SP.UI.ApplicationPages.CalendarNotify.$4b)                            // SP2010 SP1
      {
        var OldCalendarNotify = SP.UI.ApplicationPages.CalendarNotify.$4b;
        SP.UI.ApplicationPages.CalendarNotify.$4b = function () 
          {
            OldCalendarNotify();
            doModifyCal();
          }
      }
      // future service pack change may go here!
      // if (SP.UI.ApplicationPages.CalendarNotify.???)
    
    }
    
    
    function doModifyCal() {
    
      // if there is a more/collapse control (which happens when there are more than three items on month date)
      // set its click event to execute this doModifyCal function.
      // include a pause to allow for latent data population from separate asynchronous thread
    
      if ($("a.ms-cal-nav").eq(0).length) {
         $("div.ms-acal-ctrlitem").eq(0).click(function() {
              window.setTimeout(doModifyCal, 0);
         });
      } 
    
      // if there is at least one "12:00" display, clean it up   
      
      var y=$('div.ms-acal-rootdiv:eq(1) div[title^="12:00 am"]').filter(":first");
      if(y.length) {
         var urlString = urlencode(location.href);
         var CalData = $('div.ms-acal-rootdiv').eq(1);
         $("div.ms-acal-time", CalData).remove();
         $('div.ms-acal-sdiv', CalData).each(function() {
           if($('div', this).length == 0) {
             str=$(this).html();
             str=str.replace("12:00 am","");
             $(this).html(str);
           };
         });
         $('div[title]', CalData).each(function() {
           str=$(this).attr("title");
           str=str.replace("12:00 am - 12:00 am ","");
           $(this).attr("title",str);
         });
    
         // additionally, change item links to go to non-modal Editform
         // instead of modal Dispform
    
         var Links = $("a", CalData);  
         Links.each(function() {
           str=$(this).attr("href");
           str=str.replace("DispForm","EditForm");
           str=str + '&Source=' + urlString;
           $(this).attr("href",str).removeAttr("onclick");
         });
       }
       
    };
    function urlencode(link) {
      link = encodeURI(link);
      link = link.replace('+', '%2B');
      link = link.replace('%20', '+');
      link = link.replace('*', '%2A');
      link = link.replace('/', '%2F');
      link = link.replace('@', '%40');
      return link;
    }
    
    

     

    PS:  btw, here is a before and after screen shot of a month view

    http://www.flickr.com/photos/17549214@N03/6153683845/


    Betty Stolwyk
  • Freitag, 9. März 2012 16:55
     
     
    I tried to use your script  but i cause me IE java error then hangs my web part? Is there a tweak step need to be done? Btw im using IE8 is this related with my issue.
  • Montag, 12. März 2012 14:07
     
      Enthält Code

    Sorry, I do not know if using IE8 is an issue or not.  Are you on SP2010?    You may need to start simple to figure out the problem.  Start out with a small bit of jQuery code and just display an alert or something like that.  Make sure that works, then add little by little to that.  i.e:

    <!-- you may or may not need this first script tag. It depends on whether your SP pages already pull in jQuery. If

    not, then include this script tag and change path to point to your jQuery library -->

    <script type="text/javascript" language="javascript" src="my_path/jquery-1.6.1.min.js"></script> <script type="text/javascript"> // // A quick script to make sure javascript and jQuery exist, are enabled and working ok. // A successful test of each will result in a popup window. Click the OK button to continue. // alert ("js on."); $(document).ready(function() { alert ('jQuery on.'); }); </script>

    If you need help with getting started with jQuery, check out Marc Anderson's article:http://sharepointmagazine.net/articles/a-jquery-primer-for-sharepoint

    Here is a copy of the final version of my code that I ended up with.  Don't know if this will help you or not.  (By the way, this final version in different than previous scripts in that it no longer has to get rid of the 12:00 time stamps.  This is because I simply created a new calculated field on the Task list  that concatenates the Due Date and Due Time into a single Date/Time field.  Then I used the new Date/Time field in the Calendar view configuration as start/end date. All that done just through the standard browser list management.)

    <script language="javascript" type="text/javascript">
    // Created a new column on xRM Task list that concatenates the 
    // Due Date and Due Time into a single Date/Time field.  
    
    // Use the new Date/Time field in the Calendar view configuration as start/end date
    
    // Use jQuery to:
    
    // - change the monthly calendar time range displays (e.g., 3:30 pm - 3:30 pm) 
    //   such that only a single time displays.  There is no begin and end date/time 
    //   field in the xRM Task list.  Steve will use the Due Date and Due Time to track his activities.  
    // - Make the same change to tooltips. 
    // - link to edit form instead of display form.  Return automatically to calendar
    //   the "populateCalendarEventLinkIntercept" technique came from Mike Smith:
    
    // http://techtrainingnotes.blogspot.com/2010/06/sharepoint-2010-color-coded-calendars.html
    // this technique handled all calendar view changes (day-week-month; previous/next) 
    // except the "n more Items" and "collapse" links when more than 3 items are on a month day.
    //
    // the setTimeout technique was suggested by Marc Anderson.
    // it handles the more/collapse scenario
    
    // load our function to the delayed load list
    // but do not do this if page is in "Edit" mode
    
    // if ($('input[name="MSOSPWebPartManager_DisplayModeName"]').val() == "Browse"){      <-- never hit condition when
    //                                                                                         moved to Activities.aspx
                                                                            
    _spBodyOnLoadFunctionNames.push('populateCalendarEventLinkIntercept');
     
       // hook into the existing SharePoint calendar load function
       function populateCalendarEventLinkIntercept()
       {
       
         if (SP.UI.ApplicationPages.CalendarNotify.$4a)                             // 20111006 pre-SP1 - Office 365
         {
           var OldCalendarNotify = SP.UI.ApplicationPages.CalendarNotify.$4a;
           SP.UI.ApplicationPages.CalendarNotify.$4a = function () 
             {
               OldCalendarNotify();
               doModifyCal();
             }
         }
         if (SP.UI.ApplicationPages.CalendarNotify.$4b)                            // SP2010 SP1
         {
           var OldCalendarNotify = SP.UI.ApplicationPages.CalendarNotify.$4b;
           SP.UI.ApplicationPages.CalendarNotify.$4b = function () 
             {
               OldCalendarNotify();
               doModifyCal();
             }
         }
         // future service pack change may go here!
         // if (SP.UI.ApplicationPages.CalendarNotify.???)
       
       }
    // }
    
    
    function doModifyCal() {
    
       // get text "Previous Month" or "...Week"  or "...Day"
       var dateUnit = $("#AsynchronousViewDefault_CalendarView a[title^='Previous']").filter(":first").attr("title");
    
       // remove "Previous " from text, leaving only "Month", "Week" or "Day"
       dateUnit=dateUnit.substring(dateUnit.indexOf(" ")+1);
    
      // if there is a more/collapse control (which happens when there are more than three items on month date)
      // set its click event to execute this doModifyCal function.
      // include a pause to allow for latent data population from separate asynchronous thread
      if ($("a.ms-cal-nav").eq(0).length) {
         $("div.ms-acal-ctrlitem").eq(0).click(function() {
              window.setTimeout(doModifyCal, 0);
         });
      } 
    
      // if there is at least one non-reformatted time display, clean it up 
      // A dash in the title signifies that this has not yet been reformatted  
      // well - not really. I'll refine this later.  The dash would have to be 
      // within the first 7 characters:  hh:mm - hh:mm
    
      var str="";  
      var y=$('div.ms-acal-rootdiv:eq(1) div[title~="-"]').filter(":first");
      if(y.length) {
         var urlString = urlencode(location.href);
         var CalData = $('div.ms-acal-rootdiv').eq(1);
         $('div[title]', CalData).each(function() {
            str=$(this).attr("title");
            str=str.slice(str.search("-")+2);       // remove begin time from all link tool tips
            $(this).attr("title",str);
         });
    
         if(dateUnit=="Month") {
            //check for and remove begin time from single-item-per-day times
            $("div.ms-acal-time").each(function() {
               str=$(this).text();
               str=str.slice(str.search("-")+2);       
               $(this).text(str);
            });  
         }         
               
    
    
         // additionally, replace the onclick action of each task item's link such that a modal Edit form 
         // will pop up instead of modal Display form.  This involves creating a new function that
         // calls SP.UI.ModalDialog methods made available to SP2010 through the EcmaScript Client Object Model
         // ref - http://msdn.microsoft.com/en-us/library/ff410259.aspx
         //
         // do not include "more/collapse" link
         //
         // For clarification purposes we are going to:
         //
         //   change this:  
         //      <A onclick="EditLink2(this,'WPQ2');return false;" 
         //         href="/Lists/Task/DispForm.aspx?ID=74">task title</A>
         //
         //   to this:
         //      <A onclick="modalEdit("/Lists/Task/EditForm.aspx?ID=74";return(false);"
         //         href="javascript:void();">task title</A>
         //
    
         var Links = $("a:not(.ms-cal-nav)", CalData);    
         Links.each(function() {
           str=$(this).attr("href");
           str=str.replace("DispForm","EditForm");
           $(this).attr("href","javascript:void();").attr("onclick","modalEdit('" + str + "');return(false);");
         });
       }
    }
    
    
    function callBackRefresh(dialogResult, returnValue)  {
      var calDetail2 = $("#AsynchronousViewDefault_CalendarView > div.ms-acal-rootdiv >  table")
                          .filter(":first")
                          .attr("summary");
    
      // $("#Ribbon.Calendar.Calendar.Scope.Day-Large").trigger('click');
    }
    
    
    
    // We are here because someone clicked on a task item link in one of the
    // calendar views.  
    // 
    //
    function modalEdit(page) {
      var options = {
            url: page,
            title: 'Edit Task',
            allowMaximize: false,
            showClose: true,
            dialogReturnValueCallback: callBackRefresh,
            autoSize: true
      };
      SP.UI.ModalDialog.showModalDialog(options);
    }
    
    function urlencode(link) {
      link = encodeURI(link);
      link = link.replace('+', '%2B');
      link = link.replace('%20', '+');
      link = link.replace('*', '%2A');
      link = link.replace('/', '%2F');
      link = link.replace('@', '%40');
      return link;
    }
    
    </script>


    Betty Stolwyk


    • Bearbeitet Betty B Montag, 12. März 2012 17:43
    •  
  • Samstag, 26. Januar 2013 18:36
     
     

    Hello all

    My name is Héctor Calvarro and I'm Microsoft Support Escalation Engineer.

    FYI, I'm afraid that the code proposed in this thread is not supported by Microsoft as you can see in my blog entry

    http://blogs.msdn.com/b/calvarro/archive/2013/01/26/supported-namespaces-javascript-client-object-model-sharepoint-server-2010-amp-2013.aspx

    Thx

    Kind Regards.