Templates

jmvc comes with it's own template engine. It also supports other template engines (e.g. underscore) although wiring up events to invoke Controller actions will be easier with the build in template engine.

Templates are blocks of html inside script tags. Attributes are added that jmvc can understand which tell the template engine how to apply the model to the template to render the final html.

Attributes

Name Sample Description
bind bind="#model-property-name#" The bind attribute is used to render the value of the model property on the element. If static tags (e.g div, span) it will set the innerHTML and for input tags it will set the value attribute.
action action='{"event":"#event-name#","module":"#module-name#","controller","#controller-name#","action","#action-name#","model","#model-property#"}' The action attribute is used to wire an event on the tag which will invoke a controller action.
module module="#module-name#" The module attribute sets the default module scope so it does not need to be passed in multiple attributes on child tags that required it. It can be used to make the template cleaner and more maintainable.
controller controller="#controller-name#" The controller attribute sets the default controller scope so it does not need to be passed in multiple attributes on child tags that required it. It can be used to make the template cleaner and more maintainable.
repeat repeat="#model-property-name-of-array#" The repeat attribute will repeat the tag for each array element in the model with the supplied property name. If the model property is passed it will change the model scope on the repeated node and it's children.
condition condition="#boolean-expression#" The condition attribute will evaluate the expression in the attribute value. The expression should return a boolean. If the result is true the node will be added to the rendered html. If false the node and it's children will be excluded from the rendered html.
template template='template":"#my-sub-template#","model":"#propertyName#' The template attribute can be used to render a sub template from a parent template.

bind
e.g. bind="#model-property-name#"
The bind attribute is used to render the value of the model property on the element. If static tags (e.g div, span) it will set the innerHTML and for input tags it will set the value attribute.

For example take this template
<script type="text/template" id="my-template">
  <div bind="name"></div>
  <input bind="name"/>
</script>

Apply to this model
{
  name: 'John Smith',
}

You get this markup
<div>John Smith</div>
<input value="John Smith"/>

If you want to bind to the model itself (instead of a sub property) use a value of _self
e.g. bind="_self"

The bind attribute will be removed from the rendered html
action
e.g. action='{"event":"#event-name#","module":"#module-name#","controller","#controller-name#","action","#action-name#","model","#model-property#"}'

The action attribute is used to wire an event on the tag which will invoke a controller action.

The value of the action must be semantically correct JSON with the keys and values wrapped in double quotes. Use single quotes to wrap the JSON to avoid needing escape characters.

The model is the property on the model to pass to the action method when invoked. If you do not specify the model property name the entire model will be passed.

For example take this template
<script type="text/template" id="my-template">
  <input type="button" action='{"event":"click","module":"my-module", "controller":"my-controller", "action":"my-action", "model":"propertyName"}' value="Click Me"/>
</script>

Apply to this model
{
  propertyName: 'This is my model text'
}

It will register a click event on the element equivalent to this when invoked
jmvc.module('my-module').action('my-controller', 'my-action', 'This is my model Text');

The "click" event will be used as the default if not provided in the JSON.

The action attribute will be removed from the rendered html.
module
e.g. module="#module-name#"

The module attribute sets the default module scope so it does not need to be passed in multiple attributes on child tags that required it. It can be used to make the template cleaner and more maintainable.

For example the following samples are equivalent but the first is a little cleaner
<script type="text/template" id="my-template">
  <div module="my-module">
    <input type="button" action='{"controller":"my-controller", "action":"my-action", "model":"propertyName"}' value="Click Me"/>
    <input type="button" action='{"controller":"my-controller", "action":"my-action", "model":"propertyName"}' value="Click Me"/>
  </div>
</script>

<script type="text/template" id="my-template">
  <div>
    <input type="button" action='{"module":"my-module", "controller":"my-controller", "action":"my-action", "model":"propertyName"}' value="Click Me"/>
    <input type="button" action='{"module":"my-module", "controller":"my-controller", "action":"my-action", "model":"propertyName"}' value="Click Me"/>
  </div>
</script>

controller
e.g. controller="#controller-name#"

The controller attribute sets the default controller scope so it does not need to be passed in multiple attributes on child tags that required it. It can be used to make the template cleaner and more maintainable.

For example the following samples are equivalent but the first is a little cleaner
<script type="text/template" id="my-template">
  <div module="my-module" controller="my-controller">
    <input type="button" action='{"action":"my-action", "model":"propertyName"}' value="Click Me"/>
    <input type="button" action='{"action":"my-action", "model":"propertyName"}' value="Click Me"/>
  </div>
</script>

<script type="text/template" id="my-template">
  <div>
    <input type="button" action='{"module":"my-module", "controller":"my-controller", "action":"my-action", "model":"propertyName"}' value="Click Me"/>
    <input type="button" action='{"module":"my-module", "controller":"my-controller", "action":"my-action", "model":"propertyName"}' value="Click Me"/>
  </div>
</script>

repeat
e.g. repeat="#model-property-name-of-array#"

The repeat attribute will repeat the tag for each array element in the model with the supplied property name. If the model property is passed it will change the model scope on the repeated node and it's children.

If you do not want to change the scope (i.e. the current model is the list to repeat the tag for) then use _self for the attribute value.

For example take this template
<script type="text/template" id="my-template">
  <ul>
    <li repeat="items" bind="_self"></li>
  </ul>
</script>

Apply to this model
{
  items: ['first','second','third']
}

You get this markup
  <ul>
    <li>first</li>
    <li>second</li>
    <li>third</li>
  </ul>

If the model's array is empty the tag will be removed from the rendered html.

The repeat attribute will be removed from the rendered html.
condition
e.g. condition="#boolean-expression#"

The condition attribute will evaluate the expression in the attribute value. The expression should return a boolean. If the result is true the node will be added to the rendered html. If false the node and it's children will be excluded from the rendered html.

The this keyword can be used in the expression to reference the model of the current scope.

For example take this template
<script type="text/template" id="my-template">
  <div>Condition Example</div>
  <ul condition="this.items !=null && this.items.length > 0">
    <li repeat="items" bind="_self"></li>
  </ul>
</script>

Apply to this model
{
  items: ['first','second','third']
}

You get this markup
  <div>Condition Example</div>
  <ul>
    <li>first</li>
    <li>second</li>
    <li>third</li>
  </ul>

Apply to this model
{
  items: null
}

You get this markup
  <div>Condition Example</div>

The condition attribute will be removed from the rendered html.
template
e.g. template='template":"#my-sub-template#","model":"#propertyName#'

The template attribute can be used to render a sub template from a parent template.

The model is the property on the model to pass to the sub template as the model. If you do not specify the model property name the entire model will be passed.

For example take the following two templates
<script type="text/template" id="my-template">
  <div>
     This is from the parent template
    <div template='{"template":"my-sub-template","model":"propertyName"}'></div>
  </div>
</script>
<script type="text/template" id="my-sub-template">
  This is from the <span bind="_self"></span>
</script>

Apply "my-template" to this model
{
  propertyName: 'sub template'
}

You get this markup
  <div>
     This is from the parent template
    <div>This is from the sub template</div>
  </div>

The template attribute will be removed from the rendered html.

Last edited Jun 29, 2014 at 11:25 PM by dpembroke, version 51