Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

mustache.js date formatting

I have started using mustache.js and so far I am very impressed. Although two things puzzle me. The first leads on to the second so bear with me.

My JSON

{"goalsCollection": [
    {
        "Id": "d5dce10e-513c-449d-8e34-8fe771fa464a",
        "Description": "Multum",
        "TargetAmount": 2935.9,
        "TargetDate": "/Date(1558998000000)/"
    },
    {
        "Id": "eac65501-21f5-f831-fb07-dcfead50d1d9",
        "Description": "quad nomen",
        "TargetAmount": 6976.12,
        "TargetDate": "/Date(1606953600000)/"
    }
]};

My handling function

function renderInvestmentGoals(collection) {
    var tpl = '{{#goalsCollection}}<tr><td>{{Description}}</td><td>{{TargetAmount}}</td><td>{{TargetDate}}</td></tr>{{/goalsCollection}}';
    $('#tblGoals tbody').html('').html(Mustache.to_html(tpl, collection));
}

Q1 As you can see my 'TargetDate' needs parsing but I am unsure of how to do that within my current function.

Q2 Say I wanted to perform some function or formatting on one or more of my objects before rendering, what is the best way of doing it?

like image 906
Dooie Avatar asked Apr 08 '12 17:04

Dooie


4 Answers

You can use a "lambda"

"TargetDate": "/Date(1606953600000)/",
"FormatDate": function() {
    return function(rawDate) {
        return rawDate.toString();
    }
}, ...

Then in the markup:

<td>
{{#FormatDate}}
    {{TargetDate}}
{{/FormatDate}}
</td>

From the link:

When the value is a callable object, such as a function or lambda, the object will be invoked and passed the block of text. The text passed is the literal block, unrendered.

like image 193
McGarnagle Avatar answered Nov 05 '22 10:11

McGarnagle


I have created a small extension for Mustache.js which enables the use of formatters inside of expressions, like {{expression | formatter}}

You would anyway need to create a function that parses your date value like this:


      Mustache.Formatters = {
        date: function( str) {
          var dt = new Date( parseInt( str.substr(6, str.length-8), 10));
          return (dt.getDate() + "/" + (dt.getMonth() + 1) + "/" + dt.getFullYear());
        }
      };

And then just add the formatter to your expressions:

{{TargetDate | date}}

You can grab the code from here: http://jvitela.github.io/mustache-wax/

like image 25
JVitela Avatar answered Nov 05 '22 09:11

JVitela


It's a long time ago but got on this looking for exactly the same. Mustachejs (now) allows you to call functions of the passed data and not only that; in the function the value of this is whatever value is true in a section.

If my template is like this:

{{#names}}
    <p>Name is:{{name}}</p>
    <!-- Comment will be removed by compileTemplates.sh
         #lastLogin is an if statement if lastLogin it'll do this 
         ^lastLogin will execute if there is not lastLogin      
    -->
    {{#lastLogin}}
    <!-- 
      formatLogin is a method to format last Login 
      the function has to be part of the data sent 
      to the template
    -->
    <p>Last Login:{{formatLogin}}</p>
    {{/lastLogin}}
    {{^lastLogin}}
    not logged in yet
    {{/lastLogin}}
    {{#name}}
     passing name to it now:{{formatLogin}}
    {{/name}}
{{/names}}

And Data like this:

var data={
    names:[
        {name:"Willy",lastLogin:new Date()}
    ],
    formatLogin:function(){
          //this is the lastDate used or name based on the block
                  //{{#name}}{{formatLogin}}{{/name}}:this is name
                  //{{#lastLogin}}{{formatLogin}}{{/lastLogin}}:this is lastLogin
          if(!/Date\]$/.test(Object.prototype.toString.call(this))){
              return "Invalid Date:"+this;
          }
          return this.getFullYear()
            +"-"+this.getMonth()+1
            +"-"+this.getDate();
    }
};
var output = Mustache.render(templates.test, data);
console.log(output);
like image 24
HMR Avatar answered Nov 05 '22 08:11

HMR


You can get the timestamp using simple String methods:

goalsCollection.targetDate = goalsCollection.targetDate.substring(6,18);

Of course, this depends on your timestamp being the same length each time. Another option is:

goalsCollection.targetDate = 
  goalsCollection.targetDate.substring(6, goalsCollection.targetDate.length - 1);

These techniques aren't specific to Mustache and can be used to manipulate data for any library. See the Mozilla Developer Center Documentation on substring for more details.

like image 1
jmort253 Avatar answered Nov 05 '22 08:11

jmort253