-
Notifications
You must be signed in to change notification settings - Fork 17
Lifecycle on client side
This section discusses the lifecycle in the browser. It is intended to assist those who wish to author javascript modules that integrate with WComponents in the browser. It focuses on the key topics of running a script when the "page" is "ready".
The module wc/dom/initialise
allows you to register a script that will run when the document is "ready". There are many benefits to using this module instead of directly listening to the load
(or similar) event.
wc/dom/initialise
allows you to register a callback function which is:
- guaranteed to be called
- as soon as the document becomes "ready"
- any time after the document is ready if you register late, for example when a script is fetched asynchronously via a module loader like requirejs
- guaranteed to be called only once
- you could re-register and it will be executed in the "future"
- you could even re-register from within your registered callback - this will queue a future iteration.
The wc/dom/initialise
module allows you to register callbacks which will be called at three different stages and passed the document.body
element:
-
preInit
called early, before WComponents client side modules have done their main initialisation. -
initialise
the main initialisation stage, this is intended for hooking up event listeners and interacting with the DOM. -
postInit
called after the main initialisation stage postInit is what we would expect most custom scripts to use
To register with any of these phases call the register
method on the wc/dom/initialise
module with an object that has methods corresponding to the phases you wish to use. For example:
/**
* Demonstrates registering on all three phases.
* Will log:
Phase: preInit BODY
Phase: initialise BODY
Phase: postInit BODY
* You can choose any combination.
*/
require(["wc/dom/initialise"], function(initialise) {
initialise.register({
initialise: function(element) {
console.log("Phase: initialise " + element.tagName);
},
preInit: function(element) {
console.log("Phase: preInit " + element.tagName);
},
postInit: function(element) {
console.log("Phase: postInit " + element.tagName);
}
});
});
Advanced Tip: the lifecycle can be paused by returning a thenable
(e.g. a Promise) from your callback. The current phase will not end until all returned thenables
have been resolved.
For example the i18n module returns a promise in preInit
to pause the lifecycle until it has loaded its translation bundle.
Posting user input back to the server may occur via full page round trip (form submit) or XHR (AJAX POST).
The module wc/dom/formUpdateManager
is responsible for orchestrating state writing of any arbitrary state that needs to be included when posting back to the server.
Submittable HTML form components require no scripting to have their state included when posting back to the server, these will be automatically included either:
- natively, by the browser, on page round trip; or
- by
wc/dom/formUpdateManager
on AJAX post
<form name="myform">
<!-- The value of the native input "mynativeinput" will automatically be posted back to the server -->
<input type="checkbox" name="mynativeinput" value="abc123" checked="checked"/>
</form>
Note: because we rely on native serialization you need to understand the rules of form serialization, for example the state of disabled form components is not included in the post.
WComponents ensures that ARIA widgets post their values back to the server with no additional scripting. This is handled by the module wc/dom/ariaAnalog
and it's subclasses (for example wc/ui/checkboxAnalog
). There are some basic conventions that must be adhered to:
-
data-wc-name
attribute is used as the component name -
data-wc-value
attribute is used as the component value (unless a specific ARIA value attribute makes more sense)
<form name="myform">
<!-- The value of the the ARIA widget "myariainput"
will automatically be posted back to the server -->
<span role="checkbox" data-wc-name="myariainput"
data-wc-value="abc123" aria-checked="true" />
</form>
If you create a custom widget that needs to write state you should not explicitly listen to submit events and AJAX posts.
Instead you should subscribe to wc/dom/formUpdateManager
.
The wc/dom/formUpdateManager
module API includes a subscribe
method which takes either a function or an object with a writeState
method.
The subscriber will be notified when state needs to be written and posted back to the server. It will be passed two DOM elements, the HTML form being posted and a "state container" which is where you are expected to write your custom state as Submittable HTML form components (typically hidden inputs).
The easiest way to write these state fields is to use the writeStateField
method provided by the wc/dom/formUpdateManager
module.
A code snippet is worth a thousand lines of documentation:
/**
* Will send "mycustomwidget=abc123" any time the form is posted
* to the server via a page submit or AJAX.
*/
require(["wc/dom/formUpdateManager"],
function(formUpdateManager) {
formUpdateManager.subscribe(function(form, stateContainer) {
var paramName = "mycustomwidget",
paramValue = "abc123";
formUpdateManager.writeStateField(stateContainer,
paramName, paramValue);
});
});