Created
September 12, 2012 15:22
-
-
Save Pointy/3707350 to your computer and use it in GitHub Desktop.
An approach with doT templates to handling the "option"/"radio" coding mess
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!-- | |
This is the template source for the page containing a "select". In doT | |
templates the data object is by convention called "it" (though it can | |
be set to be anything). In this example, I'm inventing a field called | |
"choice", whose value would presumably have come from the server via | |
JSON (or whatever) as the property "choice" of the "it" parameter. | |
In the option elements you'll see the doT construct to fetch a value | |
from the "it" object, and you'll see that it involves what looks like | |
a function call. It *is* a function call, a call to another doT template | |
that is really the point of this. That's in a separate file. | |
--> | |
<form id='...' method=post action='...'> | |
<select name=choice> | |
<option {{= $T.optionVal("value1", it.choice) }}>The First Choice | |
<option {{= $T.optionVal("value2", it.choice) }}>The Second Choice | |
<option {{= $T.optionVal("value3", it.choice) }}>The Third Choice | |
</select> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!-- | |
Handling the list of options case | |
Assume that our "it" object looks like this: | |
{ | |
"settings" : { | |
"foo" : "low", | |
"bar" : "high", | |
"baz" : "low" | |
} | |
} | |
and we want a labeled set of radio button pairs. | |
I'll assume a sub-template, "$T.radioVal", that's | |
like the "optionVal" template only for radio buttons | |
("checked" instead of "selected" basically). Because | |
the "settings" value is an object and not an array (which, | |
if I had control of the server's JSON, I wouldn't do) | |
I'll need a function to transform that into an array, | |
which is of course a trivial utility. | |
--> | |
{{~ $T.toArray(it.settings) :setting }} | |
<h2>{{! setting.name }}</h2> | |
{{~ ["low", "high"] :lowHigh }} | |
<input type=radio name={{! setting.name }} {{= $T.radioVal(setting.value, lowHigh) }}> {{= lowHigh }} | |
{{~}} | |
{{~}} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!-- | |
This is my doT "optionVal" template. I compile my templates server-side | |
as part of my Ant-based application build (it's a Java application). | |
The build includes a home-grown Ant task that extracts templates from | |
the source and runs them through doT.js via Rhino. The templates are | |
then combined into a single JavaScript source file as properties of | |
an eventually global object called $T (my company is called "Tango" :-) | |
so references to templates is always via that symbol. | |
This simple template exploits the ability to override the default doT | |
template signature. I'll show what my code actually looks like; the | |
little header line is interpreted by the above-mentioned Ant task in | |
a way that should be obvious. | |
This template is extremely simple, and an invocation of it is not | |
much less typing than the code would be, but it's purpose is more to | |
reduce the chances for a typo in templates that call it. | |
--> | |
<%-- template optionVal(value, actual) --%> | |
value={{! value }} {{= value == actual ? "selected" : "" }} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!-- The "toArray" function (as a template, though it wouldn't have to be this way --> | |
<%-- template toArray(obj) --%> | |
{{ | |
var key, rv = []; | |
for (key in obj) | |
if (obj.hasOwnProperty(key)) | |
rv.push({name: key, value: obj[key]}); | |
return rv; | |
}} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
the difficulty, at least for a lot of templating engines, is that there's some namespace scope collision difficulty with two nested loops, when inside the inner loop you need to reference the key/iterator from the outer loop.