list.js
Version:
The perfect library for lists. Supports search, sort, filters and flexibility. Built to be invisible and work on existing HTML
196 lines (177 loc) • 5.46 kB
JavaScript
var Templater = function (list) {
var createItem,
templater = this
var init = function () {
var itemSource
if (typeof list.item === 'function') {
createItem = function (values) {
var item = list.item(values)
return getItemSource(item)
}
return
}
if (typeof list.item === 'string') {
if (list.item.indexOf('<') === -1) {
itemSource = document.getElementById(list.item)
} else {
itemSource = getItemSource(list.item)
}
} else {
/* If item source does not exists, use the first item in list as
source for new items */
itemSource = getFirstListItem()
}
if (!itemSource) {
throw new Error("The list needs to have at least one item on init otherwise you'll have to add a template.")
}
itemSource = createCleanTemplateItem(itemSource, list.valueNames)
createItem = function () {
return itemSource.cloneNode(true)
}
}
var createCleanTemplateItem = function (templateNode, valueNames) {
var el = templateNode.cloneNode(true)
el.removeAttribute('id')
for (var i = 0, il = valueNames.length; i < il; i++) {
var elm = undefined,
valueName = valueNames[i]
if (valueName.data) {
for (var j = 0, jl = valueName.data.length; j < jl; j++) {
el.setAttribute('data-' + valueName.data[j], '')
}
} else if (valueName.attr && valueName.name) {
elm = list.utils.getByClass(el, valueName.name, true)
if (elm) {
elm.setAttribute(valueName.attr, '')
}
} else {
elm = list.utils.getByClass(el, valueName, true)
if (elm) {
elm.innerHTML = ''
}
}
}
return el
}
var getFirstListItem = function () {
var nodes = list.list.childNodes
for (var i = 0, il = nodes.length; i < il; i++) {
// Only textnodes have a data attribute
if (nodes[i].data === undefined) {
return nodes[i].cloneNode(true)
}
}
return undefined
}
var getItemSource = function (itemHTML) {
if (typeof itemHTML !== 'string') return undefined
if (/<tr[\s>]/g.exec(itemHTML)) {
var tbody = document.createElement('tbody')
tbody.innerHTML = itemHTML
return tbody.firstElementChild
} else if (itemHTML.indexOf('<') !== -1) {
var div = document.createElement('div')
div.innerHTML = itemHTML
return div.firstElementChild
}
return undefined
}
var getValueName = function (name) {
for (var i = 0, il = list.valueNames.length; i < il; i++) {
var valueName = list.valueNames[i]
if (valueName.data) {
var data = valueName.data
for (var j = 0, jl = data.length; j < jl; j++) {
if (data[j] === name) {
return { data: name }
}
}
} else if (valueName.attr && valueName.name && valueName.name == name) {
return valueName
} else if (valueName === name) {
return name
}
}
}
var setValue = function (item, name, value) {
var elm = undefined,
valueName = getValueName(name)
if (!valueName) return
if (valueName.data) {
item.elm.setAttribute('data-' + valueName.data, value)
} else if (valueName.attr && valueName.name) {
elm = list.utils.getByClass(item.elm, valueName.name, true)
if (elm) {
elm.setAttribute(valueName.attr, value)
}
} else {
elm = list.utils.getByClass(item.elm, valueName, true)
if (elm) {
elm.innerHTML = value
}
}
}
this.get = function (item, valueNames) {
templater.create(item)
var values = {}
for (var i = 0, il = valueNames.length; i < il; i++) {
var elm = undefined,
valueName = valueNames[i]
if (valueName.data) {
for (var j = 0, jl = valueName.data.length; j < jl; j++) {
values[valueName.data[j]] = list.utils.getAttribute(item.elm, 'data-' + valueName.data[j])
}
} else if (valueName.attr && valueName.name) {
elm = list.utils.getByClass(item.elm, valueName.name, true)
values[valueName.name] = elm ? list.utils.getAttribute(elm, valueName.attr) : ''
} else {
elm = list.utils.getByClass(item.elm, valueName, true)
values[valueName] = elm ? elm.innerHTML : ''
}
}
return values
}
this.set = function (item, values) {
if (!templater.create(item)) {
for (var v in values) {
if (values.hasOwnProperty(v)) {
setValue(item, v, values[v])
}
}
}
}
this.create = function (item) {
if (item.elm !== undefined) {
return false
}
item.elm = createItem(item.values())
templater.set(item, item.values())
return true
}
this.remove = function (item) {
if (item.elm.parentNode === list.list) {
list.list.removeChild(item.elm)
}
}
this.show = function (item) {
templater.create(item)
list.list.appendChild(item.elm)
}
this.hide = function (item) {
if (item.elm !== undefined && item.elm.parentNode === list.list) {
list.list.removeChild(item.elm)
}
}
this.clear = function () {
/* .innerHTML = ''; fucks up IE */
if (list.list.hasChildNodes()) {
while (list.list.childNodes.length >= 1) {
list.list.removeChild(list.list.firstChild)
}
}
}
init()
}
module.exports = function (list) {
return new Templater(list)
}