taeluf / js.autowire
Javascript Library: Autowire
Requires (Dev)
- taeluf/cli: v0.1.x-dev
- taeluf/code-scrawl: v0.8.x-dev
- taeluf/liaison: v0.6.x-dev
This package is auto-updated.
Last update: 2024-10-04 01:47:32 UTC
README
Autowire
Link javascript classes with DOM nodes and make everything communicate seamlessly with one another. Extensible.
Status: Stable, unpolished
Autowire is stable, but it is not polished. I have used it in production for quite awhile. mtgpaper.me is a good example. It's not "open-source" but you can just look at the javascript source files anyway, as they are not minified or obfuscated currently (Apr 11, 20222).
Issues:
- there are no proper tests, runnable from cli
- documentation could be better
- i have not documented the BindParam extension.
- API could be better
- its not on npm or anything
Future Plans
See Status.md ... I don't have explicit plans to develop this further, but i may get around to it one day. It basically does what i need so ...
Install
Copy code/Autowire.js
into your project & include it with:
<script src="/autowire.js"></script>
Usage
For a functional example, see test/docs/kanban/. You should be able to load test/docs/kanban/kanban.html into your browser
- Create a class, such as
class Item extends Autowire{}
. see sample class below. - Attach the class any of these ways
new Item(node, ...args)
Item.aw()
: shorthand forItem.autowire('.Item')
Item.autowire('.some-css-selector')
const instance = Item.fromTemplate('.query-selector')
where the selector can point to a<template>
& clone the inner html or a non-<template>
and will clone the node. If there are multiple direct children of the<template>
, then wraps all those nodes in a<div>
Sample Class
This is nearly everything autowire can do. I didn't include stuff about how onReady()
works or a couple other primarily internal things.
class Item extends Autowire {
/** generally, you shouldn't implement constructor */
constructor(node, ...args){
super(node,...args);
}
/** called from constructor after this.node is set
* @parma args are same as passed to new `Item(node, ...args);`
*/
onCreate(...args){
this.node.innerHtml = 'whatever';
}
/** called after:
* - event listeners are setup
* - this object is added to the object map
* - extensions are initialized
*/
onAttach(...args){
this.child_item = new \ChildItem(document.querySelector('.child-item'));
// change `this` to this class for any `on` events declared in html, such as `<button onclick="this.something()">` would now reference Item instead of the node
this.bindTo(this.node);
//this.bindToAll(node_list) will bind to a node list
}
/**
* called after all autowire objects are setup
*/
onReady(){
// get all child objects of this.node. this.ga() is a shorthand
const children = this.getAnyList('ChildItem');
// get one child object of this.node. this.g() is a shorthand
const child = this.getAny('Child');
const parentNode = document.querySelector('something.whatever');j
// get all items of class name that are children of parentNode. parentNode may be null
const object_list = Autowire.getObjectsFromName('ClassName', parentNode);
// get the Autowire instance attached to the given node
const object = Autowire.getObjectFromNode(parentNode);
}
/**
* called when this.node is clicked. Even listeners are added for any method starting with `on`
*
* async is not required, but makes it easy to `await this.fetchJson()`
*/
async onclick(event){
// this.fj() for shorthand
const new_data = await this.fetchJson('/data/',{"key":"value"}, "POST");
// this.ft() for shorthand
const new_text = await this.fetchText('/text/', {"key":"value"}, "GET");
const response_promise = await this.fetch(/*same params*/);
const other_text = response_promise.text(); //or .json() for json
}
}
// apply an extension
Item.aw();
class Alerter {
// called before onAttach() & after onCreate()
static onExtAttach(){
// `this` refers to the Autowire object being attached to
const node = this.node;
this.alert = function(msg){alert("ALERTED!!! "+msg);};
// basically just modify the node & the object however you want here ...
// such as Object.defineProperty() for ... idk, whatever
}
}
Autowire.expose('Alerter', Alerter);
// turn all Item instances into Alerters
Item.use(Alerter);
PHP Integration
Get the file path to Autowire.js or another js file in this repo & add it to the page.
<?php
$autowire_path = \Tlf\Js\Autowire::filePath();
$modal_path = \Tlf\Js\Autowire::filePath('Modal.js');
$bind_param_path = \Tlf\Js\Autowire::filePath('BindParam.js');
$dropdown_path = \Tlf\Js\Autowire::filePath('addon/Dropdown.js');