## Principles

JavaScript is truy an awesome language. But if not maintained and structured
correctly, it can be become very unreadable and difficult to manage of debug.

### DRY (Don't Repeat Yourself)

This is a basic principle within software development. It is aimed at reducing
repetition of information. This basically means don't type the same
functionality twice. This does not mean you never type the same code twice, it
means that you should not define the same functionality of code blocks twice.

If not upheld, it will become difficult to manage the code if the logic changes.
We have to make changes all over the place where we have "copied" or written the
same code blocks. This is a waste of time!

To avoid having this problem you have to divide your system into pieces. Divide
code and logic into smaller reusable units and use that code by calling it
wherever you want. Avoid writing lengthy methods, but try to re-use existing
pieces. This is very difficult and requires some thinking and preparation. If
not managed correctly the consequences can be very severe (drama alert!).

The benefits are:

* Reduces chances of bugs
* Saves time and effort
* Easy to maintain

### KISS (Keep it simple, stupid)

Keep the code simple and clear! The code is for humans to understand, so keep
it straightforward. Keep methods small and divide your code into multiple files.
Each method should solve one small problem. If you have a lot of conditions in
one method, break these out into smaller methods. It is easier to read, maintain
but can also help you find bugs faster than the speed of light.

Before writing the actual code, think of many solutions for your problem. Then
choose the simplest one. Whenever you find yourself writing lengthy code, stop
for a second, rethink your life and divide it into smaller parts. Refactor all
the time, don't be lazy, but iterate onto your code and don't write hacks to
make it all work. If this is done correctly it will be easy to read and modify
the code without writing iterative if-statements and creating this lovely
pyramide effect in your code editor (😤).

This kind of affects the DRY principle as well, when do you split up and when is
the code getting to complex. Find a balance yourself between these two iterating
on them and improving your own code.

### Class based

JavaScript does not have a pattern you have to follow to create code. This is
decided by the developers themselves. You can for example either write function
based or class based JavaScript. In the brandplatform it is prefered to use
class based JavaScript because it is easier to initiate different components
and their respective functionality. Each component has their own properties and
methods, these are not possible to easily define through the use of only
functions.

For example, if you have a component that should toggle collapsing content when
clicking a button. You should keep in mind here that there can be multiple
instances of the same component. Class based JavaScript is very handy here
because we need to define an EventListener to catch the click on the button and
we need a boolean represeting the state of the collapsed content. If this is
done through functions we would always have to retrieve the state from the
document model and that would make the JavaScript unmanagable and dirty.

### Dependencies

For the brandplatform we tend to always avoid the use of dependencies because
they can make things difficult for third parties. Third party scripts or
libraries can be handy for components that are quite complex and appear in
almost every design: I'm talking about a carousel or a datepicker. Keep the
amount of dependencies as limited as possible. Do not use any library because of
just one of its many features. Just one more thing: AVOID JQUERY AT ALL COSTS.

## Structure

A modular, strict and clear JavaScript structure is very important. This can, by
default, be found in the `src/js` directory. If you want this in a different
folder, this can be done by updateing the configuration of the project.

Because there is no framework or no crazy library that does stuff behind the
scenes we write the JavaScript ourselves and tried to create a folder structure
based on our practices within this type of project.

The JavaScript structure is divided into:

* **constants**: Folder containing the global variables that should be used
across the different modules.
* **extends**: Folder containing extendable classes. These are classes that
contain functionality that is reusable across certain modules.
* **managers**: Folder containing singletons. Classes that can be initialised
only once. These have a single taks and make sure that the modules can for
example communicate between each other.
* **modules**: Folder containing the components. Each module is another folder
containing an entry point (index.js) and different parts to make the module
work.
* **utils**: Folder containing reusable and small functions that always return
something. These can be used in the different folders within the JavaScript
structure to execute certain small and repeatable tasks.
* **vendors**: Folder containing minified files or any other third party script
to make a module work. This can be a carousel, datepicker, ...
* **main.js**: The main JavaScript file where everything comes together. This
should only contain initialisers for the modules and should not contain any
logic.

## Modules

### Initialise

When creating a module there are some rules to follow to make sure a decent
structure is upheld.

The module is a class and should be called and initialised in the main
JavaScript file:

```js
"use strict";

/**
 * Import
 * =============================================================================
 */
import { Example } from "./modules";

/**
 * Init
 * =============================================================================
 */
const init = () => {
	const example = new Example(document.querySelector(".js-example"));
};

init();
```

As you can see in the above declaration we simply initialise the respective
class and pass it the element necessary to make the module work by itself. This
is a nice pattern, because this way you can select other dom elements within
this querySelector and you don't have to look through the entire document
structure.

### Definition

Now, where is this Example class placed? Each module should be placed within its
own folder in the modules folder. As an entry point the module has an index.js
file:

```js
"use strict";

/**
 * Imports
 * =============================================================================
 */

// import ... from "./";

/**
 * Class
 * =============================================================================
 */
class Example {

	/* ====================================================================== *
	 * Constructor
	 * ====================================================================== */
	constructor(el) {
		this.el = el;

		this.initBinds();
		this.init();
		this.initEvents();
	}

	/* ====================================================================== *
	 * Inits
	 * ====================================================================== */
	init() {}

	initBinds() {}

	initEvents() {}

	/* ====================================================================== *
	 * Helpers
	 * ====================================================================== */

	/* ====================================================================== *
	 * Handlers
	 * ====================================================================== */
}

export default Example;
```

As you can see in the example above we like to divide JavaScript methods in
different groups because that way we define what they are supposed to do. We
have 3 different types:

* **Initialisers**: Once the constructor is executed we start the initialisers.
These are methods that can either return something or create something. These
are only executed once. In naming these methods we always prefix them with
**init**.
* **Helpers**: Helpers are methods that always return a value. They change or
manipulate the value. These can be seen as utils as well, but they are more
defined within their respective class-scope. They belong to that component and
are specifically made to work with that component. In naming these methods we
prefix them with either **set** or **get**.
* **Handlers**: Handlers are methods that execute something or handle the
aftermath of an action. These can be more complex than the previous types and
can do anything they want. In most cases they never really return something,
they simply one thing. The naming of these methods is prefixed with **handle**.

### Expanding

Now the module can be defined. Do take note that you should divide your HTML
elements into a multitude of classes that all do their own thing within that
same module. For example: You have a collapsable component that should animate
the content height when clicking on the button. This means that you have a
module **Collapse** with its own **index.js** file. You can have another file
for the button **Button.js** and the content **Content.js**. The Button.js will
contain the eventlistener and the callback to the index.js to trigger the
Content.js animation and behaviour.

Here is a little metaphor to hopefully make it a bit more clear:

The way we see it is that the index.js is the actual brain of the module. Button
and Content are limbs that are created from that brain. Button and Content do
not directly communicate with each other. But they do communicate by sending out
signals (callbacks) to the brain and the brain catches these signals and will
send out another signal to its different limbs. So Button and Content only
communicate indirectly with each other through the brain. It is the brain that
decides which limbs should receive a signal and respond to the action, derived
from the Button.

### Conclusion

These are some tips we have when writing JavaScript for manipulating the DOM.
The developer is the one who decides how the structure is defined but try to
keep it consistent, maintained and clean.

A wise man once said:

**Always code like the developer coming after you is a dangerous psychopath that
knows where your family lives**
