Skip to content

Commit

Permalink
Merge pull request #7224 from alphagov/update-js-docs
Browse files Browse the repository at this point in the history
Adds new JavaScript Documentation and standards
  • Loading branch information
DilwoarH committed Jan 12, 2023
2 parents a77a0ea + 18bb29c commit ec3c6a0
Show file tree
Hide file tree
Showing 8 changed files with 82 additions and 29 deletions.
11 changes: 6 additions & 5 deletions app/assets/javascripts/application.js
Expand Up @@ -12,10 +12,11 @@
//= require admin/analytics

//= require admin/modules/app-analytics
//= require admin/modules/edition-form
//= require admin/modules/locale-switcher
//= require admin/modules/navbar-toggle
//= require admin/modules/paste-html-to-govspeak
//= require admin/modules/unpublish-display-conditions
//= require admin/modules/unpublish-tracking
//= require admin/modules/track-selected-taxons

//= require admin/views/edition-form
//= require admin/views/locale-switcher
//= require admin/views/track-selected-taxons
//= require admin/views/unpublish-display-conditions
//= require admin/views/unpublish-tracking
49 changes: 25 additions & 24 deletions docs/javascript.md
Expand Up @@ -7,42 +7,43 @@ Should be read in conjunction with the [GDS Way JS styleguide](https://gds-way.c
Each JavaScript object should be stored in its own file with a filename reflecting the object name. In the spirit of keeping things similar to the CSS, they should be stored in:

```
./helpers/
./frontend/views/
./frontend/modules/
./frontend/helpers/
./admin/views/
./admin/modules/
./admin/helpers/
./admin/views/
```

__Views__ are view-specific scripts and as with the css, their file path and name should exactly mirror the view template or partial it applies to. The name of the script object should reflect the whole view path (the object in `/admin/editions/index.js` should be called `GOVUK.adminEditionsIndex`).

__Modules__ are re-useable things. An example of a module would be the script for a tabbed content block. Modules should not be initialised globally, and should only be initialised when needed, by the layout / partial which needs it (see script initialisation). If a script is only ever going to be used in one place, don't make it a module.
## Modules

__Helpers__ are scripts which are loaded everywhere (such as the script which prevents forms from being submitted twice).
Modules are re-useable things. An example of a module would be the script for a tabbed content block. Modules should not be initialised globally, and should only be initialised when needed, by the layout / partial which needs it. They should be initalised using data attributes, for example:

Namespaces should be kept simple and all constructors should be under `GOVUK`. The JavaScript layer is thin for whitehall and so (at least at present) there's no need to use deeper namespaces.

## Script initialisation
```html
<div data-module="your-module-name"></div>
```

Scripts should be initialised with `GOVUK.init`:
Modules should be written in the following format:

```js
GOVUK.init(GOVUK.SomeScript, { el: '.js-the-thing' })
```

If the passed in object is a constructor, `GOVUK.init` creates an instance of the passed in constructor, passing the second argument through as an argument. A reference to the new instance is stored in `GOVUK.instances`.
window.GOVUK = window.GOVUK || {};
window.GOVUK.Modules = window.GOVUK.Modules || {};

Otherwise, `GOVUK.init` will call init on the passed in hash, treating it as a singleton.
(function (Modules) {
function YourModuleName(module) {
this.module = module;
}

Scripts should only be initialised when needed and should make use of the rails helper `initialise_script`:
YourModuleName.prototype.init = function () {
// code here
};

Modules.YourModuleName = YourModuleName;
})(window.GOVUK.Modules);
```
<% initialise_script "GOVUK.SomeView", el: '.js-some-view' %>
```

This rails helper takes a ruby hash as a second argument, which is jsonified and passed down to the javascript constructor (in content\_for block `:javascript_initialisers`). This is not done in `$.ready` by default, so if the script needs to wait for $.ready, it should do so itself.
Modules names are written with a [kebab case](https://en.wikipedia.org/wiki/Letter_case#Kebab_case) in the `data-module` attribute. However, they are [camel case](https://en.wikipedia.org/wiki/Camel_case) in the JavaScript files.

Modules are automatically initalised by the GOVUK Publishing component scripts on load.

## Views

This initialise\_script line should be in the most appropriate template/partial for view scripts / view-specific helpers, and should be near the `:javascript_initialisers` yield in the applicable layout for site-wide helpers.
Views are view-specific scripts and as with the css, their file path and name should exactly mirror the view template or partial it applies to.

They should initalise using the same way as modules. This will maintain consistency and not require a new method of initialising scripts.
51 changes: 51 additions & 0 deletions docs/legacy_javascript.md
@@ -0,0 +1,51 @@
# Deprecated: Whitehall Legacy JavaScript

Should be read in conjunction with the [GDS Way JS styleguide](https://gds-way.cloudapps.digital/manuals/programming-languages/js.html)

## Note

Please note that this documentation is now deprecated and will be removed with the legacy JS files once the migration has been completed.

## File structure and namespacing

Each JavaScript object should be stored in its own file with a filename reflecting the object name. In the spirit of keeping things similar to the CSS, they should be stored in:

```
./helpers/
./frontend/views/
./frontend/modules/
./frontend/helpers/
./admin_legacy/views/
./admin_legacy/modules/
./admin_legacy/helpers/
```

**Views** are view-specific scripts and as with the css, their file path and name should exactly mirror the view template or partial it applies to. The name of the script object should reflect the whole view path (the object in `/admin_legacy/editions/index.js` should be called `GOVUK.adminEditionsIndex`).

**Modules** are re-useable things. An example of a module would be the script for a tabbed content block. Modules should not be initialised globally, and should only be initialised when needed, by the layout / partial which needs it (see script initialisation). If a script is only ever going to be used in one place, don't make it a module.

**Helpers** are scripts which are loaded everywhere (such as the script which prevents forms from being submitted twice).

Namespaces should be kept simple and all constructors should be under `GOVUK`. The JavaScript layer is thin for whitehall and so (at least at present) there's no need to use deeper namespaces.

## Script initialisation

Scripts should be initialised with `GOVUK.init`:

```js
GOVUK.init(GOVUK.SomeScript, { el: ".js-the-thing" });
```

If the passed in object is a constructor, `GOVUK.init` creates an instance of the passed in constructor, passing the second argument through as an argument. A reference to the new instance is stored in `GOVUK.instances`.

Otherwise, `GOVUK.init` will call init on the passed in hash, treating it as a singleton.

Scripts should only be initialised when needed and should make use of the rails helper `initialise_script`:

```
<% initialise_script "GOVUK.SomeView", el: '.js-some-view' %>
```

This rails helper takes a ruby hash as a second argument, which is jsonified and passed down to the javascript constructor (in content_for block `:javascript_initialisers`). This is not done in `$.ready` by default, so if the script needs to wait for $.ready, it should do so itself.

This initialise_script line should be in the most appropriate template/partial for view scripts / view-specific helpers, and should be near the `:javascript_initialisers` yield in the applicable layout for site-wide helpers.

0 comments on commit ec3c6a0

Please sign in to comment.