# CreateDOM - $C()
#### Create DOM Stuctures Easily
__$C()__ is a function that provides a much easier alternative to W3C DOM's _createElement_ function.
__$C()__ is light-weight and turns the process of constructing DOM structures into one that is easy and intuitive.
## Features
* enables the declaration of an entire DOM tree into a single data structure.
* this data structure consists of a plain object with key/value pairs.
a key can either represent:
* an html tag
* a text node
* when the key represents an html tag, then the value can contain:
* falsy - when the tag has no attributes or children
* a nested plain object with key/value pairs.
a key can either represent:
* a boolean "condition", to indicate whether this tag should be ignored
* a text node
* a nested child html tag
* otherwise: an html attribute
* a string - to add a child text node.
this is short-hand notation for: {"text": value}
## Notes
* when a "condition" attribute is used, it's much more efficient to always include it as the first attribute.
doing so prevents the creation of nested/child DOM nodes,
belonging to other attributes that were processed before reaching the "condition",
which would only be discarded when the condition evaluates to false.
## Issue/Workaround
* the process of mapping a DOM tree into an object representation results in a problem.
* a DOM node can contain multiple child nodes of the same type
> ex: ``
* a hash table (javascript object) can only contain one value for each unique key
> ex: `{"div":{"class":"foo"},"div":{"class":"bar"}}`
> => this hash table only has one key and, consequently, only one value; the other is lost.
* to work around this issue, there are two options:
1. (my preference) is to:
* make keys unique by appending an underscore ("_") and any (unsigned) integer you like
> ex: `{"div_1":{"class":"foo"},"div_2":{"class":"bar"}}`
* the script simply removes this trailing pattern from all keys before processing them
2. (legacy) is to:
* replace an object with an array
* wrap each object attribute into a new object (having only a single attribute),
and pushing this object into the array
## Example #01
```javascript
$C({
"span" : {
"condition" : (name !== null),
"class" : "name_wrapper",
"span" : {
"class" : "name",
"span" : {
"class" : "expand_button"
},
"text" : name
},
"text" : " : "
},
"div" : {
"class" : "value",
"b_1" : sym[0],
"ul" : {
"class" : "children"
},
"b_2" : sym[1],
"text" : {
"condition" : (!is_last),
"text" : ","
}
}
},parent_element,document);
```
things to note:
* the resulting DOM tree is going to look like:
```AsciiDoc
parent_element
span.name_wrapper
span.name
span.expand_button
textnode
textnode
div.value
b
textnode
ul.children
b
textnode
textnode
```
* use of "condition" by:
* `parent_element > span.name_wrapper`
* `parent_element > div.value > textnode:last-child`
each of these nodes passes a boolean value that dynamically determines whether or not these nodes (and any trees that may root from these nodes) are created.
* the creation of two `` within:
* `parent_element > div.value`
this is done using the methodology of appending `_\d+`
* the textnodes contained within each of the `` nodes are created implicitely,
simply by passing the text as the value.
* __parent_element__ can be passed as either:
* a string that contains the id of a DOM node
> ex: 'foobar'
* a DOM Element
> ex: `document.getElementById('foobar')`
* when passed in this way, it doesn't matter if the DOM element is currently attached to the DOM.
> ex:
```javascript
var detached_parent_element = document.createElement('div');
$C({"text":"hello world"},detached_parent_element,document);
document.body.appendChild(detached_parent_element);
```
## Example #02
```javascript
$C({ul:[
{li:"First Item"},
{li:"Second Item"},
{li:"Third Item"},
]},"insert-here");
```
things to note:
* this uses the 2nd (legacy) workaround methodology.
* _parent_element_ in this case is a string, which must be a DOM node "id".
* _document_ is not being specified, so window.document will be used to create all Elements.
## Closing Comments
* In most situations, jQuery will already be available and adding yet-another script to the page will be unnecessary.
* My particular use-case was one in which I wanted to keep the code base as minimal as possible,
and there were no pre-loaded libraries to leverage (writing Firefox add-ons).
That being said, I actually do prefer this syntax;
it feels much more natural and streamline to me, than writing nested .append() statements.
Also, any logical "condition" would interrupt chaining.