JS - GreenImp/bill-bootstrap GitHub Wiki
File structure
The Javascript libraries are organised in much the same way as the CSS. All of the JS files are stored under
/src/assets/js/
In the directory is the bill.js file, which (like our scss files) simply includes the required files.
The actual base Bill object (which handles all functionality) is stored in base/base.js, along with basic.js, which contains some default required functionality.
All of the libraries are stored in their own files, inside the libraries/ directory.
Likewise, extensions are stored in the extensions/ directory.
File structure:
/src/assets/js/
bill.js
base/
base.js
basic.js
extensions/
{extensions}
libraries/
base/
{base_libraries - such as browserNotice and cookieNotice}
ui/
{ui_libraries}
Before modifying/adding libraries/extensions/etc you need a basic understanding of Javascript objects. I suggest the following two articles;
Embedding JS
To embed/include one JS file in another, you use @depend (Must be inside of a comment):
#!javascript
/* @depend {filename} */
Where {filename} is the path and filename, relative to the current file. You can see some good examples in bill.js
Library vs. extension
Libraries and extensions are very similar; they're formatted in the same way and share a lot of the same base variables, but they are uniquely different.
Libraries are used for things that will mainly affect the DOM or enable GUI elements, whereas extensions are predominantly helper functions or functionality that doesn't provide large amounts of front-end visible changes.
Some good examples are the modal library, which enables the displaying of content in a modal dialogue.
This is a user interactive interface and provides functionality that the end user is very aware of. It also modifies DOM elements in a visual way.
The querystring extension, however, doesn't provide any sort of graphical elements or modify the DOM in any way. It simply provides a helper for other libraries to use. It's function is solely to return query string data.
Building for Bill
Library
All libraries must have a unique name and handle. If you're creating a new library, try to think of a relevant name (Like 'accordion' for the accordion element)
All libraries must be part of the Bill.libs object, declared like so:
#!javascript
Bill.libs.accordion = {}; // declares a library with the handle 'accordion'
As you can see, libraries are objects.
There are a few required variables and functions that each library must declare:
- Variables
name: Human readable name for the library (should be unique)version: Library version number (this is different from Bill's version number)nameSpace: used for event handlers (must be unique)
- Functions
-
init(scope, method, options)This function is called when the library is initialisedscope: The current document scopemethod: Method called by useroptions: user defined optionsIf no method is defined, the
methodargument could contain the options instead andoptionswill beundefined -
on()This function is called to enable the plugin (usually after it has been disabled byoff()) -
off()Disables the plugin
-
Example
An example base library is below:
#!javascript
Bill.libs.accordion = {
name:'Accordion',
version:'0.1.0',
nameSpace:Bill.eventNameSpace + '.accordion', // the namespace is built up using Bill's default namespace, then appening our libraries own
init:function(scope, method, options){
// store the scope in the library object, for referencing later
this.scope = scope || this.scope;
// check whether a method has been specified or if it contains options
if(typeof method === 'object'){
// method is actually options
$.extend(true, this.options, method);
}else if(typeof method === 'string'){
// method has been defined - call it and return
return this[method].call(this, options);
}
// if we're here, then no method was called.
// we should initialise the library and usually call the `on()` function
},
/**
* Activates the plugin
*/
on:function(){
// enable the plugin - this usually consists of enable event handlers
// here we are binding a click handler to the scope (usually `document`).
// the click handler has a namespace, so it is unique to the library.
// It is a 'live' event on elements that have the `data-accordion` attribute.
$(this.scope).on('click' + this.nameSpace, '[data-accordion]', function(e){
// do something here...
});
},
/**
* De-activates the plugin
*/
off:function(){
// disable the plugin - this is usually disabling the event handlers
// unbind all event handlers on the scope, that have our libraries namespace
$(this.scope).off(this.nameSpace);
}
};
Extension
Extensions are very similar to Libraries. They must also have a unique name and handle. If you're creating a new extension, try to think of a relevant name (Like 'querystring' for the querystring handler extension)
All extensions must be part of the Bill.exts object, declared like so:
#!javascript
Bill.exts.querystring = {}; // declares a library with the handle 'querystring'
Like libraries, extensions are objects.
There are a few required variables and functions that each extension must declare:
- Variables
name: Human readable name for the extension (should be unique)version: Extension version number (this is different from Bill's version number)
- Functions
-
init()This function is called when the extension is calledThink of it as your extension function, when called it will be passed any arguments that the user passes it.
Unlike libraries, the arguments are completely customisable, to the individual extension's requirements; just like you would in a normal JS class.
-
Example
An example base extension is below:
#!javascript
Bill.exts.querystring = {
name:'Querystring',
version:'0.1.0',
// the querystring extension takes a single argument `name`
init:function(name){
// do something here.
// We can do anything here - alter the DOM, do AJAX requests, return values
// return a value (assuming that `val` is defined above
return val;
}
};
You would call the extension like so:
#!javascript
Bill.extension('querystring', 'foo')
Where 'foo' is the value of the name argument.