An extendable class for Web Elements, modules and components
This library allows you standardize each module-like Element throughout your single-page web application. A module can essentially be anything, but it usually represents an independent component (like a modal, or a carousel for example).
The idea behind this library is to provide a common interface between all the modules you may want to use on your site. Which all means less code, less work, and less things to unit test.
Each module that you have on your site/app will generally be tied to an HTML/DOM element on the page, which you pass to the Module class to create an instance. Then you'll have access to all the helpful methods below. For our example, we'll use an element that represents our modal container (assuming there is already an element in the DOM with the id of "modal-container").
let modalContainer = documentgetElementById'modal-container';let modalModule = modalContainerstyles: ''template: ''data: ''loadedClass: 'modal-loaded';
Once your instance is created, you can call the built-in methods on it. For instance, calling load()
on the Modal instance (demonstrated below) will load module along with its template, styles, and even fetch the module's data using the
options we've specified above. Once loaded, it will also add the
loadedClass specified to the module's
// load the modulemodalInstanceload;
NOTE: since a handlebars file was used as the
template option above, calling
load will inject the data JSON response
from the `data`` url specified into the handlebars file.
Out of the box, the Module class will provide a few helpful methods. But the real power comes when you begin to have your components extend it with their own custom implementations. From there, you can override the default abstract methods to add logic that is custom to each specific module. Here is an example of how to create a Modal class that extends the module class and has custom loading functionality.
class MyCustomModule extends Moduleload// do some custom stuff before loadreturn superloadthen =>// do some custom stuff after load;
As you can see above, you can overridethe load method of the parent Module class and call it whenever you want. We recommend
that you call the Module class's method via
super when overriding any of the methods to ensure you get all internal functionality.
When instantiating a module, you can pass it options:
let modalContainer = documentgetElementById'modal-container';let modalModule = modalContainerstyles: ''template: ''data: ''loadedClass: 'modal-loaded'activeClass: 'modal-shown'disabledClass: 'modal-disabled'errorClass: 'modal-has-error';
||Array/String||Array of stylesheet urls to be loaded (or single url string)|
||Object/String||The url to the data or the data object that should be loaded into the module's
||Object||The set of request options that will be passed to the fetch call when fetching data|
||String||The CSS class that will be applied to the module element when it is loaded|
||String||The CSS class that will be applied to the module element when it is shown|
||String||The CSS class that will be applied to the module element when it is disabled|
||String||The CSS class that will be applied to the module when error occurs|
||Function||A function that fires when module is loaded|
||Function||A function that fires when module is shown|
||Function||A function that fires when module is hidden|
||Function||A function that fires when module is enabled|
||Function||A function that fires when module is disabled|
Your module will get some useful methods whenever an instance of it is created.
Your module instance will have a .load() method when it is instantiated. When called, it will load all templates, styles,
and data passed into the options above, apply your module's
loadedClass and, when done, will call
onLoad callback option (if specified).
You can also do some custom load handling tasks. Below you can see how a Carousel class can be created that loads some assets asynchronously when the load() method is called.
class Carousel extends Moduleload// code that loads carousel images asynchronously here// and return a promise when donereturn superload;;let carousel = ;// trigger carousel loadcarouselload;
You can call the
waitForTransition method to wait until your Module finishes its transition before doing other
var modal = documentgetElementByTagName'div'0;modalclassListadd'animate'; // start transitionmodalwaitForTransitionthen =>// 100 milliseconds later...console.log'transition complete!';;
The show() method can be called when you want to set your module to its "active" state. It adds the css
activeClass to your Module element. If you have css that transitions your element when the
activeClass is applied,
you can utilize the returned promise to wait until after the element has transitioned.
let myModule = documentgetElementById'my-module';myModuleshowthen// module has finished animating into its active state!
The hide() method can be called when you want to set your module to its "inactive" state, which essentially just removes
activeClass. If there any css transitions that take place when the
activeClass is removed, you can use the promise
it returns to wait until the animation completes.
let myModule = documentgetElementById'my-module';myModulehidethen// module has finished animating into its inactive state!
A method that fetches the data for the Module using the API url supplied as the
let mod = documentgetElementById'my-module'data: 'path/to/mydata';modfetchDatathen// data has been fetched
Loads the css stylesheets supplied via the
let mod = documentgetElementById'my-module'styles: 'path/to/my/style.css' 'path/to/my/second/style.css';modgetStylesthen// styles have been loaded into the head of the current document
Loads the template supplied via the
Supports .html and Handlebars (.hbs) files.
let mod = documentgetElementById'my-module'template: 'path/to/template.hbs';// you can optionally pass data to be injected into the templatelet data = my: 'value';modgetTemplatedatathen// the data has been injected in returned html stringthiseltextContent = html;
Traverses upwards from the
target until finding an ancestor element with the
target is optional and, if not passed, the Module instance
el is used.
The disable() method can be called to add the css
disabledClass to your Module element and set your module to a state
in which it can no longer be interacted with.
let myModule = documentgetElementById'my-module';myModuledisable;
The enable() method does the opposite of the
disable() method above, removing the
disabledClass from your Module element.
let myModule = documentgetElementById'my-module';myModuleenable;
The error() method can be called when you want to manually trigger an error in your module, which adds the
to your Module element.
NOTE: the error() method is called automatically when the load() call on your module fails.
let myModule = documentgetElementById'my-module';myModule.error;
Each module instance provides a
subModules object to which you can attach additional modules that have extended the
Module class. So when
destroy() is called on the parent module, the same methods will be executed for all
subModules you've specified, saving you from having to call methods on all of the
subModules directly. Take
a look at the example below.
class MyCustomModule extends Moduleconstructor// calling super gives you access to the subModules objectsuper;thissubModulesmyModuleId = ;thissubModulesmyModuleId2 = ;thissubModulesmyModuleId3 = ;;let customMod = ;// destroy parent module, which will// call destroy on all submodulescustomModdestroy;