Script - Component Parts - Modulo Documentation

Custom vs Script Component Part - The general rule of thumb is that Script tags are for custom, component-specific behavior, or to fill in gaps in stitching together other Component Parts, while writing Custom Component Parts is for interfacing with async, APIs, or any time that a Script Component Part gets too cumbersome. Modulo's philosophy is to allow separation of work between component development (HTML, CSS, templating, and high-level behavior), and Component Part development (complex JavaScript and APIs).

Script

Script Component Parts allow you to define custom behavior for components using the full power of JavaScript. The most common use of Script tags is to add more sophisticated interactive behavior. Instead of just relying on premade Component Parts, with a Script tag you can program any custom behavior into your component.

Typical use

The most common use of a Script Component Part is to specify custom JS code. See below for a simple example:

Event callbacks

The most common purpose of a Script Component Part is to add custom behavior when certain "events" occur to your component. Consider the following example of 3 click events:

In this, the Script Component Part defines a function named countUp. The on.click= attribute on the button utilizes directives to attach a "click event" to the button, such that when a user clicks on that button it will invoke the countUp function.

From within event callbacks, the Script Component Part exposes the current renderObj as variables. So, state by itself is equivalent to renderObj.state. This enables us to directly modify the state by simply doing state.count++. By default, components rerender after every event, so after the event the component will rerender and visually reflect the state changes.

This means that all renderObj variables will be available here, in a similar way to how Template exposes them: For example, you can use code like props.XYZ to access data from a Props Component Part.

You can also access the JavaScript Object instances of the Component Part Class. To access those, you use the cparts

Finally, the variable element will refer to the HTML element of the current component. This is useful for direct DOM manipulation or interfacing with other frameworks or "vanilla" JavaScript. Generally, however, you should avoid direct DOM manipulation whenever you can, instead using a Template Component Part to render the component (otherwise, the Template will override whatever direct manipulation you do!).

DOM references

script.ref

Using script.ref, we can get easy access to DOM elements. See below for examples:

Example 1: Using script.ref to focus input
Example 2: Script.ref naming and drilling down

Using a suffix we can provide a custom name. For example, the directive script.ref.firstname becomes ref.firstname.

By specifying a value, we can "drill down" to properties of the element. For example, to access the built in style attribute, you can do script.ref=style.

Lifecycle callbacks

By naming functions with certain names, you can "hook into" the component rendering lifecycle with callbacks.

You can define a function with any of the following names and expect it to be invoked during it's namesake lifecycle phase: initializedCallback, mountCallback, prepareCallback, renderCallback, domCallback, reconcileCallback, and finally updateCallback.

See below for an example of defining a custom prepareCallback in order to "hook into" the component rendering lifecycle to execute custom code. The return value of this function is available to the Template Component Part when it renders during the render lifecycle.

Example 1: prepareCallback
Example 2: All callbacks

Template literals? The back-tick syntax is template literals.

Manual HTML creation with Script

Template vs renderCallback Before replacing a Template with a renderCallback, first consider using prepareCallback or extending the templating language with a custom filter. The Templating language is intentionally limited and result in more readable code and a cleaner separation of concerns of logic (JavaScript) from presentation (HTML templates).

You can use Script as a Template replacement, if necessary. For fine-grained control over a component's rendered HTML, you can hook into the renderCallback. While not recommended for most usage, it remains an option to use the renderCallback to write JS that constructs the HTML in a custom fashion, such as using a third party templating system, or simply using template literals.

For even greater control, you can simply replace the innerHTML of the entire element. This will skip any virtual DOM or reconciler. Thus, we don't have access to click events or binding, making many features less useful. Also note that we can't use "onkeyup" but instead use "onchange" -- using the built-in element.innerHTML causes the input to lose focus, otherwise. Nonetheless, it's still usable, and might be a useful example for fine-grained control.

See below for both examples:

Example 1: Script without Template
Example 2: Script without Virtual DOM