element-model
v1.1.5
Published
HTML and SVG element object model and renderer for the browser
Downloads
11
Readme
element-model
The element-model package is a JavaScript library for creating and rendering HTML and SVG element hierarchies. It is useful for the creation of front-end components and applications.
Links
Rendering HTML Elements
The element model is a native JavaScript object representation of HTML and SVG element hierarchies. It provides a straight-forward, programmatic way to generate HTML content in the web browser using pure JavaScript. For example, consider the following HTML element hierarchy:
<h1>Title</h1>
<p>
This is <a href="link.html">a <strong>link</strong></a>
</p>
The element model for the HTML element hierarchy above is as follows:
const elements = [
{
'html': 'h1',
'elem': {'text': 'Title'}
},
{
'html': 'p',
'elem': {
'html': 'a',
'attr': {'href': 'link.html'},
'elem': [
{'text': 'a '},
{
'html': 'strong',
'elem': {'text': 'link'}
}
]
}
}
];
An element model is rendered to the web browser using the renderElement function.
import {renderElements} from 'element-model/lib/elementModel.js';
renderElements(document.body, elements);
If the element model comes from an un-trusted source, you'll want to verify it before rendering using the validateElements function.
import {validateElements} from 'element-model/lib/elementModel.js';
validateElements(elements);
The validateElements function is also useful for testing element model components by ensuring that they return valid element model objects.
The Element Model
An element model is either an element object, null, or an array (of any above). Element objects define either an HTML element, an SVG element, or a text element.
HTML and SVG element model objects may define the following attributes: "html", "svg", "attr", "elem", and "callback". The "html" or "svg" attributes define the HTML or SVG element tag (e.g., "h1"), respectively.
HTML and SVG elements can optionally define attributes using the "attr" attribute. The "attr" attribute is a dictionary of the element's attributes or null. If "attr" is null, there are no attributes. Further, if any attribute's value is null, that attribute is ignored.
HTML and SVG elements can optionally define sub-elements using the "elem" attribute. The "elem" attribute can be an element object, null, or an array of any of the above. If "elem" is null, there are no sub-elements. Any null element encountered is ignored.
If an HTML or SVG element object defines the "callback" attribute, the function is called with the created HTML or SVG element. This allows for the addition of callbacks (e.g., "click") on the created elements.
Text element model objects are identified by the "text" attribute. The "text" attribute value is the text of the element.
Examples
The following examples demonstrate the element model in practice.
Dynamic List
The element model was designed to make creation of dynamic content easy in code. For example, here's how to dynamically create a list:
const listItems = ['One', 'Two', 'Three'];
const elements = [
{'html': 'h1', 'elem': {'text': 'The List'}},
{
'html': 'ul',
'elem': listItems.map((text) => ({'html': 'li', 'elem': {'text': text}}))
}
];
renderElements(document.body, elements);
Optional Content
To hide optional content, simple replace the content's element model with null. For example:
const hasOptionalContent = false;
const elements = [
{'html': 'p', 'elem': {'text': 'This is required content'}},
!hasOptionalContent ? null : {'html': 'p', 'elem': {'text': 'This is optional content'}}
];
renderElements(document.body, elements);
Front-End Components
Any function that returns an element model can be considered a component. For example:
const linkElements = (text, url) => {
return {'html': 'p', 'elem': {'html': 'a', 'attr': {'href': url}, 'elem': {'text': text}}};
};
const elements = [
linkElements('Link 1', '#one'),
linkElements('Link 2', '#two'),
linkElements('Link 3', '#three')
];
renderElements(document.body, elements);
Collapsing Menu
To create a collapsing menu, we add add an "click" event handler that hides or shows the sub-menu.
const onHideShow = () => {
const submenu = document.getElementById('submenu');
if (submenu.getAttribute('style').includes('visible')) {
submenu.setAttribute('style', 'visibility: collapse;');
} else {
submenu.setAttribute('style', 'visibility: visible;');
}
};
const elements = [
{'html': 'ul', 'elem': [
{'html': 'li', 'elem': [
{'html': 'a', 'elem': {'text': 'Menu'}, 'callback': (element) => {
element.addEventListener('click', () => onHideShow(), false);
}},
{'html': 'ul', 'attr': {'id': 'submenu', 'style': 'visibility: visible;'}, 'elem': [
{'html': 'li', 'elem': {'html': 'a', 'attr': {'href': '#one'}, 'elem': {'text': 'Sub-menu 1'}}},
{'html': 'li', 'elem': {'html': 'a', 'attr': {'href': '#two'}, 'elem': {'text': 'Sub-menu 2'}}}
]}
]}
]}
];
renderElements(document.body, elements);
Development
This package is developed using javascript-build. It was started using javascript-template as follows:
template-specialize javascript-template/template/ element-model/ -k package element-model -k name 'Craig A. Hobbs' -k email '[email protected]' -k github 'craigahobbs' -k noapp 1