Developing ScriptParts

As stated in the introduction, a ScriptPart has to contain a JavaScript object that implements a Render method, and the filename must be the full object name, including namespace, with the extension .js. When adding the ScriptPart to the ScriptPart Library, the title can be set to give a more readable description to the ScriptPart in the selection menu. This is already optional.

So lets take a look at one of my samples, the My Red BG Title. This one has been added to the Script Editor part on the page directly.

<script>
Test = {};
Test.Part = {};
Test.Part.Render = function(el, settings) {
   var o = Booden.jq("<div style='background-color: red;'>" + settings.title + "</div>");
   o.appendTo(el);
};
Booden.ScriptParts.RegisterPageScriptPart("My Red BG Title", "Test.Part");
</script>

That looks simple enough, I think. So this starts by declaring the 'namespace' Test, and then the (initialized) object Part. Then we add the Render function to this object. This function recieves:

  • el - the jQuery object of the container element.
  • settings - the object with the ScriptPart settings, by default this contains the title.

As the ScriptParts framework intelligently loads jQuery, even if .noConflict has been used, a variable jq in the namespace Booden is available to get to jQuery. If you use $ or jQuery directly, this might be an issue when .noConflict is used.

An element containing a div with a red background, containing the ScriptPart title, is then added to the container element. That is all there is to it. Now as this is added to the page directly the RegisterPageScriptPart is called. This method requires the title and the full object name of the ScriptPart as text parametrs.

One thing to note here, I added 'initialized' to the object Part, as this method of creating a JavaScript object already creates an instance. If you use this and add multiple ScriptParts of this type to the page, they all share this instance. In this case this is no problem, but you might want to consider a different approach, and create an object that needs to be initialized with the new keyword first (this is done automatically by the framework).

Booden = window.Booden || {};
Booden.SimpleSample = window.Booden.SimpleSample || function () { }; // using function here

// settings script not shown here

// using prototype here
Booden.SimpleSample.prototype.Render = function (el, settings) {
    var content = Booden.jq('<div>'
        + '<div>' + settings.val1 + '</div>'
        + '<div>' + settings.val2 + '</div>'
        + '<div>' + settings.val3 + '</div>'
        + '<div>' + settings.val4 + '</div>'
        + '</div>');
    content.appendTo(el);
}

Here we create an object definition and add the methods to the prototype. An other option could be:

Booden = window.Booden || {};
Booden.CreateSitePart = window.Booden.CreateSitePart || function() {

    this.target = "";
    this.Url = "";
    this.BaseUrl = _spPageContextInfo.webAbsoluteUrl;
    this.Title = "";
    this.ResultElement = "createResult";
    this.LoadingElement = "waitForLoad";


    // methods not shown for brevity

    this.Render = function (el) {
        // not shown for brevity
    }

};

Here we directly add properties and methods within the function. As JavaScript is a flexible language, there are multiple options to achieve your goal. The main thing to notice here, is the difference between a single shared object and multiple object instances.

When using multiple instances, you probably would want to us the object with the this keyword, to refer to the current instance, for example in a click event. As the this keyword is context sensitive, you need to take this into account.

var btn = Booden.jq("<input type='button' value='Create Site' />");
var me = this;
btn.on("click", function () { me.Create() });
btn.appendTo(el);

Here is an abstract from the CreateSitePart. In the render method we want to bind the click event to the create method of this object. To do so, we must declare a local variable, set the variable to this, and use the variable in the handler. You need to do this as the this keyword in the handler, when called, has a different context, and will not point to the current object.

Most of the above, involves JavaScript and isn't related to the requirements for creating a ScriptPart. I think describing these scenarios makes it easier to create ScriptParts.

How to add settings

This is optional. If you use this, there are some requirement you need to adhere to. Lets take a look at the settings of the Simple Sample ScriptPart:

Booden.SamplePartSettings = window.Booden.SamplePartSettings || {};
Booden.SamplePartSettings.Defaults = { say: 'Hello', text: 'Hello world of ScriptParts' };
Booden.SamplePartSettings.RenderForm = function(body, settings, easyadd) {
   easyadd('say', 'Say', settings.say);
   var el = Booden.jq('<div style="margin: 10px 10px 10px 10px;"><label>Text: <div><input type="text" name="text" value="' + settings.text + '" style="width: 220px;" /></div></label></div>');
   el.appendTo(body);
};

The first thing to note is that you need to add settings using a naming convention. This is [full object name]Settings, so these settings are for the Booden.SamplePart object. The settings object needs to be an already instantiated object, hence the { }, and you need to add the Defaults as an object with properties and values, these need to be text values that can be parsed by your code if needed.

You also need to add a RenderForm method that receives 3 parameters.

  • body - the element that contains the settings form.
  • settings - the settings object containing the currently set values.
  • easyadd - a method reference for creating a simple text input field for the property.

So you can easily add a text input using the easyadd method, or add your own input using jQuery. When adding your own input, you need to know that the name property of the input needs to be the same as the property in the settings. When choosing Apply the value is automatically set using the name property of the field and reading the value of the field. When a checkbox or radio(button) is used, it also looks at the checked state. Multiple checkboxes with the same name are not supported.

When using the easyadd method, you need to supply three parameters:

  • property - the name of the property in text.
  • label - the label shown about the textfield (: is already set behind this label)
  • current value - the current value of this setting

That is it, with knowledge of JavaScript, jQuery and probably some SharePoint JSOM, you should now be able to create ScriptParts.