Note (added July 29, 2016) — for the sake of clarity, this tutorial assumes that the library you want to add is not AMD compatible. If it is AMD compatible then you do not need to follow this tutorial; instead, you can simply add it like you would any other module of code: directory structure, ns.package.json, update distro.json, etc.
For the purposes of this tutorial I have the use case of wanting to add a field to the Profile Information page to capture the customer's preferred delivery time for any orders they place. I have found a jQuery plugin called ClockPicker that provides a neat interface for selecting a time. For the sake of brevity, I'm not going to include the steps for storing the data on the backend as that is out of the scope of the article.
What if you're adding a JS library that isn't a jQuery plugin? At the bottom of this article, I've added additional information about this.
Once you've found the library you want to add, you will need to create a module folder for it. Like all site-specific customizations, we recommend that you put them in the folder under Modules where you keep your site's customizations. When naming it, it's good to use the name of the library as the folder name and the version of the library as the version number. So, for me, I'm creating a folder called firstname.lastname@example.org.
_) in front of the file name. Keep in mind that CSS is still valid Sass, so this isn't an issue, just a nuance of the compiler. Finally, the folder needs a ns.package.json file so that Gulp picks it up; thus the final list of files is simply:
Then you just need to put the right things in your ns.package.json file, e.g.:
The only thing in here that you may not have seen with other modules is the
You may ask why we haven't replicated the folder structure common to the other modules, this is mainly because the jQuery library only has two files that we want to use. We could also modify the source code so that it is in the AMD format, but the flexibility of this method means that we don't have to. One side-effect of this, however, is that we'll have to make some unconventional modifications to our distro.json file.
First things first: you need to register your module like you would any other module at the top. This is pretty standard, I'm just adding in
"custom/jquery-clockpicker": "0.0.7" to mine.
After that, I need to register the module's Sass as a dependency in the Sass task for each application. If you wish, you may just register them only with the applications you plan to use the library with, but if your aim is to make it available globally then it's simple to register it with them all.
In total, if I add in lines for each application, my new module will be mentioned seven times in distro.json file:
- Once, at the top, in the
- Once for each application when configuring
- Once for each application when registering the Sass.
Save the file!
View and Template
Once I've done that, I'm going to edit Profile.Information.View.js and add
jquery-clockpicker as a dependency but I'm not going to add it as a parameter to the function. Why? This is because it is a jQuery plugin and we have shimmed it into jQuery (i.e., augmented jQuery with the plugin); seeing as
jQuery has already been added as a parameter, we do not need to add anything more.
initialize function in the view we need to add something like:
var self = this;
The code within the function is the stuff ClockPicker needs, but it is the wrapper that is most important. First, the variable allows us to keep the context of the object we're instantiating, which is the view. Secondly, the
After saving the view, the only thing left to do is to modify the template. Obviously, this part is specific to the library that you're using and there no special tips other than to read their documentation and make sure you include the appropriate data elements, classes, IDs, or any other code that is required for the library to work. I've included the code below, for reference:
<div class="profile-information-row clockpicker" data-placement="top" data-input="clockpicker">
<label class="profile-information-label" for="clockpicker">Preferred Delivery Time</label>
<input type="text" class="profile-information-input-large form-control" value="09:30" name="clockpicker">
Note how I'm able to use my own classes and structure, just so long as I include the
clockpicker class. Make sure with your choice of library that you include all the relevant parts. A good way to start is to include just the bare minimum to get the JS to work, and then build it out from there.
Test Your Code
After of all this, you will need to stop your local server (if it is already running) and start it again. When you visit the page where your library is called, you should see the changes you made take effect. If you don't, check the console and perform some diagnostics (see 5 Ways to Troubleshoot SCA in the Browser for some tips). Here's what my page looks like:
So what I've written in the tutorial is clearly not enough to implement the functionality — it's missing the entire backend. But, what we have seen is how easy it is to include a jQuery plugin. It starts similarly to other modules: you create the directory for it in your customizations directory and then add in the files, along with a ns.package.json. Then we covered the nuances of updating the distro.json file for jQuery plugins, namely using shims. Finally we updated the view to include our jQuery plugin and use
afterViewRender event to run some code when the view has finished rendering.
You should be able to adapt this article's method for your own third-party JS — not just jQuery plugins but all third-party libraries. For additional help, check out what we've done with the third-party JS that we've included in the SCA product and try to replicate it.
Notes on non-jQuery JS Libraries
OK, so you've got a JS library that isn't powered by jQuery — what do you do? The method for adding it is a combination of the above steps and the steps to adding any other module to your site.
The first thing you need to do is get the files, create your folder structure, and create the ns.package.json file as normal.
Then, when updating your distro.json file, you need to do this like you normally would for a new module. Put a line in the modules object for the location of your module.
Now, if your JS library is AMD-compatible then you can add as a you would normally add any new custom module. If it's not, then you then need to find the section for the application JS that you want to add it to and add it as an entry to amdConfig > paths. As a key-value pair, this should be
"[name you want to call it]": "[name of the JS file]". Note the conventions used for the other JS files, namely that you do not include the file extension (.js) in the value of the pair. So, for example, if my module is called SuperGreatLibrary, which contains a minified JS file in it called SuperGreatLibrary-1.0.2.min.js then I would add the following to paths:
For adding any CSS, you can follow the normal steps for adding a custom module.
After saving and recompiling your code, you can now use your third-party JS library like you would any other module — find the module file that you want to use it in and add it is a dependency. If, however, you want to use it 'globally' then you will need to override a module with a wider scope and include it in that.
So, for example, if you want to have it available throughout your My Account application, override SC.MyAccount.js in MyAccountApplication and add it as a dependency there. Just pay attention, though, to the list of dependencies in the
define statement and include it in the right place. In some files (including SC.MyAccount.js) the
define statement will register some modules as dependencies but does not give them names; thus, if you were to add your JS library to the end of the statement, you would encounter an error as the ordering is wrong.