Multiple instances of javascript webparts on the same page
By Anatoly Mironov
Javascript has become popular among many SharePoint developers thanks to easy and fast jQuery, CSOM, SPServices and many other javascript libraries. That can make solutions modern and fast. On the other hand developers should be aware of more things (some of them at Bamboo Team Blog). One of those is scoping of javascript webparts. The problem a developer has to consider: what happens if a user creates two or more instances of the same beautiful webpart on the page? Let’s go and lab :) I’ll create a solution for this lab: sp-lend-id.ikkelen. This time it will be a sandboxed solution. This solution contains a webpart:
<%@ Assembly Name="$SharePoint.Project.AssemblyFullName$" %>
<%@ Assembly Name="Microsoft.Web.CommandUI, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Control Language="C#" AutoEventWireup="true"
CodeBehind="Ikkelen.ascx.cs" Inherits="sp\_lend\_id.ikkelen.Ikkelen.Ikkelen" %>
<link rel="stylesheet" href="/sp-lend-id/ikkelen.css"/>
<script type="text/javascript"
src="//ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script type="text/javascript"
src="/sp-lend-id/ikkelen.js"></script>
<div id="notification-area"></div>
<input type="button" id="clickMe" value="Click me to show a notification"/>
```a javascript file:
function notifyIkkelen() { jQuery("#notification-area") .append(jQuery("Tada!")); } function initIkkelen() { jQuery("#clickMe").on({ click: notifyIkkelen }); } jQuery(document).on({ ready: initIkkelen });
.notification { font-size: 20px; padding: 8px 35px 8px 14px; margin-bottom: 18px; color: #C09853; text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); background-color: #FCF8E3; border: 1px solid #FBEED5; border-radius: 4px; }
#### What shall we do about it?
##### Proposition 1: Make advantage of ASP.NET built-in id genereation
If you want to use your ids and make sure they don't conflict, just add runat="server" to your divs and in jQuery selector use ClientID: [![](https://sharepointkunskap.files.wordpress.com/2012/06/ikkelen-005.png "ikkelen-005")](https://sharepointkunskap.files.wordpress.com/2012/06/ikkelen-005.png) That generates unique ids. But unfortunately it isn't enough: [![](https://sharepointkunskap.files.wordpress.com/2012/06/ikkelen-006.png "ikkelen-006")](https://sharepointkunskap.files.wordpress.com/2012/06/ikkelen-006.png) Now every time I click on the first button or the second button a notification is added to the second notification area (with the last loaded auto-generated id). Allright, what if we "scope" it by using an anonymous function as a click event listener which won't be overwritten:
function initIkkelen() { jQuery("#<%= clickMe.ClientID %>").on({ click: function() { jQuery("#<%= notificationArea.ClientID %>") .append(jQuery("Tada!")); } }); } jQuery(document).on({ ready: initIkkelen });
##### Proposition 2. Use webpart scopes
First of all we have to remove all ids, because ids cannot be used more than once on a page. We can use just class attributes as in many projects. But there can be problems as well, because class attributes are a designer's domain. Your solution should not break if you as designer then add and remove classes to adjust the look. Let's take inspiration from [jQuery Mobile](http://jquerymobile.com/) and **data-role** attributes. Ikkelen.ascx:
function initIkkelen() { jQuery("[data-role=‘clickMe’]").on({ click: notifyIkkelen }); }
$(document).on({ ready: initIkkelen });
(function($) { function notifyIkkelen() { $("[data-role=‘notification-area’]") .append($("Tada!")); }
function initIkkelen() { $("[data-role=‘clickMe’]").on({ click: notifyIkkelen }); }
$(document).on({ ready: initIkkelen }); })(jQuery);
function ikkelen($, webpartId) { var webpart; function notifyIkkelen() { webpart.find("[data-role=‘notification-area’]") .append($("Tada!")); }
function initIkkelen() { webpart = $("#" + webpartId); webpart.find("[data-role=‘clickMe’]").on({ click: notifyIkkelen }); }
$(document).on({ ready: initIkkelen }); }
(jQuery, “<%= this.Parent.ClientID %>”)
## Comments from Wordpress.com
####
[Björn]( "bjorn.roberg@bool.se") - <time datetime="2012-09-06 13:47:24">Sep 4, 2012</time>
Module pattern rocks! And with this pattern, it's easily integrated into SP. Awesome!
<hr />
####
[Anatoly Mironov]( "mirontoli@gmail.com") - <time datetime="2012-09-06 14:15:58">Sep 4, 2012</time>
Thank you Björn! When developing javascript solutions for SharePoint it is not taken much attention to the fact that the webparts can be provisioned multiple times and in pages and contexts we don't know about. So encapsulating the javascript code and using modules gives us more control und encreases the product quality.
<hr />
####
[Arumoy]( "arumoy18@gmail.com") - <time datetime="2015-06-04 07:53:25">Jun 4, 2015</time>
Thank you. Great article. It saves my day.
<hr />