4

When I add a new appointment to the calendar, for example "Appointment with dentist", then I get a modal dialog where I fill in all the details. This is good. The appointment is then visible in the calendar.

However, when I click on the appointment, instead of opening it in a modal dialog, it just opens in a new page.

How do I configure the calendar so that it opens the appointment/calendar item in a modal dialog?
I already set the option for modal dialogs to yes in the advanced settings of the calendar, but this only seems to work when I make a new appointment. I really want to be able to actually show appointments in a modal dialog.

7 Answers 7

5

Old answer:
I found it! This code does the trick:

function openDialog(pUrl) { 
  var options = {
      title : "Kalender",
      width : 600,
      height : 400,
      url : pUrl 
  };

  SP.SOD.execute('sp.ui.dialog.js', 'SP.UI.ModalDialog.showModalDialog', options);
}

$('.ms-acal-month').ready(function () { 
   setTimeout(function() {
       $('a[href*="DispForm.aspx"]').each(function() {
           $(this).attr('onclick', 'openDialog("' +  $(this).attr('href') + '")');
           $(this).attr('href','javascript:void(0)');
       });
   }, 1000);
});

It is slightly based on a post I found here, but I edited it because in the original post it opened the dialog twice. So instead of doing so, I added a "javascript:void(0)" to the calendar item.

Thanks anyway for the help though!

New answer:
The old answer only showed a modal dialog when there were no more than three items. As soon as you have 4 items or more, you get a link at the bottom of the day saying "1 extra item". When you click on that link, the code no longer works and all events once again open in a new page. To prevent this, I have re-written the code.

This code allows events/calendar items to show in a modal dialog instead of on a new window. Comments are in the code.

// When called, this function opens the dialog.
function openDialog(pUrl) { 
var options = {
    width : 600,
    height : 400,
    url : pUrl };

    SP.SOD.execute('sp.ui.dialog.js', 'SP.UI.ModalDialog.showModalDialog', options);
}

// When the class "ms-acal-month" is loaded, add an onclick 
// attribute to all the links ending with "DispForm.aspx" so
// that the calendar items will open in a dialog instead of
// on a new page.
$('.ms-acal-month').ready(function () { 
    setTimeout(function modal() {
        $('a[href*="DispForm.aspx"]').each(function() {
            $(this).attr('onclick', 'openDialog("' +  $(this).attr('href') + '")');
            $(this).attr('href','javascript:void(0)'); 
        });
    }, 500);
});

// This function adds an onclick attribute to the class "ms-cal-nav"
// (the a tag that shows/hides extra items), code is needed when
// there are more than three calendar items on a day. 
$('.ms-acal-month').ready( function() {
    setTimeout(function() {
        $('a.ms-cal-nav').attr('onclick', 'clickMe()');
    }, 500);
});

// This function is called when the onclick attribute has been
// triggered. It needs to add the onclick attribute again,
// since SP automatically removes this attribute as soon as
// the function was triggered. 
function clickMe() {
    setTimeout(function() {
        $('a.ms-cal-nav').attr('onclick', 'clickMe()');
        $('a[href*="DispForm.aspx"]').each(function() {
            $(this).attr('onclick', 'openDialog("' +  $(this).attr('href') + '")');
            $(this).attr('href','javascript:void(0)');
        });
    }, 500);
}

