I too was using Angular.js few years ago, but then I realized it's nature. I needed lighter and happier syntax to achieve same kind of designs faster. That's how Deval was born - a W3C validating syntax with a blazing fast parser.
Mastering Deval only requires learning the basic attributes to use it, JS you already know. Unlike Angular, this doesn't provide observables.. Why? Because they suck.
Angular coders, if you're reading this... Stop exhausting my CPU and eating up my memory! Always respect the client space and its resources.
If you're interested of porting this logic into Node.js, please let me know.
Happy hacking! ;-)
@license FREE FOR ALL - But, let me know of any public usage (for fame) or bugs (for shame)
@TODO Refactor and port for Node.js (npm)
<html><head><scriptsrc="deval.min.js"></script></head><body><h1data-eval="timer = new Date().toLocaleTimeString()"
data-interval="1000">
[timer]
</h1><script>deval.parse();</script></body></html><pdata-eval="simple = 'Example'">[simple]</p><pdata-eval="time = new Date()">[time]</p><pdata-eval="timer = new Date().toLocaleTimeString()" data-interval="1000">[timer]</p><pdata-eval="this.style.background = true ? 'yellow' : 'red'">I have yellow background</p><divdata-eval="dat = ajax:json:myJsonUrl"><divdata-ajax="init">Loading..</div><divdata-ajax="ok"><divdata-eval="dat.status == 'ok'">Success!</div><divdata-eval="dat.status == 'error'">Error: [dat.error]</div></div><divdata-ajax="error">Could not connect to server</div></div><divdata-eval="news = ajax:xml:news.xml" data-interval="5000"><divdata-ajax="init">Loading..</div><divdata-ajax="ok"><table><tbodydata-loop="n = news.getElementsByTagName('title')"><trdata-eval="[n.num()] > 2"><td>[n.childNodes[0].nodeValue]</td></tr></tbody></table></div><divdata-ajax="loading">Updating..</div><divdata-ajax="error">Could not load any news.</div></div><divdata-eval="data = ajax:json:myAjaxGetURL"><formaction="myAjaxPostURL"
method="POST"
id="myform"
data-form="myform"
data-validate="myValidator"
data-callback="serverResponse"><inputtype="text" name="myinput" data-value="data.myinput | 'My auto-input'"></form><script>functionmyValidator(form){returnform.myinput!=='My auto-input';}functionmyServerReponse(response){// server data handling}</script></div><script>varexample={contents: {firstArray: [{html:'content1-1'},{html:'content1-2'},{html:'content1-3'}],secondEmpty: {// empty},thirdObject: {'some': {html:'content3-1'}}}};functionmyRowFormatter(dat){dat.html=dat.html.toUpperCase();returndat;}functiondoSomethingWithDataAndKey(s,key){returns+' render key '+key;}</script><!-- Rendering --><uldata-loop="s = example.contents"><li>
[s.num()]. [s.key()] ([s.count()])
<uldata-loop="c = s" data-row="myRowFormatter"><li><divdata-eval="html = doSomethingWithDataAndKey(c.html, '[c.key()]')"><p>[html]</p></div></li></ul></li></ul><pdata-eval="timer = new Date().toLocaleTimeString()" data-event="clock">Event clock: [timer]</p><buttononclick="deval.dispatchEvent('clock')">Event: clock</button>Remember to respect cross origin XMLHttpRequests ;)
<!-- Text file --><pdata-eval="txt = ajax:test.txt">[txt]</p><!-- JSON file --><pdata-eval="json = ajax:json:test.json">[json.some.example]</p><!-- XML file --><divdata-eval="xml = ajax:xml:test.xml"><pdata-eval="xmlContent = xml.getElementsByTagName('example')[0].childNodes[0].nodeValue">
[xmlContent]
</p></div><script>// debugdeval.debug=true;// parse and render the whole bodydeval.parse();</script>Javascript evaluation and conditionals etc.
<divdata-eval="txt = ajax:hello.txt">[txt]</div>
Few examples:
data-eval="myString = 'it\'s a string!'"
data-eval="myObject = {data:'things'}"
data-eval="myArray = [1,2,3,4]"
data-eval="myBoolean == 'things' ? true : false"
data-eval="myData = ajax:hello.txt"
data-eval="myJson = ajax:json:my.json"
data-eval="myXml = ajax:xml:my.xml"
data-eval="myUppercaseString = 'wow'.toUpperCase()"
data-eval="myOutput = calculateMyThings(data)"URL params can be passed into ajax URL with data-params attributes
<div data-params="min=1&max=myMaxValue" data-eval="my = ajax:/call"></div>
This tries to read all values first as a variable, if not found, they're interpreted as value.
So you can pass text and variables like var min = 0; var max = 10; with foo=bar&min=min&max=max.
Here are some other examples of usage -> result:
data-params="foo=bar&limit=10" -> /call?foo=barVariableValue&limit=10
data-params="foo='bar'" -> /call?foo=bar
data-params="p" -> /call?pVarValue
data-params="{foo:'bar'}" -> /call?foo=bar
data-params="t=Date.now()" -> /call?t=1126217126272
Events for DOM objects: init | loading | ok | error
<pdata-ajax="init">Loading..</p><pdata-ajax="loading">Reloading data..</p><pdata-ajax="ok">Ajax completed succesfully.</p><pdata-ajax="error">Could not access the server!</p>Loop data within innerHTML template
<uldata-loop="row = some.data"><li>[row]</li></ul>Supported inline methods for data:
[row.num()] - Row number
[row.key()] - Row key
[row.count()] - Row array|object count (length)Handle loop data before it renders on a row basis
<uldata-row="myRowFormatter" data-loop="row = some.data"><li>[row]</li></ul>
myRowFormatter(row) { return row; }Listen to events with chosen name and fire Deval.update accordingly
<pdata-eval="clock = new Date()" data-event="clock">[clock]</p><script>deval.dispatchEvent('clock');</script>Loop limit uint[,uint]
<uldata-limit="5" data-loop="row = some.data"><li>[row]</li></ul>
data-limit="10" -> limit loop to 10 rows
data-limit="5,10" -> loop only rows 5 to 10
data-limit="mylimitvar" -> use variable to pass the limit ie. mylimitvar = 10
data-limit="start,limit" -> use variables to pass the start,limit ie. start = 5, limit = 10Binds the form to Deval and gives support for data-value, data-validate, etc. methods.
You can pass URL GET params with same input names into the fields automatically (urlParamsToForm).
Use multipart/form-data in your form to send files, default is application/x-www-form-urlencoded
<formdata-formaction="/myFormHandler"></form>Form field default value if no value is set
<inputdata-value="target.country||'fi'||23" type="text">Handle any form changes, also fired upon ajax submit. You can do easily server side checks with this or make logics according to the user input.
<formdata-validate="myValidator(dat)"></form>
function myValidator(dat) { return dat; }Data update interval in milliseconds (for data-eval)
<pdata-interval="1000" data-eval="time = new Date()">[time]</p>Handle ajax data before rendering (for your own data logics)
<divdata-translate="myPreDataHandler" data-eval="my = { foo: 'bar' }"></div>
function myPreDataHandler(dat) { return dat; }Callback function after we are done eval'ing, passes object so ie. function myCallback(o) {}.
Callback for ajax forms server response, if you want data pre-processing use ie. data-translate="json"
With ajax calls, there can be error so setup your ajax callbacks like:
<divdata-callback="myCallback(dat, error)" data-eval="my = ajax:call"></div>Ignores this dom tree in parsing (if you want to use deval.render calls directly)
<divdata-ignore></div>Debug all related parses into console.log
<divdata-debugdata-eval="debug = this">[debug]</div>ie. deval.debug = true
vardeval=newDeval({urlParamsToForm: false,// default: truedebug: true,// default: false// Global Ajax callbacksonLoad: function(){},// ajax onLoad (loading)onAjax: function(){}// ajax onAjax (ok)});deval.render({// Requiredid: 'content',// element idset: 'now',// variable// Data methodsget: 'new Date()',// eval datadat: function(){// direct datareturnnewDate()},limit: 0,// loop limit (0 = unlimited)// Ajax optionsurl: 'http://ajax/jsondata',// ajax urltranslate: '',// json|xml|tags|function|otherxml: false,// parse as xml?tags: false,// encode html tags?params: 'foo=bar&limit=max'// pass params to url with dynamic values// Form optionsform: 'formid',// handle as form data// Update intervalinterval: 1000,// milliseconds// Callbackcallback: function(o){// Object o has all the info above with tha data in o.dat// your codealert(JSON.stringify(o));},// If you want your own templatetemplate: '<p>Date is [now]</p>'// Debugging and debug console overwritedebug: true,console={log: function(s){console.log(s);},// overwrite example:error: function(s){console.error(s);}// deval.console.error = function(s) { alert(s); }}});deval.event('myEvent','myDivId');// create eventdeval.event('myEvent','myDivId');// dispatch eventdeval.addEventListener('myEvent','myDivId');deval.dispatchEvent('myEvent');deval.removeEventListener('myEvent','myDivId');deval.parse();deval.parse('myDataEvalDivId');ordeval.parse(document.getElementById('myDataEvalDivId'));deval.update('myDataEvalDivId');I need this kind of url handling constantly, so it's logical to include this.
Try: alert( JSON.stringify(url) );
http://localhost/foo/bar/things/?myparam=some#key=value
url.myparam // some
url._parent // bar
url._first // foo
url._last // things
url._hash.key // value
url.1 // foo
url.2 // bar
etc.