6

Is it possible to disable drag and drop event in SharePoint calendar? I looked all available properties in SPCalendar control but I didn't find any.

Rendered Javascript has a parameter in factory class which control this behavior but not sure if I can access it through code behind or Javascript:

SP.UI.ApplicationPages.CalendarContainerFactory.create(document.getElementById('ctl00_m_g_67e2a6e7_070b_4dbd_8082_cdb772ec594e_ctl00_ctl01_ctl00_ctl00'),{ctxId:'WPQ1',dataSources:[{id:'00000000-0000-0000-0000-000000000000',name:'',color:'',formUrl:'\u002fLists\u002fCorpCalendar\u002fDispForm.aspx',primary:true, **disableDrag:true**}],userInfo:{current:{id:'27',loginName:'ACME\\Test',displayName:'Test',email:'[email protected]'}},enablePeople:false,enableResource:false,usePostBack:false,canUserCreateItem:true,sharedPickerClientId:null,reservationContentTypeId:'0x0102004F51EFDEA49C49668EF9C6744C8CF87D',aM12String:'12:00 am',serviceUrl:'\u002f_layouts\u002fCalendarService.ashx'},'day','',[{"Options":41,"Table":null,"DatePicker":null,"Dates":["12/12/2011","12/13/2011"],"RangeJDay":[150094,150094],"Navs":null,"Items":{"Data":[[0,1,2,150094,150094,3,3,4,5,12,0,30,0,0,0,2,6]],"Strings":["1158","Test Meeting","","12/12/2011","12:00 pm","12:30 pm","0x7fffffffffffffff"]}}]); 

Thanks in advance.

2 Answers 2

9

I've written a small console app to test my solution and it seems that all work fine.
Here is a code:

var site = new SPSite("http://localhost/sites/test/");
var web = site.OpenWeb();
var wpManager = web.GetLimitedWebPartManager("Lists/cal/calendar.aspx", PersonalizationScope.Shared);
var contentEditor = new ContentEditorWebPart();
var xmlDoc = new XmlDocument();
var xmlElement = xmlDoc.CreateElement("HtmlContent");
xmlElement.InnerText = @"<script type='text/javascript'> 
      ExecuteOrDelayUntilScriptLoaded(fixupDrag, 'SP.UI.ApplicationPages.Calendar.js');
        function fixupDrag(){
            SP.UI.ApplicationPages.CalendarContainerFactory.create = function(elem, cctx, viewType, date, startupData) {ULSSPg:;
            if (!elem) {
                return;
            }

            if(cctx.dataSources && cctx.dataSources instanceof Array && cctx.dataSources.length > 0){
                for(var i = 0; i < cctx.dataSources.length; i++){
                    cctx.dataSources[i].disableDrag = true;
                }
            }

            var $v_0 = SP.UI.ApplicationPages.ElementUtility.$3f(cctx.ctxId);
            if (!$v_0) {
                return;
            }
            $v_0.style.position = 'relative';
            if (Sys.Browser.agent === Sys.Browser.InternetExplorer && (navigator.userAgent).toLowerCase().indexOf('trident/4.0') !== -1) {
                var $v_2 = ($v_0.style.width === '100%') ? null : $v_0.style.width;
                var $v_3 = ($v_0.style.height === '100%') ? null : $v_0.style.height;
                if (!SP.UI.ApplicationPages.SU.$5($v_2) || !SP.UI.ApplicationPages.SU.$5($v_3)) {
                    $v_0.style.display = 'none';
                    $v_0.style.overflow = 'auto';
                    $v_0.style.display = 'block';
                }
            }
            else {
                $v_0.style.display = 'none';
                $v_0.style.overflow = 'auto';
                $v_0.style.display = 'block';
            }
            var $v_1 = new SP.UI.ApplicationPages.CalendarContainer(elem);
            $v_1.$4h(cctx);
            SP.UI.ApplicationPages.CalendarInstanceRepository.registerInstance(cctx.ctxId, $v_1);
            $v_1.$Av(viewType, date, (SP.UI.ApplicationPages.SU.$3(startupData)) ? null : startupData[0]);
        }
        }
    </script>";
contentEditor.Content = xmlElement;
wpManager.AddWebPart(contentEditor, "Main", 0);

As you can see the main idea is to replace standard sharepoint method SP.UI.ApplicationPages.CalendarContainerFactory.create with custom, a little bit modified. I just copy from SP.UI.ApplicationPages.Calendar.debug.js this method and insert this lines:

if(cctx.dataSources && cctx.dataSources instanceof Array && cctx.dataSources.length > 0){
   for(var i = 0; i < cctx.dataSources.length; i++){
     cctx.dataSources[i].disableDrag = true;
   }
}  

ExecuteOrDelayUntilScriptLoaded(fixupDrag, 'SP.UI.ApplicationPages.Calendar.js'); needed to ensure that calendar script already has loaded. This is a tricky solution I think, because this code must run right after SP.UI.ApplicationPages.Calendar.js has been loaded, but before call to SP.UI.ApplicationPages.CalendarContainerFactory.create. I've tested it under firefox and ie and it works for me.

UPDATE
After some thoughts I decided that above script is not very good. Imagine if Microsoft in any cumulative update will change source code of method SP.UI.ApplicationPages.CalendarContainerFactory.create, this changes will be lost if we are using above script. So, more preferable way is to save reference to previous calendar create function, then replace it with custom and in custom make call of function, saved on previous step:

<script type='text/javascript'> 
  ExecuteOrDelayUntilScriptLoaded(fixupDrag, 'SP.UI.ApplicationPages.Calendar.js');
    function fixupDrag(){
        var calendarCreate = SP.UI.ApplicationPages.CalendarContainerFactory.create;
        SP.UI.ApplicationPages.CalendarContainerFactory.create = function(elem, cctx, viewType, date, startupData) {
            if(cctx.dataSources && cctx.dataSources instanceof Array && cctx.dataSources.length > 0){
                for(var i = 0; i < cctx.dataSources.length; i++){
                    cctx.dataSources[i].disableDrag = true;
                }
            }
            calendarCreate(elem, cctx, viewType, date, startupData);
        }
    }
</script>   

Hope this helps.

2
  • Kai, Your updated suggestion make more sense. Dec 19, 2011 at 17:51
  • I tried your script and its working perfectly. Appreciate your help. Dec 19, 2011 at 17:56
0

Another way is override the SP.UI.ApplicationPages.CalendarStateHandler.prototype.onItemsSucceed function and iterate through the $p0 array and set $N.disableDrag to false. This seems to work for me:

var _onItemsSucceed = SP.UI.ApplicationPages.CalendarStateHandler.prototype.onItemsSucceed;
SP.UI.ApplicationPages.CalendarStateHandler.prototype.onItemsSucceed = function($p0, $p1)
{
    // run the original one
    _onItemsSucceed.call(this, $p0, $p1);

    // go through them
    for(var i = 0, numEvents = $p0.length; i < numEvents; ++i)
    {
        $p0[i].$N.disableDrag = true;
    }
};

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.