If you put this code in a JS file (example: calendar.js", located in "Style Library/Styles"), then all you need to do is put a script editor web part on the bottom of the page on which you have a calendar, and add the following code:

<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.9.2/jquery-ui.min.js" type="text/javascript"> </script>
<script src="~sitecollection/Style%20Library/Scripts/calendar.js" type="text/javascript"></script>

This answer can also be found on my blog. I hope I was of any help for others who also wanted a solution to this!

6
  • Does this work in Share Point 2013?
    – user22206
    Jan 24, 2014 at 13:31
  • It works in SharePoint 2013 yes, please refer to the blog in the link at the bottom of the answer for the latest update on how to do this in SP2013.
    – Magali
    Jan 28, 2014 at 10:18
  • Somehow it's working only in IE for me? Chrome and Firefox still going to a new window? :P
    – Tenttu
    Sep 10, 2014 at 11:27
  • And if I change to the next month, modals won't work even in IE anymore (I used your new code). :/
    – Tenttu
    Sep 10, 2014 at 12:04
  • I don't know why it does not work with you, but it works fine with me in IE, Chrome and Firefox. :s
    – Magali
    Sep 16, 2014 at 8:40
3

I was messing about with this today and used a different approach (no jQuery required).

I wanted the dialog to open straight into edit mode, as well as refresh the view once the item had been edited and the dialog closed. Rather than attach an eventhandler to the click events, I overwrote the EditLink2 function that normally opens the calendar events. Tested only with SP2013.

Here's the script that can be used

    <script language="javascript">

//saving a reference of the existing function
var EditLink2_Old = EditLink2;

//Overwriting the existing EditLink2 function
EditLink2 = function(el, ctx){

    //check our context is a calendar
    var calContainer = SP.UI.ApplicationPages.CalendarInstanceRepository.lookupInstance(ctx);
    if(calContainer && typeof(calContainer.refreshItems)=="function"){

        //I wanted to go directly to the edit form instead of the view form
        var url = el.href.replace("DispForm", "EditForm");

        var options = {url: url,
                        title:"Edit Event",
                        dialogReturnValueCallback: function(res, args){
                            //if the item was saved
                            if(res==1){
                                    calContainer.refreshItems();
                            }
                        }   
                    };

        //show the edit dialog
        SP.SOD.execute("sp.ui.dialog.js", "SP.UI.ModalDialog.showModalDialog", options);
    }else{
        //Business as usual
        EditLink2_Old(el, ctx);
    }
    return false;
}

</script>
2
  • Very interesting, I will try it when I can. Thanks!
    – Magali
    Jun 18, 2014 at 12:07
  • 3
    This is the best answer, without a doubt.
    – CeeMoney
    Aug 31, 2016 at 5:18
2

add a content editor webpart to the page, copy past code into it:

// load our function to the delayed load list
_spBodyOnLoadFunctionNames.push('calendarEventLinkIntercept');


 // hook into the existing SharePoint calendar load function.
 function calendarEventLinkIntercept()
 {
  if (SP.UI.ApplicationPages.CalendarNotify.$4a)
   {
   var OldCalendarNotify = SP.UI.ApplicationPages.CalendarNotify.$4a;
   SP.UI.ApplicationPages.CalendarNotify.$4a = function () 
   {
   OldCalendarNotify();
   bindEventClickHandler();
   }
   }
  if (SP.UI.ApplicationPages.CalendarNotify.$4b)
   {
   var OldCalendarNotify = SP.UI.ApplicationPages.CalendarNotify.$4b;
   SP.UI.ApplicationPages.CalendarNotify.$4b = function () 
   {
   OldCalendarNotify();
   bindEventClickHandler();


   } 
  }
 // future service pack change may go here!
 // if (SP.UI.ApplicationPages.CalendarNotify.???)
 }


 function bindEventClickHandler() {
  $('.ms-acal-rootdiv a').click(function(){EditLink2(this,'WPQ2');return false;});
 }

now it will display the items within a modal dialog rath than a new page!

if you have many calendars over many pages/ sites than you need to add code to feature, when you activate feature it needs to be scoped to web and it will add code to that page that the feature is activated on resulting in the same output.....so where ever you have a calandar than you want to display items in modal you just activate feature ;)

code was takem from:

http://mahedevelopment.blogspot.co.uk/2012/04/open-sharepoint-calendar-overlay-events.html

2
  • Could it be that this code is for SP2010? I can't get it to work in SP2013. It only runs up to the part where it says var OldCalendarNotify = SP.UI.ApplicationPages.CalendarNotify.$4a;
    – Magali
    Nov 14, 2013 at 14:12
  • This code is for SP2010, it doesn't work in SP2013. However, I found a solution to my question. I'll post the answer below.
    – Magali
    Nov 19, 2013 at 10:17
2

The code works, however if you are using overlays, the newpage still opens (empty) in addition to the dialog also opening.

A solution is to add $(this).removeAttr("target"); to the setTimeout function after $(this).attr('href','javascript:void(0)');

