1.0.0 • Published 6 years ago

@reactivelib/html v1.0.0

Weekly downloads
1
License
MIT
Repository
-
Last release
6 years ago

This is a virtual dom using only plain json objects and the reactive package. There are no additional compilation steps. For example, let's create a simple form to add 2 numbers:

<!DOCTYPE html>
<html>
<head>
    <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/@reactivelib/html@latest/dist/reactivelib.min.js"></script>
</head>
<body>
<div id="myForm"></div>
<script type="text/javascript">

    var reactive = reactivelib.reactive;
    var html = reactivelib.html;

    function createInput(){
        //we create a reactive property object for the input.
        var props = reactive({
            value: 0
        });

        return {
            //We define a new html element with "input" tag name
            tag: "input",
            //Define what properties the html element has
            prop: props,
            //Define what attributes the html element has
            attr: {
                type: "number"
            },
            //Define event handlers for the html element
            event: {
                //We listen to the keyup and mouseup event of the input element and update the reactive property object value
                keyup: (event) => {
                    props.value = event.target.value;
                },
                mouseup: (event) => {
                    props.value = event.target.value;
                }
            }
        }
    }

    var input1 = createInput();
    var input2 = createInput();

    // Create div that prints the sum of the 2 inputs.
    var result = {
        // html element with "div" tag name
        tag: "div",
        //This getter will be called again if the reactive value of input1 or input2 changes,
        //causing a rerendering of this html elements children
        get child(){
            return "Sum is: "+(parseInt(input1.prop.value) + parseInt(input2.prop.value))
        }
    }

    var form = {
        tag: "div",
        //The child elements of this html element
        child: [{tag: "div", child: input1}, {tag: "div", child: input2}, result]
    }

    // attach the form to the "myForm" div
    html.attach(document.getElementById("myForm"), form);

</script>
</body>
</html>

When the user changes the input, the result will automatically be updated.

Installation

npm install @reactivelib/reactive

commonjs

var html = require("@reactivelib/html");
html.attach(document.getElementById("myElement"),{ 
    tag: "div",
    child: "Hello"
})

Browser

We provide a browser ready file "dist/reactivelib.min.js" in the npm package that exposes the global "reactivelib" and includes both this and the reactive package.

<head>
    <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/@reactivelib/html@latest/dist/reactivelib.min.js"></script>
</head>

<body>

    <script type="text/javascript">
        //reactive package
        var reactive = reactivelib.reactive;
        //this package
        var html = reactivelib.html;        
    </script>
</body>

Typescript

import * as html from '@reactivelib/html';
html.attach(document.getElementById("myElement"),{ 
    tag: "div",
    child: "Hello"
})

Typescript with "esModuleInterop"

When using "esModuleInterop" option, you can also import as follows:

import html from '@reactivelib/html';
html.attach(document.getElementById("myElement"),{ 
    tag: "div",
    child: "Hello"
})

or

import {attach} from '@reactivelib/html';
attach(document.getElementById("myElement"),{ 
    tag: "div",
    child: "Hello"
})

Creating html elements

Html elements can be created with a json object that contains following properties:

propertydescription
tagdefines the html tag name of the html element to create
propdefines the properties of the html element. This sets the properties of the javascript object that you get when using document.getElementById
attrdefines the attributes of the html element
styledefines the style attribute of the html element
eventdefines the event handlers of the html element
childdefines the children of the html element. Can be a string, a virtual dom element or an array containing string or virtual dom elements

For example, following json object:

var el = {
    tag: "div",
    child: "Hello",
    attr: {
        id: "panel"
    },
    style: {
        background: "black"
    }
}

would render following html element:

<div id="panel" style="background: black">Hello</div>

Attaching to the DOM

In order to render the virtual dom elements, you need to attach them to the dom. You can accomplish that with the "attach" method as follows:

Assume we have following html element somewhere in the page

<div id="element"></div>
var el = {
    tag: "div",
    child: ["Input number: ",{
        tag: "input",
        attr :{
            type: "number"
        },
        prop: {
            value: 5
        }
    }]
}
reactivelib.html.attach(document.getElementById("element"), "el")

The attach renders and appends the rendered html element to the element given to the attach method. This is how the html element looks like after attaching:

<div id="element">
Input number: <input type="number" />
</div>

Note that defining

prop: {value: 5}

we also set the value of the input element to 5.

Reactive properties

You can use the reactive package to create virtual dom elements that are reactive. Any property you create and make reactive will be automatically kept in sync with the rendered html element. For example:

var el = reactivelib.reactive({
    tag: "div",
    child: "Hello"    
})

This renders following html element

<div>Hello</div>

We can now change the content of the div element like follows:

el.child = "New content"

The content of the html element will be automatically refreshed:

<div>New content</div>

For a more complex example, take a look at the example at the top of this readme file.

Lifecycle

When you attach a virtual dom element to the dom, the "onAttached" method will be called if available:

var el = {
 tag: "div",
 child: "Hello",
 onAttached: function(){
     console.log("on attached called")
 }
};

reactivelib.html.attach(document.getElementById("element"), el);

//at some later point, console will print "on attached called"

There is also a "onDetached" method when you remove the virtual dom element from the dom:

var el = {
  tag: "div",
  child: "Hello",
  onAttached: function(){
      console.log("on attached called")
  },
  onDetached: function(){
    console.log("on detached called")
  }
};

reactivelib.html.attach(document.getElementById("element"), el);

//at some later point, console will print "on attached called"

//Some time later
reactivelib.html.detach(el);

//at some later point, console will print "on detached called"

Note that rendering happens asynchronously inside an animation frame. Therefore, the lifecycle methods are called at some point in the future after attaching or detaching.

The node object

The node object gives you access to the html element and parent and is available after the virtual dom element has been attached:

var el = {
    tag: "div",
    child: {
     tag: "div",
     child: "Hello",
     onAttached: function(){
         var node = el.node;
         console.log("html element: "+node.element)
         console.log("parent virtual dom object: "+node.parentModel);
     },
     onDetached: function(){
         
     }
   }
};

Projects using this module

ReactiveChart