JSLink Noticeboard for SharePoint (Online)

SharePoint Client-side rendering allows you to easily change list views and forms. In a previous post I wrote about JSLink and DataTables and how you can use them together to create powerful tabular list views. This time another example that also shows how easy it is to radically change the way list items are rendered.

Let’s create a noticeboard, a digital version of the familiar wooden-framed punch-pin boards. Something that looks like this:

1

The backend is obviously very simple, just a SharePoint list with a title and maybe an Author field. And since the rendering is based on HTML, CSS and JavaScript very few components are needed to create a great looking List View:

CSS postit.css CSS for both the post-it and the noticeboard
Images <several> Images used by the noticeboard (background and border)
JS notesListView.js The actual JSLink file which we will create in the next step

That’s it: no jQuery, no additional JavaScript, no images for the post-it itself. Because of the excellent work done by “Creative Punch” on the post-it CSS this is a very lean solution. Check out this blogpost for more information: http://creative-punch.net/2014/02/create-css3-post-it-note/

Once the files are available and loaded on the page, we need to create our JSLink file. Please note that JSLink inner workings is beyond the scope of this article. Fortunately, there is quite a lot of information available on the web. See this link for more information: http://msdn.microsoft.com/en-us/magazine/dn745867.aspx

Creating the listview

First thing we need to setup is our template registration. This registration is fairly simple as it basically only contains the container HTML structure and the ID of the List Type we are operating on. The only other thing added was some “randomness” logic that takes care of the otherwise static experience:

  • Fonts: I included three additional fonts in the CSS and you can add more if you would like.
  • Colors: these are the background colors for the post-its.
  • Degree: amount degree of tilt of the post-it.

So on every refresh the font, color and tilt can vary to mimic traditional sticky notes.

function registerNotes() {
    var itemCtx = {};

    itemCtx.Templates = {};
    itemCtx.Templates.Header = "<div id='notesListView' class='notes-container'>";
    itemCtx.Templates.Item = ItemOverrideNotes;
    itemCtx.Templates.Footer = "</div>";
    itemCtx.ListTemplateType = 100;
    itemCtx.OnPostRender = [];

    itemCtx.OnPostRender.push(function () {
        var myElements = document.querySelectorAll(".post-it");

        for (var i = 0; i < myElements.length; i++) {
            var fonts = ["Cookie:30", "Satisfy:27", "Merienda One:20"];
            var colors = ["#eae672", "#cfe38c", "#f9666e"];
            var rDegree = (Math.random() * 4) - 2;
            var rFont = fonts[Math.floor(Math.random() * fonts.length)];
            var rColor = colors[Math.floor(Math.random() * colors.length)];

            myElements[i].style.webkitTransform = 'rotate(' + rDegree + 'deg)';
            myElements[i].style.mozTransform = 'rotate(' + rDegree + 'deg)';
            myElements[i].style.msTransform = 'rotate(' + rDegree + 'deg)';

            myElements[i].style.background = rColor;
            myElements[i].style.fontFamily = rFont.split(":")[0];
            myElements[i].style.fontSize = rFont.split(":")[1] + 'px';
        }
    });

    SPClientTemplates.TemplateManager.RegisterTemplateOverrides(itemCtx);
}

The actual post-it note is created during the List Item override.

function ItemOverrideNotes(ctx) {
    var rowItem = "<div class='post-it'><i class='pin'></i><blockquote class='note'>";
    rowItem += "<a href='" + ctx.displayFormUrl + "&ID=" + ctx.CurrentItem.ID + "'>";
    rowItem += ctx.CurrentItem.Title;
    rowItem += "</a><cite class='author'>";
    rowItem += ctx.CurrentItem.Author[0].title;
    rowItem += "</cite></blockquote></div>";

    return rowItem;
}

