Skip to content

Instantly share code, notes, and snippets.

@apiv
Last active February 11, 2017 20:13
Show Gist options
  • Save apiv/4401615 to your computer and use it in GitHub Desktop.
Save apiv/4401615 to your computer and use it in GitHub Desktop.
This is a simple coffeescript class that provides a flexible platform for creating interactive views; much like BackboneJS, although library-independent. TODO: use the document.querySelector for setup elements and event binding. querySelector can be implemented easily on browsers that don't include native support.
###
Helper functions
###
###
@function {getElementsByDataEl}: find and return elements by data-el attribute
@param {parent}: the DOM node to search through
@param {elements}: Array of data-el values to find
###
getElementsByDataEl = (parent, elements) ->
elements = elements.slice 0
all = parent.getElementsByTagName "*"
found = {};
for element in all
do (element) ->
dataEl = element.getAttribute "data-el"
isWanted = elements.indexOf dataEl
if !!~isWanted
found[ elements[isWanted] ] = element
elements.splice isWanted, 1
found
###
@function {templatize}: renders templates
@param {template}: String template
@param {options}: Object map to replace template vars
###
templatize = (template, options) ->
(options) ->
keys = Object.keys options
for key in keys
do (key) ->
template = template.replace "{" + key + "}", options[key]
template
###
BaseView Class
###
class BaseView
###
base presets
###
tagName: "div"
className: ""
template: ""
# elements to select for manipulation, by data el
elements: []
###
base functions
###
### @constructor {constructor}: sets instance options ###
constructor: (@options) ->
### @function {render}: creates element and returns instance ###
render: ->
@_templatize();
@el = document.createElement(@tagName);
@el.innerHTML = @_template(@options);
@_setupElements();
@
###
pseudo-private functions
###
_templatize: ->
@_template = templatize @template
_setupElements: ->
this.els = getElementsByDataEl @el, @elements
###
Example View
###
class Example extends BaseView
tagName: "div"
className: "dialog"
template: '<h2>{title}</h2><span>{message}</span><button data-el="dostuff">Do Something</button>'
elements: ["dostuff"]
###
Example Implementation
###
testParent = document.getElementById("body")
testOptions =
title: "This is the title!"
message: "This would be a message of some sort, unless you don't want that."
testView = new Example testOptions
testParent.appendChild( testView.render().el )
# bind actions to elements
# TODO: internal event binding
testView.els.dostuff.onclick = ->
alert "You clicked it"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment