Monday, July 27, 2015

Show all user's schedule in calendar view by default without having to select people/group in selector (sharepoint 2013)

The Problem

One feature of SharePoint is to create a calendar and make it a group calendar. This allows the user to see the schedule of list of people at the same time on the same view as per the image below.
image

To configure the Calendar as a group Calendar you need to edit the List settings and then click on “List name, description and navigation” and finally select the radio button as per the image below.

image

So all this is SharePoint out of the box functionality. So where is the problem?

The problem is that to get the view of all calendar of your work group every time you open the calendar view you need to add each one of them individually! 

And there is no any way to persist this information so that it would open the calendar view automatically with the people added as per the list you see in the first image. 

The Solution

Here is a javascript workaround, which takes current site, get Calendar List ID, enumerates through List Roles and select groups contains "Member" word. You can find this place a replace the group name

1. Place script editor web part on page with calendar view
2. Copy and insert code snippet 


<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script type="text/javascript" unselectable="on">
    //Change to name of your SharePoint group with the team members in it
var groupName = "";
//Change to the id of your SharePoint group with the team members in it
var groupID = "";

    $(document).ready(function () {
        SP.SOD.executeFunc('sp.js', 'SP.ClientContext', execOperation);
    });

    function execOperation() {
        var currentContext = new SP.ClientContext.get_current();
        this.oWeb = currentContext.get_web();
        currentUser = this.oWeb.get_currentUser();
        var allGroups = currentUser.get_groups(); 
        var oList = currentContext.get_web().get_lists().getById(_spPageContextInfo.pageListId)
        currentContext.load(oList);
        console.log(oList);
        var listRoleAssignments = oList.get_roleAssignments()
        currentContext.load(listRoleAssignments,'Include(Member,RoleDefinitionBindings)');
        currentContext.load(allGroups);
currentContext.executeQueryAsync(OnSuccess,OnFailure);

function OnSuccess(sender, args) {
    //enumerate results
    var listPermsEnumerator =  listRoleAssignments.getEnumerator();
    while (listPermsEnumerator.moveNext()) {
        var rAssignment = listPermsEnumerator.get_current();
        var member = rAssignment.get_member();
        var grName = member.get_title();
        if (grName.indexOf("Members") >= 0) {
            groupName = grName;
            groupID = member.get_id();
        
            break;
        }
    } 
}

function OnFailure(sender, args) {
}   
}
function _firstTime() {
    //need to select the calendar tab so we can override the onlick method on some of the buttons.
    SelectRibbonTab('Ribbon.Calendar.Calendar', true);
    //give the ribbon time to load
    setTimeout('_doWireUp();',1000);
}

function _doWireUp()
{
    //change the onclick event for the group buttons to make sure it reloads our default group
    var weekElem = document.getElementById('Ribbon.Calendar.Calendar.Scope.WeekGroup-Large');
    if(weekElem)
        weekElem.onclick = function() {setTimeout('_setDefaultResources();',1000);return false;};

    var dayElem = document.getElementById('Ribbon.Calendar.Calendar.Scope.DayGroup-Large');

    if(dayElem)
        dayElem.onclick = function() {setTimeout('_setDefaultResources();',1000);return false;};

    _setDefaultResources();
}


function _setDefaultResources() {
    //this is where the magic happens
    var el = jQuery('.ms-acal-rootdiv');
    var tmpstr = "\u003cEntities Append=\u0022True\u0022 Error=\u0022\u0022 DoEncodeErrorMessage=\u0022True\u0022 Separator=\u0022;\u0022 MaxHeight=\u00223\u0022\u003e\u003cEntity Key=\u0022MyGroup\u0022 DisplayText=\u0022MyGroup\u0022 IsResolved=\u0022True\u0022 Description=\u0022MyGroup\u0022\u003e\u003cExtraData\u003e\u003cArrayOfDictionaryEntry xmlns:xsi=\u0022http:\u002f\u002fwww.w3.org\u002f2001\u002fXMLSchema-instance\u0022 xmlns:xsd=\u0022http:\u002f\u002fwww.w3.org\u002f2001\u002fXMLSchema\u0022\u003e\u003cDictionaryEntry\u003e\u003cKey xsi:type=\u0022xsd:string\u0022\u003eSPGroupID\u003c\u002fKey\u003e\u003cValue xsi:type=\u0022xsd:string\u0022\u003eMyGroupID\u003c\u002fValue\u003e\u003c\u002fDictionaryEntry\u003e\u003cDictionaryEntry\u003e\u003cKey xsi:type=\u0022xsd:string\u0022\u003eAccountName\u003c\u002fKey\u003e\u003cValue xsi:type=\u0022xsd:string\u0022\u003eMyGroup\u003c\u002fValue\u003e\u003c\u002fDictionaryEntry\u003e\u003cDictionaryEntry\u003e\u003cKey xsi:type=\u0022xsd:string\u0022\u003ePrincipalType\u003c\u002fKey\u003e\u003cValue xsi:type=\u0022xsd:string\u0022\u003eSharePointGroup\u003c\u002fValue\u003e\u003c\u002fDictionaryEntry\u003e\u003c\u002fArrayOfDictionaryEntry\u003e\u003c\u002fExtraData\u003e\u003cMultipleMatches \u002f\u003e\u003c\u002fEntity\u003e\u003c\u002fEntities\u003e";
    var tmpstr2 = tmpstr.replace('MyGroupID',groupID);
    var xml = tmpstr2.replace(/MyGroup/g,groupName);
    var sel = SP.UI.ApplicationPages.CalendarSelector.instance().getSelector(1, $(el).attr('ctxid'));
    sel.selectEntities(xml, true);
}
ExecuteOrDelayUntilScriptLoaded(_firstTime, "sp.ribbon.js");