We save all of this code to a separate JSLink JavaScript file so we can reference it from our Web Part properties.
Setting it up
The setup of the solution is easy since you just need to copy the files to a shared location (for instance the Style Library, Asset Library or Master Page gallery. The most important part is to have the CSS files loaded on the page you enable this view on. As mentioned earlier, there are multiple ways to achieve this so you should be able to get this to work.Just remember, you only need the support files pre-loaded on the page and not the actual JSLink file. We can reference that from our Web Part properties:

2

To be able to show the Author field, we should also include the field in the view:

3

Once saved and published, the page should show the noticeboard in all its glory. Download the sample files here: Blog.Examples.NoticeBoard

Please note: this code was not tested in every browser known to mankind, so your mileage will vary J (actually it was only tested in IE 10+ and a recent version of Chrome). If you want to make this work for older versions, you will likely have to adjust the CSS.

Another thing to note is that I load the CSS from the JSLink file. You might want to load this with your other CSS files. In that case you can remove the IncludeCSS function and call.

Advertisements

6 comments

  • this is awesome ..thank you for sharing

  • Sir..is it ok, if I use this in one of my solutions?

  • Hi ,

    Actually this link Blog.Examples.NoticeBoard (see above) is not working. The list is not rendering anything, can you help me out?

    I have created a simple list called ‘Notes’ with the columns ‘Title and Author’ in the view included. And I have this piece refering from JS Link textbox:

    /*
    Code by Creative Punch
    http://creative-punch.net/2014/02/create-css3-post-it-note/#comments
    Create a CSS3 post-it note without images
    */

    @import url(http://fonts.googleapis.com/css?family=Satisfy);

    .quote-container {
    margin-top: 50px;
    position: relative;
    }

    .note {
    color: #333;
    position: relative;
    width: 300px;
    margin: 0 auto;
    padding: 20px;
    font-family: Satisfy;
    font-size: 30px;
    box-shadow: 0 10px 10px 2px rgba(0,0,0,0.3);
    }

    .note .author {
    display: block;
    margin: 40px 0 0 0;
    text-align: right;
    }

    .yellow {
    background: #eae672;
    -webkit-transform: rotate(2deg);
    -moz-transform: rotate(2deg);
    -o-transform: rotate(2deg);
    -ms-transform: rotate(2deg);
    transform: rotate(2deg);
    }

    .pin {
    background-color: #aaa;
    display: block;
    height: 32px;
    width: 2px;
    position: absolute;
    left: 50%;
    top: -16px;
    z-index: 1;
    }

    .pin:after {
    background-color: #A31;
    background-image: radial-gradient(25% 25%, circle, hsla(0,0%,100%,.3), hsla(0,0%,0%,.3));
    border-radius: 50%;
    box-shadow: inset 0 0 0 1px hsla(0,0%,0%,.1),
    inset 3px 3px 3px hsla(0,0%,100%,.2),
    inset -3px -3px 3px hsla(0,0%,0%,.2),
    23px 20px 3px hsla(0,0%,0%,.15);
    content: ”;
    height: 12px;
    left: -5px;
    position: absolute;
    top: -10px;
    width: 12px;
    }

    .pin:before {
    background-color: hsla(0,0%,0%,0.1);
    box-shadow: 0 0 .25em hsla(0,0%,0%,.1);
    content: ”;
    height: 24px;
    width: 2px;
    left: 0;
    position: absolute;
    top: 8px;
    transform: rotate(57.5deg);
    -moz-transform: rotate(57.5deg);
    -webkit-transform: rotate(57.5deg);
    -o-transform: rotate(57.5deg);
    -ms-transform: rotate(57.5deg);
    transform-origin: 50% 100%;
    -moz-transform-origin: 50% 100%;
    -webkit-transform-origin: 50% 100%;
    -ms-transform-origin: 50% 100%;
    -o-transform-origin: 50% 100%;
    }

    function registerNotes() {
    var itemCtx = {};

    itemCtx.Templates = {};
    itemCtx.Templates.Header = “”;
    itemCtx.Templates.Item = ItemOverrideNotes;
    itemCtx.Templates.Footer = “”;
    itemCtx.ListTemplateType = 100;
    itemCtx.OnPostRender = [];

    itemCtx.OnPostRender.push(function () {
    var myElements = document.querySelectorAll(“.post-it”);

    for (var i = 0; i < myElements.length; i++) {
    var fonts = ["Cookie:30", "Satisfy:27", "Merienda One:20"];
    var colors = ["#eae672", "#cfe38c", "#f9666e"];
    var rDegree = (Math.random() * 4) – 2;
    var rFont = fonts[Math.floor(Math.random() * fonts.length)];
    var rColor = colors[Math.floor(Math.random() * colors.length)];

    myElements[i].style.webkitTransform = 'rotate(' + rDegree + 'deg)';
    myElements[i].style.mozTransform = 'rotate(' + rDegree + 'deg)';
    myElements[i].style.msTransform = 'rotate(' + rDegree + 'deg)';

    myElements[i].style.background = rColor;
    myElements[i].style.fontFamily = rFont.split(":")[0];
    myElements[i].style.fontSize = rFont.split(":")[1] + 'px';
    }
    });

    SPClientTemplates.TemplateManager.RegisterTemplateOverrides(itemCtx);
    }

    function ItemOverrideNotes(ctx) {
    var rowItem = "

    “;
    rowItem += ““;
    rowItem += ctx.CurrentItem.Title;
    rowItem += “
    “;
    rowItem += ctx.CurrentItem.Author[0].title;
    rowItem += “

    “;

    return rowItem;
    }

    • Hi Mohamed, it seems wordpress has stripped the HTML tags from your comment making it a bit difficult for me to see what might be wrong. Did you include the CSS as part of the JS file or did you load them separately?

  • Hi Yuri,

    I’ve incuded the css as part of the js file.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s