Having multiple JSLink based webparts on the same page, overrides all the other templates in SP 2013


Scenario:

Create a dashboard page in SP 2013, displaying just 3 lists in 3 different views using Js Link capability. The 3 lists are:

  1. Accordion: A list containing title and description which will be displayed on the dashboard with an accordion functionality with title being the accordion item heading and description being the accordion item body.
    Image
  2. Menu: A list containing entries that can be used to construct a mega menu or a navigation menu.
    Image
  3. Alert: A list containing entries whose Body contents are lengthy and hence have to be trimmed down and ellipsis (…) added to the lengthy ones
    Image

The dashboard page was created and all the 3 list view webparts were added to it. All of them were given 3 different JsLink with different namespaces and method names. Each js had their template methods that rendered the list in the desired views and functionalities. ex. the accordion template method just returned “<h2>{Title}</h2><p>{Description}</p>” and an OnPostRender jQuery script to toggle them on <h2> click.

Issue:

Loaded the Alert list first on the fresh page–> No issue; trimming the body content worked perfectly

Image

Loaded the Accordion list next –> No issue; slide up and down of the accordion worked perfectly
Image

Loaded the Menu list next –> Boom! The accordion lost its Js Link functionality and started behaving like the menu displaying items using the template defined for the Menu list.

Image

Attached below are the 3 JsLink files used:

AlertsAccordion | Menu

Feel free to test it out…

