raziloBind - Binders for ES6 JS/HTML Binding Library
What is raziloBind?
ES6 JS/HTML binding library for creating dynamic web applications through HTML attribute binding. Made up of 4 libraries, puled in via a parent package that pulls in all required parts and configures as importable ES6 module 'RaziloBind'.
- razilobind-core (the main part), to traverse, detect and observe.
- razilobind-binder [injectables] (the actual binders), binding object properties to elements to do various things.
- razilobind-resolver [injectables] (to parse attribute data), resolving attribute data to things like strings, numbers, objects, methods etc.
- razilobind-alterer [injectables] (to change things), altering resolved data to something else without affecting the model.
This package razilobind-core, is the base functionality that binds, observes, traverses and detects, allowing injectables to be used on dom elements.
What are Binders?
Binders are a way we do something with an element, such as showing it, hiding it, looping it many times, changing attributes, taking inputs etc. Basically the many things you can do manually to an element in your application to make your application come alive. This is the basis of having a binding engine/tool/framework, we have stripped these out into standalone classes to be injected into razilobind to allow you to configure what you need (razilobind-core) or just choose all defaults (razilobind).
Binders start with bind, then follow with the binder type (you can have a prefix too if you wish!). We then place resolvable data in the attribute, see here for what types of resolvable data can be used, to be evaluated and used with the binder. Each binder can accept all [] or certain types ['boolean', 'object', 'phantom'] of resolved data. To use a binder we can...
<!-- binding model data directly (two way) --> <!-- bind a literal (one way) --> <!-- binders producing phantom properties (two way) [configurable] --> <!-- one way binder (object) that gets re-evaluated like two way binding, by having an observed value inside it that changes --> <!-- one way binder (method) that gets re-evaluated like two way binding, by having an observed value inside it that changes -->
NOTE: Two way binding happens when binding properties of the model directly, or anything that uses a property of the model (including alterers and configs for binders!). Any time a re-evaluation is triggered, the elements complete binding is updated. Single binding is everything not falling into this rule meaning a one time evaluation on load.
What Binders are Available
text Add text to element
Adds text inside an element.
Accepts Resolvers all resolver types
html Add html to element
Adds html inside an element.
Accepts Resolvers string, property, phantom, method
show Show an element
Show an element and it's children only if resolved data is truthy.
Accepts Resolvers all resolver types
hide Hide an element
Hide an element and it's children only if resolved data is truthy. Use for constant showing and hiding during application use.
Accepts Resolvers all resolver types
if Use an element
Use an element and it's children in the dom if resolved data is truthy. Not to be mistaken for 'show'. Use for one time evaluation of wether element should be present on load.
Accepts Resolvers property, phantom, boolean, method
else Dont use an element
Don't use an element and it's children in the dom if resolved data is truthy. Not to be mistaken for 'hide'. Use for one time evaluation of wether element should be present on load.
Accepts Resolvers property, phantom, boolean, method
class Add class name/s to element
Add class name/s to an element, do this as a one time bind or on a changable basis (add/remove based on truthy).
Accepts Resolvers property, phantom, object, array, string, method
<!-- basic add --> <!-- add property value --> <!-- add method value --> <!-- add method value --> <!-- add add/remove truthy --> <!-- add collection of classes -->
attributes Add attributes to element
Add attributes to an element either as an attributes only based on truthy, or an attributes with data set on it.
Accepts Resolvers property, phantom, object, array, string, method
<!-- basic add attribute only --> <!-- basic add attribute from property --> <!-- basic add attribute with data --> <!-- add/remove with property as data, or if --> <!-- add property value --> <!-- add method value -->
disabled Add disabled attribute to element
Add attribute to an element.
Accepts Resolvers property, phantom, object, array, string, method
<!-- basic add attribute only --> <!-- basic add attribute from property -->
required Add required attribute to element
Add attribute to an element.
Accepts Resolvers property, phantom, object, array, string, method
<!-- basic add attribute only --> <!-- basic add attribute from property -->
selected Add selected attribute to element
Add attribute to an element.
Accepts Resolvers property, phantom, object, array, string, method
<!-- basic add attribute only --> <!-- basic add attribute from property -->
href Add href attribute to element
Add src attribute to an element.
Accepts Resolvers property, phantom, object, array, string, method
<!-- basic add attribute only --> <!-- basic add attribute from property -->
src Add src attribute to element
Add src attribute to an element.
Accepts Resolvers property, phantom, object, array, string, method
<!-- basic add attribute only --> <!-- basic add attribute from property -->
style Add style to element
Add style to an element.
Accepts Resolvers property, phantom, object, method
<!-- basic add --> <!-- add property value --> <!-- add method value -->
for Loop over element
Loop over an element, repeating it for each instance of resolved data.
Accepts Resolvers property, phantom, method, array, object Config {'key': 'name', 'value': ''} Filter {'title': 'name', 'value': ''}
<!-- basic for loop, access itteration using phantom property --> <!-- loop from property object/array, access itteration using phantom property --> <!-- set phantom names for key and value --> <!-- more complex optionsm ordering on contents, filtering on contents, limits and offsets -->
value Two way bind to element value
Offers two way binding to form controls such as inputs, select boxes textareas etc. Updating the controls will update the model, model updates will update the dom.
Accepts Resolvers property, phantom
<!-- basic value binds --> <!-- binding values in selects -->
model Two way bind to element model
Offers two way binding to allow us to get data into things like custom web components. All raziloComponent web components are capable of excepting object data from element.model
Accepts Resolvers property, phantom
<!-- basic value binds -->
checked Two way bind to element checked value
Offers two way binding to form controls that use checked status such as radio buttons and check boxes. Updating the controls will update the model, model updates will update the dom.
Accepts Resolvers property, phantom
<!-- radio buttons --> <!-- check box -->
event Multi-purpose event binder
Offers a simple way to bind any event to a method. Accepts all js element event types without the 'on' bit.
Accepts Resolvers method
<!-- radio buttons -->
Making your own Binders
There are two ways to add your own binders to the library, by injecting them with the addBinders() method bundled with razilobind, or if you have decided to import the core and have extended it, you may inject them along with all the other binders in the same fashion.
First off you will need a new binder, you can start off by taking an existing binder and copying it, changing the necessary parts. Lets call this your-test.binder.js...
/** * Test Binder * Do something to the element node based on resolved data * * Inherits * * properties: options, node, resolver, traverser, model, accepts * method: detect(node) { return bool } * method: build(model) { return binder } * method: update(newValue, oldValue) { } */ { super; thisoptions = options; // prefix etc. thistraverser = traverser; // so you can re-traverse new elements for binds thisname = 'your-test'; // name of the resolver to search for thisaccepts = ; // accept all resolvers } /** * bind() * Bind the resolved data by showing hiding the node * @param object oldValue The old value of the observed object */ { // oldValue is the value before the new change, before it was re-evaluated or empty on load // path is the path to the model property if property bound // action is the action being performed in this evaluation, such as update or array-remove // key is the key of any objects or array values removed or added (to allow synching of elements such as looping) // this.resolver contains the element binds resolver (resolved is the data that has been resolved and after alterers applied) // this.node is the actual element node you are on // this.traverser is the traverser instance you can use to re-traverse new elements (garbage collection on removed nodes is automatic!) // this.model is the bound model at the root level // various things methods are automatically run on bind, such as detection, build and updates from observers (which fire this method) // all that is required is to complete the necessary changes for your element in this method // this is a sample of showing and hiding an element based in truthy data if !!thisresolverresolved thisnodestyledisplay = ''; else thisnodestyledisplay = 'none'; }
You can now import this into your project logic along with razilobind, injecting YourTestBinder into razilobind by adding custom binder...
var model = foo: 'foo' bar: 'bar'; var rb = ;rb;rb;
or if you have extended the core with your own class, you can add them as follows...
{ superoptions; // Inject injectables, pull in what you need! RaziloBindCoreDetectordefaultAlterers = TrimAlterer: RaziloBindTrimAlterer ...; RaziloBindCoreDetectordefaultBinders = ForBinder: RaziloBindForBinder ...; RaziloBindCoreDetectordefaultResolvers = BooleanResolver: RaziloBindBooleanResolver ...; // Inject custom injectables RaziloBindCoreDetectorcustomBinders = YourTest: YourTestBinder ...; }
...either way will inject custom binders, should you wish to replace all default binders with your own custom ones, substitute the default injectables with your custom ones. Default injectables will also be parsed first, followed by custom ones, you choose how to and what to inject.
Once your new binder is injected, you should be able to use it like so (don't forget strings are in quotes, miss the quotes and you will be sending a property in!)