1

You could use this script to show all pages (display, edit, add) of the calender in a dialog. This also works with the buttons in the ribbon.

// wait until "core.js" is loaded, to override it's function
SP.SOD.executeOrDelayUntilScriptLoaded(function ()
{
    var _useDialogsForFormsWithCtx = window.UseDialogsForFormsWithCtx;
    window.UseDialogsForFormsWithCtx = function (ctx)
    {
        // is context from a calendar list?
        if (ctx != null && ctx.listTemplate == "106")
            return true;
        else
            return _useDialogsForFormsWithCtx(ctx);
    }
}, "core.js");

You're replacing the function UseDialogsForFormsWithCtx that is reponsible to evaluate whether a dialog is needed or not. If the passed in rendering context is from a calendar, then make sure a dialog is displayed. Otherwise, we let the original function decide what to do.

Reference click here

0

Thank You Magali!

jQuery ready could not fire in time, also timeout in 500ms is not applicable if You have many calendar overlays. I used hook from Munir Husseini's blog: https://mhusseini.wordpress.com/2012/05/18/handle-clicks-on-calendar-items-in-sharepoint-2010-with-javascript/

and modified code from first post. It runs multiple times but handles all overlays and does not depend on timeouts:

"use strict";

if (!window.console) window.console = {};
if (!window.console.log) window.console.log = function () { };

// modify Calendar markup to open items in dialog
function setCalendarItemsToOpenInDialog() {
    try {
            var time = new Date();
            console.log(time.getSeconds() + ":" + time.getMilliseconds() + " Modifying Calendar Links..");

            jQuery('a[href*="DispForm.aspx"]').each(function () {
                jQuery(this).attr('onclick', 'openDialog("' + jQuery(this).attr('href') + '")');
                jQuery(this).attr('href', 'javascript:void(0)');
                jQuery(this).removeAttr("target");
            });

    } catch (e) {
        console.log("Exception in setCalendarItemsToOpenInDialog: " + e.name + ", " + e.message);
    }
}

function myCalendarHook() {
    try {
        //  save the original onItemsSucceed function
        var _onItemsSucceed = SP.UI.ApplicationPages.CalendarStateHandler.prototype.onItemsSucceed;

        // override a function that is called whenever calendar items are loaded (onItemsSucceed)
        SP.UI.ApplicationPages.CalendarStateHandler.prototype.onItemsSucceed = function($p0, $p1) {
            // call the original onItemsSucceed to make sure that all calendar functionality is as it used to be
            _onItemsSucceed.call(this, $p0, $p1);

            // modify Calendar links
            setCalendarItemsToOpenInDialog();

            // For more than 3 items per day there is 'Show n more items' link.
            // This link rewrites all modified links when clicked, so we need to wait a little and call our function again:
            jQuery('a.ms-cal-nav').on('click', function() {
                setTimeout(function() {
                    setCalendarItemsToOpenInDialog();
                }, 500);
            });
        };
    } catch (e) {
        console.log("Exception in myCalendarHook: " + e.name + ", " + e.message);
    }
}

// When called, this function opens the dialog.
function openDialog(pUrl) {
    var options = {
        autoSize: true,
        url: pUrl
    };
    SP.SOD.execute('sp.ui.dialog.js', 'SP.UI.ModalDialog.showModalDialog', options);
}

ExecuteOrDelayUntilScriptLoaded(function () {
    myCalendarHook();
}, "SP.UI.ApplicationPages.Calendar.js");
0

Add this script in a script editor webpart on your Calendar view .aspx page:

 <script type="text/javascript">
function openDialogBox(Url) 
{    
var ModalDialogOptions = { url:Url, width: 600, height: 500, showClose: true, allowMaximize: true};
SP.SOD.execute('sp.ui.dialog.js', 'SP.UI.ModalDialog.showModalDialog', ModalDialogOptions);
}
$(document).ready(function() {
$('#contentBox').on("click", 'a[href*="DispForm.aspx"]', function(e) {
    e.preventDefault();
    openDialogBox($(this).attr("href"));
    return false;
});
});
</script>

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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