DOM Mode¶
DOM mode provides an output mode which generates DOM Elements from
DOMBuilder.createElement()
calls and DOM DocumentFragments from
DOMBuilder.fragment()
calls.
The DOM mode API is exposed through DOMBuilder.modes.dom.api
.
Mode-specific element functions are exposed through DOMBuilder.dom
.
-
DOMBuilder.
dom
¶ Element functions which will always create DOM Element output.
New in version 2.0.
Attributes¶
Some attributes are given special treatment based on their name.
Event Handlers¶
Event handlers can be specified by supplying an event name as one of the element’s attributes and an event handling function as the corresponding value. Any of the following events can be registered in this manner:
Event Names | |||||
---|---|---|---|---|---|
blur | focus | focusin | focusout | load | resize |
scroll | unload | click | dblclick | mousedown | mouseup |
mousemove | mouseover | mouseout | mouseenter | mouseleave | change |
select | submit | keydown | keypress | keyup | error |
These correspond to events which have jQuery shortcut methods, which will be used for event handler registration if jQuery is available, otherwise legacy event registration will be used.
For example, the following will create a text input which displays a default value, clearing it when the input is focused and restoring the default if the input is left blank:
var defaultInput =
el.INPUT({
type: 'text', name: 'email'
, value: 'email@host.com', defaultValue: 'email@host.com'
, focus: function() {
if (this.value == this.defaultValue) {
this.value = ''
}
}
, blur: function() {
if (this.value == '') {
this.value = this.defaultValue
}
}
}
)
Other ‘Special’ Attributes¶
Other attributes which trigger special handling or explicit compatibility handling between DOM and HTML modes.
innerHTML
If you specify an
innerHTML
attribute, the given String will be the sole source used to provide the element’s contents, even if you pass more contents in as arguments.- In DOM mode, the element’s
innerHTML
property will be set and no further children will be appended, even if given. - In HTML mode, the given HTML will be used, unescaped, as the element’s contents.
- In DOM mode, the element’s
Document Fragments¶
A DOM DocumentFragment is a lightweight container for elements which
allows you to append its entire contents with a single call to the
destination element’s appendChild()
method.
If you’re thinking of adding a wrapper <div>
solely to be able to
insert a number of sibling elements at the same time, a
DocumentFragment will do the same job without the need for the redundant
element. This single append functionality also makes it a handy container
for content which needs to be inserted repeatedly, calling
cloneNode(true)
for each insertion.
DOMBuilder provides a DOMBuilder.fragment()
wrapper function,
which allows you to pass all the contents you want into a DocumentFragment
in one call, and also allows you make use of this functionality in HTML
mode by creating equivalent Mock DOM Objects as appropriate. This
will allow you to, for example, unit test functionality you’ve written
which makes use of DocumentFragment objects by using HTML mode to verify
output against HTML strings, rather than against DOM trees.
See http://ejohn.org/blog/dom-documentfragments/ for more information about DocumentFragment objects.
Mapping Fragments¶
-
DOMBuilder.fragment.
map
(items, mappingFunction)¶ Creates a fragment wrapping content created for (potentially) every item in a list.
Arguments: - items (Array) – the list of items to use as the basis for creating fragment contents.
- mappingFunction (Function) – a function to be called with each item in the list, to provide contents for the fragment.
The mapping function will be called with the following arguments:
mappingFunction(item, itemIndex)
The function can indicate that the given item shouldn’t generate any content for the fragment by returning
null
.Contents created by the function can consist of a single value or a mixed
Array
.
This function is useful if you want to generate sibling content from a list of items without introducing redundant wrapper elements.
For example, with a newforms FormSet
object, which contains multiple
Form
objects. If you wanted to generate a heading and a table for each
form object and have the whole lot sitting side-by-side in the document:
var formFragment = DOMBuilder.fragment.map(formset.forms, function(form, loop) {
return [
H2('Widget ' + (loop.index + 1)),
TABLE(TBODY(
TR.map(form.boundFields(), function(field) {
return [TH(field.labelTag()), TD(field.asWidget())]
})
))
]
})
Appending formFragment
would result in the equivalent of the following
HTML:
<h2>Widget 1</h2>
<table> ... </table>
<h2>Widget 2</h2>
<table> ... </table>
<h2>Widget 3</h2>
<table> ... </table>
...