If the JS Links had different namespaces & methods, why would it overwrite all the other templates on the same page? Could it be by design? By changing the BaseViewID, i could get the Accordion working but the menu then started taking the accordions template behavior…:(

Finally, I ended up having a single Js Link file (added as JS Link to all the webparts on the page) having the same template method, but internally it loaded different templates for each webpart by doing an <if> condition check for the List Name.
ex. if (ctx.ListName==’Accordion’) return “<h2>{Title}</h2>…”; if (ctx.ListName==’Menu’) return ‘<ul><li>{Tite}</li></ul>’; etc…

But somehow you will feel something is not right when you code it. Having a bulky js method with If-else or switch-cases…:(

Solution:

Paul Hunt (@Cimares) has the solution for this scenario wonderfully detailed out here.This solution works and you can do an IF condition check to load the templates corresponding to each webpart accordingly.

I still wish if i could use independent JS Link files for all the webparts on the dashboard…:(…But, all in all JSLink is wonderful and I am happy to see MS taking the client side route and would love to support them in this direction…:)

Feel free to post your comments or possible alternatives or solutions.

JSLink SharePoint 2013 troubleshooting


JsLink is a good feature that was introduced in SP 2013 to allow users to bring in more flexibility in Client Side Rendering (CSR). With this you can control how your list data is getting displayed in View, Display, Edit and New forms.

For ex., you can achieve this using JSLink:

Image

 

You can check the implementation here: JSLink Custom JS Rendering Tutorial

ISSUE:

The JS Link was still not working and the list view remained the same.

SOLUTION #1:

Check the URL you defined in your JSLink webpart property (under Miscellaneous). You need to define the URL as: ~site/Site Assets/xyz.js” instead of defining the absolute or relative URL of your js file. It should always begin with a given set of URL tokens and then your file path. JsLink URL can begin with either of the following URL tokens: ~site, ~sitecollection, ~layouts, ~sitecollectionlayouts or ~sitelayouts only. Absolute paths will break the JsLink functionality.

SOLUTION #2:

MDS (Minimal Download Strategy) strategy having issues. Try using RegisterModuleInit(“{file URL}”, MyJsMethod); to register the JSLink. Check this link.

Also, as a best practice, its recommended to specify the SharePoint CSR filename in the JS Link URL.

ex. The JSLink URL for Tile View in Promoted Links would look like:

sp.ui.tileview.js | ~site/SiteAssets/xyz.js

Basics of javascript Templating


Being the 100th post, i felt i should share some of my most useful learning here. And i could not think of anything better than javascript Templating. There are quite a handful of such templating tools available online(JsRender, Underscore.js, Moustache.js…). Feel free to run a jsPerf on the tool you wish to use and then go ahead. This post will focus on giving you a grip on the concept of templating in javascript, by correlating it to a day to day example you see around you.

A little bit of Background:

The concept of templating is pretty simple once you understand what it is. Let me take you through a simple example here, so that you could correlate this concept to some live example and remember this forever.

Observe the Facebook “People You May Know” (PYMK) section below:

Fb People You May Know section

 

 

 

 

 

 

 

 

 

 

 

 

Its pretty much straight forward, with a header and some contents. Normally we feel that its a direct 6 div-based HTML section (1 div for header and 5 for the friends list). Lets deep dive into this a little bit.

When we look deeper, we could see two major sections here. One is the header and then there a friends list section which is replicated as is 5 times, but with different contents.

Consider the section breaking visually below:

Fb PYMK Section Breakup

 

 

 

 

 

 

 

 

 

 

 

 

Header is simple and nothing much special about it. You could even achieve it using a simple HTML code. But our focus here is the “Repeating Template Section“. This section repeats by itself 5 times here, populating 5 different contents. This is infact the place where we could see the power of templating coming into play.

But before that lets dig a bit more deeper into the repeating Template section:

Fb PYMK Template section detailed

 

 

 

 

 

How Templating Works:

Now lets see how these templating engines available online works. For simplicity, I am considering JsRender here.

Firstly, its nothing but a plugin – jsrender.min.js (just like your jQuery.min.js), you can download from Github.

Secondly, it basically need 2 inputs(for just the basic functionality):

1. Is the Template section – An HTML section on the page with just the basic skeletal structure, as shown below

Fb PYMK Template Schema

Inside these sections we normally keep something called placeholders, for ex.

A sample template could be like this:

<script id=”tmpl_pymk” type=”text/x-jsrender”>

<div id=’hdrpymk’>

People You May Know

<a href=”{{>SeeAllLink}}“>See All</a>

</div>

<div id=’rptpymk’>

<img src=’{{>ProfilePic}}‘ />

</div>

</script>

The templating engine just replaces these placeholders (SeeAllLink, ProfilePic) with the data picked up from the input JSON

2. The Input JSON

JsRender Input JSON Sample

Note: In the above JSON, I have shown only 3 entries; which would imply the final rendered HTML would generate 3 repeater section with the data you provided in the “Contents” array inside the input JSON (see above screenshot).

Thirdly, using the render() method, it merges the input JSON into the template and constructs the final HTML, which you can render it on your page.

var finalHTML = $(“#tmpl_pymk”).render(jsondata);

As simple as that!!

A schematic diagram of how this works is shown below:

JsRender Templating Working

HEADER: This could be just the heading with a link to “See All”

SECTION DATA: JsRender repeats this section 5 times displaying different data, picking them up from the input JSON. I shall get into the technical aspects in a later post.

But for now, I hope you got a background on how templating works in javascript and you could visualize the power of this concept in our day to day life.

This is just a drop from the ocean i wish to drive you through. But i hope the example used here helped you correlate to the concept.

Hope this post was useful!!

Feel free to post your comments & suggestions.

Note: The example used here is just a sample and need not be the way fb would have implemented it. The idea here is to correlate this topic to things that we see around us on the web in a better way.

Detect multiple key press in javascript for your website


Many a times we end up in situations where in our clients are windows app migrants to web. And they could not let go off the “hotkey” concept. Let’s say “Ctrl + S” or “Alt + R” to perform save or submit operation on a website. The options are endless.

A scalable code that you could use to achieve something in line with this is given below:

//Register the Utility Namespace
var Utility = Utility || {};

/**
* @MethodName : Utility.RegisterKeyPress
* @Description : Register multiple key press events
* @Param {object} ctrl : The control to be clicked when the user press Alt + R
*
* @Example : Utility.RegisterKeyPress('#btnSubmit');
*/
Utility.RegisterKeyPress = function (ctrl) {
    //keyCodes for Alt(18) and r(82)
    var codeset = { 82: false, 18: false };

    //Tracking the Key down & Key up events
    $(document).on('keydown', function (e) {
        if (e.keyCode in codeset) {
            codeset[e.keyCode] = true;
            if (codeset[82] && codeset[18]) {
                //Functionality to be executed on key press - Alt + R
                //An alert here would trigger on each key press
                //Instead define your functionality here
                //Click is an example used here.
                $(ctrl).click();
            }
        }
    }).on('keyup', function (e) {
        if (e.keyCode in codeset) {
            codeset[e.keyCode] = false;
        }
    });
};

//Invoke the above method
//When the user press Alt + R on the page, it will trigger the submit button click
Utility.RegisterKeyPress('#btnSubmit');

You could extend this code to any key press by referring to the javascript keycode chart from here.

Hope this was useful!!

Combining Multiple attributes in jQuery


Below are some of the code snippets available in jQuery for you to combine your multiple lines of code:

Combining multiple css properties or element attributes:

Statement: Set the width and height attributes for a table with id=mytable
$(“#mytable”).attr({width:’50px’,height:’40px’});

Statement: Set the css properties of width, height, background-color for a div with id=mydiv
$(“#mydiv”).css({width:’50px’,height:’40px’,background-color:’#F2F2F2′});

Combining element multiple selector:

Statement: Set the width, height and background-color css properties for controls with id=mydiv1, mydiv2 and mydiv3

$(“#mydiv1, #mydiv2, #mydiv3”).css({width:’50px’,height:’40px’,background-color:’#F2F2F2′});

Combining attribute selectors:

Statement: Find out those elements with an id attribute, having ‘name’ ending with ‘mydiv’ and the ‘checked’ state being ‘checked’

$(“#mydiv[id][name$=’mydiv’][checked=’checked’]”).val();

Combining attribute selectors with psuedo properties:

Statement: Delete dropdown option values myvalue3, myvalue4 from a dropdown with id=mydiv

$(“#mydiv options:not([value=’myvalue1′][value=’myvalue2′]).remove();
$(“#mydiv options:[value=’myvalue3′],[value=’myvalue4′]”).remove();

Note: The coma separator in the last statement above will perform a repeat operation on the same element which implies that the above statement is a combined version of the below statements:

$(“#mydiv options:[value=’myvalue3′]”).remove();

$(“#mydiv options:[value=’myvalue4′]”).remove();
Setting multiple attributes for an element:

Statement: Create a new anchor tag and set its id, class and redirect url

$(‘</a>’, {
id : ‘myId’,
class : ‘myClass’,
href : ‘mytest.html’
});

Combining Objects in jQuery:

Statement: To combine or merge two objects in jQuery

var parentObject = { property1: false, property2: 5, property3: “foo” };
var options = { property1: true, property3: “bar” };

jQuery.extend(parentObject, options);
//Final values for parentObject { property1: true, property2: 5, property3: “bar” }

Happy Coding!!!

Best Practices for jQuery Developers


Following are some of the best practices that you could follow while working with jQuery:

  • Plugins:
    • Please avoid unnecessary use of plugins
    • If a plugin is being used, respect the authors work and ensure that the plugin file is reused with the license comments intact
    • If you are writing a reusable functionality in the code, always move it into a jQuery plugin format, to be reused across the site
  • Coding:
    • Use jQuery CDN (google or Microsoft or jQuery) as much as possible for script registration, if its fine with clients. To be on the safer side, you could have a fallback code as well:
      <!– Grab Google CDN jQuery. fall back to local if necessary –> 

<script src=”http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js“></script> 

<script>!window.jQuery && document.write(‘<script src=”js/jquery-1.4.2.min.js”><\/script>’)</script>

  • Avoid unnecessary upgrades of jQuery, unless there are features, which you require or some plugins require. Stick to one version from the beginning. (ex. 1.5.1)
  • Avoid writing event handler attributes (onclick etc.), instead use live or bind methods to attach the respective event handlers.
  • Avoid mixing javascript code with jQuery code.
  • Cache any jQuery selector, if reused in multiple statements.
    Ex. Avoid $(“#x”).val(); $(“#x”).attr(“align”,”right”); Use var $x = $(“#x”); $x.val();$x.attr(“align”,”right”);
  • Ensure that you place ready function in your code. $(document).ready(function(){});
  • Use find method, instead of building a complex jQuery selector.

//Fine in modern browsers, though Sizzle does begin “running”

$(‘#someDiv p.someClass’).hide(); 

// Better for all browsers, and Sizzle never inits. 

$(‘#someDiv’).find(‘p.someClass’).hide(); 

  • Avoid misusing $(this).
    Ex. Use this.id instead of $(this).attr(‘id’)
  • Keep your code safe, by using noConflict() method or by passing jQuery.
    Ex. (function($){})(jQuery); or by wrapping it in a ready method.
  • Avoid declaring new jQuery selectors within foreach, instead declare them outside and reuse it inside the loop.
  • Use $.ajax instead of $.get or $.getJSON, because internally they call $.ajax.
  • Use JSON formats for communications.
  • Ensure that you move your jQuery codes to a separate javascript file, instead of inline scripts.
  • Compress javascript files for better performance.
  • Combine multiple css() calls or attr() calls into one. In case of attributes, you could also pass them as shown below: 
$(‘</a>’, {

    id : ‘myId’, 

    className : ‘myClass’, 

    href : ‘mytest.html’ 

});

  • Debugging:
    • Use Developer Toolbars and Inspectors to debug your code from client side. You do not need to perform deployments and builds to debug your jQuery code(s).
  • jQuery Cheat Sheet:
    • Always keep a jQuery cheat sheet handy with you to know about the list of functions available for you. Download here

Below are some more useful links you could check out:

Some words of caution:

  • $.ajax has issues in making cross domain AJAX calls. As a solution, you can get a patched version of $.ajax from the net.
  • Avoid http request on https sites. Your user will be prompted with a nagging security popup, which on rejection can break your request.
  • Avoid loading multiple jQuery versions.
  • Majority of the jQuery plugins are browser compatible, but NOT ALL. Read the plugin documentations carefully and use them judiciously.

This might appear to be a drop from the ocean. But it will guide them in the right direction.

Generate JSON string output in C#


This is one of the most widely used and very useful script that you could use in your web services/ WCF services/ Handlers or any place wherein you require a JSON string to be passed to the client/ consumer.

We make use of the Serialize method in JavaScriptSerializer class in C# under the following namespace:

using System.Web.Script.Serialization;

The code snippet below show how its done:

//Namespace for the JavascriptSerializer object

using System.Web.Script.Serialization;

public string GenerateJSONString(List<myObject> myCustomList)

{

//Initialize the JavascriptSerializer object   

JavaScriptSerializer serializer = new JavaScriptSerializer();

//Initialize a stringbuilder object to hold the final JSON output     

StringBuilder jsonBuilder = new StringBuilder();

//Generate the JSON string

serializer.Serialize(myCustomList, jsonBuilder);

//Return the JSON string

return Convert.ToString(jsonBuilder);

}

This code is just a framework to get to know that the JavascriptSerializer could help you generate JSON string with ease.

In the client side, you could use jQuery.parseJSON(JSONstring); and then parse this JSON string using the myObject properties. Remeber that parseJSON was added in jQuery v1.4.1.