How to pass object to partial in dot.js

1.9k views Asked by At

I am trying to pass a new created object to my dot.js partial snippet like this :

try {
  var tempFn = doT.template($('#myTpl').text());
  var resultText = tempFn({
    "foo": "this snippet"
  });
  $('#result').html(resultText);
} catch (e) {
  $('#error').show().html(e);
  throw e;
}
#error {
  font-weight: bold;
  border: 1px solid red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/dot/1.0.3/doT.js"></script>

<!-- Template HERE -->
<script id="myTpl" type="template/doT.js">//<![CDATA[
{{##def.snippet:obj:
  <div>How to use {{=obj.x}}</div>
#}} 
{{#def.snippet:{"x":it.foo}}}
// ]]></script>


<div id="result"></div>
<div id="error" style="display: none;"></div>

But I get Template has an error: SyntaxError: Unexpected token : So how can I create and pass object (or multiple params) to a defined partial ?

What's going wrong ?

EDIT:

I have a schedule structure that come from a REST webservice like that :

"schedule": {
      "MONDAY": {
        "amOpenTime": {
          "hours": 8,
          "minutes": 30
        },
        "amCloseTime": null,
        "pmOpenTime": null,
        "pmCloseTime": {
          "hours": 17,
          "minutes": 0
        }
      },
      "TUESDAY": {
        "amOpenTime": {
          "hours": 8,
          "minutes": 31
        },
        "amCloseTime": null,
        "pmOpenTime": null,
        "pmCloseTime": {
          "hours": 17,
          "minutes": 40
        }
      },
      ....
}

I would to do not repeat my templating for each day because they must be processed in same way (DRY!) So I consider using partial snippet to print each line of my schedule (morning open/close time and afternoon open/close time). So as morning and afternoon div sould be threated in same way, I would like to create a second snippet to handle that. But for morning I need to pass only am prefixed data and pm prefixed data for afternoon like that :

{{##def.scheduleHalfDay:fday:
// multiple condition that I ommited
<div class="closed {{fday.type}}">{{fday.openTime.hours}}:{{fday.openTime.minutes}} - {{fday.closeTime.hours}}:{{fday.closeTime.minutes}}</div>
#}}

{{##def.scheduleRow:hday:
{{? (typeof hday.amOpenTime === "undefined" || hday.amOpenTime === null) && (typeof hday.pmCloseTime === "undefined" || hday.pmCloseTime == null) }}
<div class="closed">Closed</div>
{{??}}
{{#def.scheduleHalfDay:{"type": "morning", "openTime": hday.amOpenTime, "closeTime": hday.amCloseTime}}}--{{#def.scheduleHalfDay:{"type": "afternoon", "openTime": hday.pmOpenTime, "closeTime": hday.pmCloseTime}}}
{{?}}
#}}
<div class="agency-schedules">
    <div class="line"><div class="agency-schedules-day">Monday</div>{{#def.scheduleRow:it.horaires.MONDAY}}</div>
    <div class="line"><div class="agency-schedules-day">Tuesday</div>{{#def.scheduleRow:it.horaires.TUESDAY}}</div>
    ...
</div>

scheduleHalfDay are not working. So how can I pass my 3 parameters properly (without change data structure) ?

2

There are 2 answers

0
Dan On BEST ANSWER

Another way to make it work is to declare your param as a variable.

{{ var param = {"x":it.foo}; }} {{#def.snippet:param}}

8
Silkster On

First, your template has HTML in it so you should use .html() to get the template text.

Second, brackets, { and }, are reserved for doT template borders so you can't have them in templates.

Third, you don't need to use a partial there if all you're doing is passing an object to a template:

<script id="myTpl" type="template/doT.js">
  {{##def.snippet:
    <div>How to use {{=it.foo}}</div>
  #}}
  {{#def.snippet}}
</script>

Here's the simple working example: https://jsfiddle.net/silkster/wq5tjzrt/

Here's an example of transforming your position data and passing it to doT: https://jsfiddle.net/silkster/wq5tjzrt/2/

EDIT

From the new data you added, it seems what you need is an array of days. What you have in the original JSON data is a regular object with day names as properties. In my 3rd example below, I transform the object into an array of days and pass that to doT to output a schedule and use a partial template to show the opening and closing times for each day.

One edit I had to do in the partial template was to change the snippet so the correct properties are used in the template.

This might be the answer you're looking for: When you define the partial template, use the variable that will be available when the partial is used. "it" is the default, but if you use the partial in a loop as in my example, then define the partial with the variable as defined within the loop template.

Also, while transforming the data, add any data from calculations that you might need in your template. For example, if you need to determine if the opening time and closing time happen in am or pm, then do that while transforming the data and add the new key/value pairs to the transformed data.

Example 3 using your schedule data: https://jsfiddle.net/silkster/nq6guog9/