2

Here i am working with SharePoint Calendar. I came up with the requirement where i need to filter the Calendar view by Category. Here i am entering the custom categories.

Here is my approach snap:

User interface

I was able to filter the Calender View by Month/Date/Week with the help of this post Changing view of Calendar

But for filtering Calendar based on custom category i am not able to get any proper approach or code.

If any one of you have gone through the same requirement then please suggest me the approach or solution.

My working environment is SharePoint Online and i want to avoid custom C# solutions.

Based on the answer given by @Hardik I kept an CEWP and kept the following code

<html>
<head>
    <title></title>
    <style type="text/css">
        .ms-cal-nodataMid, .ms-cal-nodataBtm2 {
            background-color: #FFFFFF;
        }
    </style>
    <script type="text/javascript" src="DocumentLibraryUrl/interaction.js"></script>
    <script type="text/javascript" src="DocumentLibraryUrl/jquery-1.9.1.min.js"></script>
    <script type="text/javascript" src="DocumentLibraryUrl/stringBuffer.js"></script>
    <script type="text/javascript">
    // Set variables

    function filterCode()
    {
        listGuid = 'Company Calender'; // Use list Name or List Guid
        listBaseUrl = L_Menu_BaseUrl;
        arrOfFieldInternalNames = ['Category']; //Put the internal name of the field "Category" here.

        // Hide calendar view until it is filtered
        $(".ms-cal-gempty").hide();

        // Get the UserInfo
        var e = document.getElementById("ddlFilter"); // Change the dropdown ID here.
        var category = e.options[e.selectedIndex].value;

        // Find all "relevant" items
        var myItems = getMyItemsID(category, arrOfFieldInternalNames);
        // Filter view
        filterCalendarView(myItems);

    }


    function getMyItemsID(find, findInArr) {
        debugger;
    wsBaseUrl = listBaseUrl + '/_vti_bin/';
    var query = "";
    $.each(findInArr, function (i, fin) {
        query += "<Eq><FieldRef Name='" + fin + "' /><Value Type='Text'>" + find + "</Value></Eq>";
        if (i > 0) query = "<Or>" + query + "</Or>";
    });
    query = "<Where>" + query + "</Where>";
    var arrToReturn = [];
    res = queryItems(listGuid, query, ['ID']);
    $.each(res.items, function (i, item) {
        arrToReturn.push(item.ID);
    });
    return arrToReturn;
}

    function filterCalendarView(arrOfIDs) {
        debugger;
    $(".ms-cal-gempty a[href*='DispForm.aspx?ID=']").each(function () {
        var currID = $(this).attr('href').match(/ID=(d+)/);
        if ($.inArray(currID[1], arrOfIDs) == -1) {
            // remove
            var thisParentTd = $(this).parents('table:first').parents('td:first');
            var colspan = thisParentTd.attr('colspan');
            if (colspan > 1) {
                for (i = 1; i < colspan; i++) {
                    thisParentTd.after("<td class='ms-cal-workitem'>&nbsp;</td>");
                }
                thisParentTd.replaceWith("<td class='ms-cal-workitem'>&nbsp;</td>");
            } else {
                thisParentTd.html('&nbsp;');
            }
        }
    });
    // Show calendar view after it has been filtered
    $(".ms-cal-gempty").show();
}

    </script>

</head>
<body>
    <select onchange="filterCode()" id="ddlFilter">
        <option value="test">test</option>
        <option value="test1">test1</option>
        <option value="test2">test2</option>
    </select>
</body>
</html>

Still code has no effect. Console does not shows any error log.

1
  • @ Hardik, I am working on similar requirement, where do I get interaction.js and stringbuffer.js libraries as mentioned in your code. Also I found interact.js Is that same as interaction.js? Any suggestions? Aug 7, 2017 at 14:58

1 Answer 1

2

Add this code to a CEWP below the calendar view:

Note :- Change the variables according to your needs.

<style type="text/css">
    .ms-cal-nodataMid, .ms-cal-nodataBtm2 {
        background-color: #FFFFFF;
    }
</style>
<script type="text/javascript" src="/test/English/Javascript/jquery-1.3.2.min.js"></script>
<script type="text/javascript" src="/test/English/Javascript/interaction.js"></script>
<script type="text/javascript" src="/test/English/Javascript/stringBuffer.js"></script>
<script type="text/javascript">
    // Set variables
    listGuid = 'FilterCalendarView'; // Use list Name or List Guid
    listBaseUrl = L_Menu_BaseUrl;
    arrOfFieldInternalNames = ['Category']; //Put the internal name of the field "Category" here.

    // Hide calendar view until it is filtered
    $(".ms-cal-gempty").hide();

    // Get the UserInfo
    var e = document.getElementById("ddlCategory"); // Change the dropdown ID here.
    var category = e.options[e.selectedIndex].value;

    // Find all "relevant" items
    var myItems = getMyItemsID(category, arrOfFieldInternalNames);
    // Filter view
    filterCalendarView(myItems);

    function getMyItemsID(find, findInArr) {
        wsBaseUrl = listBaseUrl + '/_vti_bin/';
        var query = "";
        $.each(findInArr, function (i, fin) {
            query += "<Eq><FieldRef Name='" + fin + "' /><Value Type='Text'>" + find + "</Value></Eq>";
            if (i > 0) query = "<Or>" + query + "</Or>";
        });
        query = "<Where>" + query + "</Where>";
        var arrToReturn = [];
        res = queryItems(listGuid, query, ['ID']);
        $.each(res.items, function (i, item) {
            arrToReturn.push(item.ID);
        });
        return arrToReturn;
    }

    function filterCalendarView(arrOfIDs) {
        $(".ms-cal-gempty a[href*='DispForm.aspx?ID=']").each(function () {
            var currID = $(this).attr('href').match(/ID=(d+)/);
            if ($.inArray(currID[1], arrOfIDs) == -1) {
                // remove
                var thisParentTd = $(this).parents('table:first').parents('td:first');
                var colspan = thisParentTd.attr('colspan');
                if (colspan > 1) {
                    for (i = 1; i < colspan; i++) {
                        thisParentTd.after("<td class='ms-cal-workitem'>&nbsp;</td>");
                    }
                    thisParentTd.replaceWith("<td class='ms-cal-workitem'>&nbsp;</td>");
                } else {
                    thisParentTd.html('&nbsp;');
                }
            }
        });
        // Show calendar view after it has been filtered
        $(".ms-cal-gempty").show();
    }

</script>

This solution does:

  1. Filters a calendar view based on a text retrieved from the Dropdown.
  2. Filters with an “OR” statement looking for a match in multiple text fields
  3. Handles “single day items” and items spanning over multiple days.
  4. Hide the calendar view until it has been filtered.
8
  • is this code works for you?
    – Hardik
    Apr 27, 2016 at 7:12
  • I am trying dude. let you know as soon as i am done. Apr 27, 2016 at 7:20
  • ok if you need help than please let me know here.
    – Hardik
    Apr 27, 2016 at 7:21
  • i implemented the code but i am not able to get requirement solved. There is no error i checked in console, but its not working, i guess i am missing something. I downloaded interaction.js, stringbuilder.js and jquery and uploaded in document library and linked it into code, replaced the list name, replaced the internal name of field though its not working. Any suggestion? Apr 27, 2016 at 8:28
  • debug the code...you will get idea.. Or post the entire code so i can look into it
    – Hardik
    Apr 27, 2016 at 8:30

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