0.2.0 • Published 1 year ago

cattleprod v0.2.0

Weekly downloads
-
License
Apache-2.0
Repository
-
Last release
1 year ago

Cattleprod ##########

Cattleprod is a framework for declaritively adding javascript behavior to existing HTML. A special data-controller attribute tells controller to link an HTML element to a javascript class. Further data-* attributes link DOM events to methods in your class, and make HTML elements easily accessible to be manipulated from your javascript code.

Concepts

A javascript controller class is linked to an HTML element with a data-controller="myController" attribute in the HTML tag.

Actions link DOM events fired from within the controlled HTML element to named methods in the controller class. A data-myController-actions='{"click": "handleClickEvent"}' attribute adds an event listener to call the handleClickEvent method whenever a click event is triggered.

Targets are HTML elements that are mapped to instance variables of your controller class. A data-myController-target="myTarget" attribute makes a DOM element available to your class as this.myTarget.

Values are used to pass parameters to your controller class. A data-myController-values='{"foo": "bar"}' attribute creates a corresponding instance property, this.values.foo = "bar".

An Application object must be created to initialise your controllers and watch the DOM tree to dynamically add and remove controllers, actions, targets and values when HTML elements are created or removed.

Example

Markup your HTML to map elements to javascript controller classes::

<div data-controller="clickMe">
    <div data-clickMe-actions='{"click": "doClick"}'>
        Try clicking me!
        <div data-clickMe-target="message"></div>
    </div>
</div>

Then create a controller class and a cattleprod application::

<script type="module">
    import * as cattleprod from "cattleprod.js";
    class ClickMeController extends cattleprod.Controller {

        // This controller has a target called ``message``,
        // which corresponds to exactly 1 HTML element.
        static targets = {"message": "1"}

        doClick(event) {
            this.message.innerHTML = "You clicked me!";
        }
    }

    // Launch the application
    new cattleprod.Application({"clickMe": ClickMeController});
</script>

How-tos

How to pass options / parameters to a controller

Add a data-<ident>-values attribute to your controller's html tag::

<div data-controller="counter" data-messages-values='{"messageText": "Whoa nelly!"}'>...</div>

The controller must declare value names::

class ClickMeController extends cattleprod.Controller {

    static values = ["messageText"]

    doClick(event) {
        alert(this.values.messageText);
    }
}

How to look up a controller for an element

The controller for any element may be looked up from the Application instance, using application.getController(<element>, <ident>). This will return the controller attached to the given element, or the closest parent element if the element itself is not attached to a controller.

Reference

Controllers

Controllers must extend cattleprod.Controller. They may implement the following methods:

`connect()`

    Will be called whenever the Controller is attached to a DOM element.

`disconnect()`

    Will be called whenever the Controller is detached from a DOM element.

Application

The application object sets up controllers, then monitors the DOM for changes, dynamically connecting and disconnecting controllers as required.

The Application constructor takes a single object argument, mapping string identifiers to controller classes::

new cattleprod.Application({"clickMe": ClickMeController});

In addition, application instances have a debug attribute. If true, this enables debug log messages in the javascript console::

cattleprod.Application.debug = true;
const app = new cattleprod.Application(...);

Events

Events are bound from the DOM to the controller by using a data attribute::

data-<ident>-actions='{"<eventName>": "<methodName>(:<eventOption>)*"}'

This maps the named event to the named controller method.

Custom events

When a controller is attached to the DOM, a cattleprod:connected event is dispatched to the corresponding element.

Targets

A target is a labelled HTML element or elements, that cattleprod makes accessible to the controller class as an instance property.

Target names must be registered on the controller class using the static targets property::

class SearchController extends cattleprod.Controller {
    static targets = {
        "results": "1"
        "pagination": "+"
    };
}

The values associated with each target name are:

1 The target must match exactly one HTML element. The instance property will be a HTMLElement object

? The target may match zero or one HTML elements. The instance property will either be an HTMLElement object, or undefined.

* The target may match any number of HTML elements. The instance property will be an Array of HTMLElement objects.

+ The target may match one or more HTML elements. The instance property will be an Array of HTMLElement objects.

The markup can then define targets as so::

<div data-search-target="pagination">...</div>
<div data-search-target="results">...</div>
<div data-search-target="pagination">...</div>

Targets are accessed from the controller instance using the defined names::

…
static targets = {
    "results": "1"
    "pagination": "+"
};

showResults() {
    // this.esults is an HTMLElement
    this.results.classList.remove("loading");

    // this.pagination is an array of HTMLElement objects
    this.pagination.forEach(
        (n) => { ... }
    }
}

Actions

Actions link DOM events to a controller. The action must be configured in the markup using a data attribute containing a JSON mapping of <eventName>: <handlerMethod>::

<button data-search-actions='{"click": "refreshResults"}'>search</button>

Pass options to event listeners with::

<button data-search-actions='{"click": "refreshResults:passive:once:capture"}'>search</button>

This configuration will cause a click event listener to be registered on the button element, with the corresponding refreshResults instance method on the search controller registered as the handler. This will be called with a single event argument::

class SearchController {
    ...
    refreshResults(event) {
    }
}

Values

Values must be registered on the controller class using the static values property::

class SearchController extends cattleprod.Controller {
    static values = ["url"];
}

Values may be declared on the same tag that contains the data-controller attribute. Values should be declared in a data attribute named data-<ident>-values, containing a JSON object::

<div data-controller="search" data-search-values='{"url": "https://.../search"}'>

Data found in the JSON object will be copied into the controller instance's values property.

0.2.0

1 year ago

0.1.1

1 year ago

0.1.0

1 year ago