</script>


so enjoy. :)

Please comment if you have any question.

Have a good day :)


22 comments:

  1. Hi Aleks,

    Thank you very much for the guidance, this is exactly what I am was looking for! I have one further question regarding the javascript workaround. How do I get the Group-ID of my group, which I want to handle in the calendar?
    Thank you very much for your help!
    Alex

    ReplyDelete
    Replies
    1. Hi, thank you for you comment.

      In my example, the idea was to loot at Members group of the Calendar list. I just check if group name contains word "Members"

      if (grName.indexOf("Members") >= 0)

      and the set up an id

      groupID = member.get_id();

      In this case I knew, that it will be only one Member group. So you can create our own group, and change condition.

      Best regards

      Delete
    2. Hi Aleks, for me it only works during edit mode. After saving when the page is loaded it still doesn't show all members.

      Delete
  2. Hi Aleks, I am struggling to get this to work for some reason. I have a group called staff and for some reason it just wont display :-( I changed the following
    if (grName.indexOf("Staff") >= 0) {

    ReplyDelete
    Replies
    1. Hi, did you turn on "Group Calendar Option" to yes, try to make it working with Members group, and then rename to Staff. I would advice to open developer tool F12 and loot in console tab if there are any errors.

      Delete
  3. Would like to do this in SP2010, what would I have to change

    ReplyDelete
    Replies
    1. Hi, I think it should work also in SP2010

      Delete
    2. I have it working perfectly in 2013 but am unable to get it working in 2010 for a resource calendar

      Delete
    3. Applying to 2010 produces:
      Object doesn't support property or method 'get_groups'

      Delete
    4. This comment has been removed by a blog administrator.

      Delete
    5. Hi Lan, I m glad, it helped you!!

      Delete
  4. It is a workaround,not a solution. :) I had the same issue with it. I suggest to increase timeout setTimeout('_setDefaultResources();',1000);return false;

    ReplyDelete
  5. I'm trying to do this, but till now I couldn't, I noticed that sp.ribbon.js file is not loaded in the network. What's the wrong?

    ReplyDelete
  6. MAGIC! AWESOME!!! WONDERFUL!
    IT WORKS EVERY WELL FOR ME. YOU JUST NEED TO REPLACE GROUP NAME AND ID IN THE RIGHT PLACES.

    THANK YOU SO MUCH Aleksandr Perepelkin. YOU ARE TELENTED.
    Lan Morton
    lan.morton999@gmail.com

    ReplyDelete
  7. Is it possible to show user only with events, I mean to show me and other users that HAVE particular event.

    ReplyDelete
  8. Hi, is it possible to show me and other users that have any events? I want to see me and users with particular event name/group.

    ReplyDelete
  9. HI, is it possible to create a view that will show users with particular event, let say with day of or traning, and me ( the user that is logged).

    ReplyDelete
    Replies
    1. Hi, I have not tried to create such view. I think this out of the box calendar does not support such complex workaround. So I would advice to look for other solutions.

      Delete
  10. Hi! This solution is wonderful, thanks so much.

    I did have one question, another team member viewed the Web page I created and the above solution did not seem to work for him. Does he have to in a edit the page for himself? Or did I miss a step. Thanks in advance!

    ReplyDelete
    Replies
    1. It should work, maybe a team member does have some lack of permissions

      Delete
  11. Hi, Thanks for this script Ive managed to get it to pull my SP group in however its doesn't pull in any of the data, it looks as though it needs to refresh without refreshing the page (If that makes sense)? Hope some one can help, many thanks

    ReplyDelete
  12. It is really a great work and the way in which u r sharing the knowledge is excellent.Thanks for helping me to understand basic concepts. As a beginner in Dot Net programming your post help me a lot.Thanks for your informative article. Dot Net Training in chennai | Dot Net Training in velachery

    ReplyDelete