Laconic JavaScript (LJS)
NFX Template Compiler Tool supports the LJS (Laconic Java Script - LJS) sytax inserts right in the template content.
The LJS is based on laconic-syntax.
LJS is a Laconic representation of HTML DOM elements used for custom controls (i.e. dialogs, widgets etc.) dynamic rendering.
LJS compiler translates LJS into Javascript statements that build DOM elements.
Specify LJS compiler on ntc
cli: NFX.Templatization.TextJSTemplateCompiler
- compiles java script files or NFX.Templatization.NHTCompiler
- compiles the whole page:
ntc.exe src.js -ext ".result" /src /c "NFX.Templatization.TextJSTemplateCompiler, NFX"
ntc.exe my_page.nht -r -ext ".auto.cs" /src /c "NFX.Templatization.NHTCompiler, NFX"
LJS code is marked with /***
and ***/
delimiters. In the terms of Laconic config, every config segment becomes a DOM element and
config section attributes become become attributes of the DOM element, nested sub-section become sub-elements, section value becomes an inner text of the DOM element.
You can specify which element will be root for the new tree - first argument of function with LJS (id or element itself).
Other arguments also can be used in LJS code through ? js_code
syntax but in this case the first argument of the function will be considered as a root
even if you are not going specify it so you should add corresponding parameter.
function buildChangeSNameForm(root, dfltName) {
/***
form {
id=frmChangeSName
action="#"
method=post
div="Please enter new screen name:" {}
input {
type=text
name=sname
value=?dfltName
}
input {
type=submit
value=Submit
class=uiSmallButton
}
}
***/
}
After compilation that LJS code turns into:
function buildChangeSNameForm(root, dfltName) {
var Ør = arguments[0];
//try to find the root element by id
if (WAVE.isString(Ør)) Ør = WAVE.id(Ør);
var Ø1 = WAVE.ce('form'); // create new element-form
Ø1.setAttribute('id', 'frmChangeSName');
Ø1.setAttribute('action', '#');
Ø1.setAttribute('method', 'post');
var Ø2 = WAVE.ce('div');
Ø2.innerText='Please enter new screen name:';
Ø1.appendChild(Ø2);
var Ø3 = WAVE.ce('input');
Ø3.setAttribute('type', 'text');
Ø3.setAttribute('name', 'sname');
Ø3.setAttribute('value', dfltName);
Ø1.appendChild(Ø3);
var Ø4 = WAVE.ce('input');
Ø4.setAttribute('type', 'submit');
Ø4.setAttribute('value', 'Submit');
Ø4.setAttribute('class', 'uiSmallButton');
Ø1.appendChild(Ø4);
// if some root is specified, then append the new tree to it
if (WAVE.isObject(Ør)) Ør.appendChild(Ø1);
return Ø1;
}
And somewhere in your code you can call this function: var form = buildChangeSNameForm(null, user.first_name)
.
More complicated than references to the arguments javascript statements (conditions, loops, etc.) should be defined as laconic section:
function withCondition(root, count) {
/***
"? var a=count*2;" {}
input {
id=limitExceeded
type=checkbox
checked="?(a>10)"
}
"?if (a>10)" {
div {
class="? a>100 ? 'divCritical' : 'divWarning'"
}
}
***/
}
After compilation we have:
function withCondition(root, count) {
var Ør = arguments[0];
if (WAVE.isString(Ør)) Ør = WAVE.id(Ør);
var Ø1 = WAVE.ce('nfx');
var a = count * 2;
var Ø2 = WAVE.ce('input');
Ø2.setAttribute('id', 'limitExceeded');
Ø2.setAttribute('type', 'checkbox');
Ø2.checked = (a > 10);
Ø1.appendChild(Ø2);
if (a > 10) {
var Ø3 = WAVE.ce('div');
Ø3.setAttribute('class', a > 100 ? 'divCritical' : 'divWarning');
Ø1.appendChild(Ø3);
}
if (WAVE.isObject(Ør)) Ør.appendChild(Ø1);
return Ø1;
}
You can use ?this
as a pointer on current html element:
/***
table {
"? buildRow(?this);" {}
}
***/
And we get:
var Ø1 = WAVE.ce('table');
buildRow(Ø1);
Also you can create pointer to any item in tree with the construct ljsid=<your_identifier>
and use it:
/***
div {
ljsid=root
div = "some text" {}
"? if(root.hasChild())" {
...
}
}
***/
Result:
var Ø1 = WAVE.ce('div');
var Ø2 = WAVE.ce('div');
Ø2.innerText = 'some text';
Ø1.appendChild(Ø2);
if (Ø1.hasChild()) {
...
}
Besides that there is a possibility to make "inline" LJS insertions:
var div = "*#* div { h2='Header' {} p='Paragraph' {} } *#*";
turns into:
var div = (
function() {
var Ø1 = WAVE.ce('div');
var Ø2 = WAVE.ce('h2');
Ø2.innerText = 'Header';
Ø1.appendChild(Ø2);
var Ø3 = WAVE.ce('p');
Ø3.innerText ='Paragraph';
Ø1.appendChild(Ø3);
return Ø1;
})();
Usage of NHT code in LJS looks like:
/***
span="?'?[:SomeVariable]'"
***/
And output file will contain something like that:
const string s1 = @"var Ø1=WAVE.ce('span'); Ø1.innerText='";
const string s2 = @"';return Ø1;";
Target.Write(s1);
Target.Write(SomeVariable);
Target.Write(s2);