Display a formatted timestamp in template - node.js

How do i format a timestamp inside the template? I followed a tutorial on building a chat and it works. Now i expanded the chat with some features like deleting the message and putting the time in front of the message. But when i write {{timestamp}} inside the template a UNIX timestamp is being given. How do i format it to show time like '6:12'. The timestamp is being stored in a Messages collection.
Is the right place to manipulate the timestamp inside of the
Template.Messages.created = function ( ) { ... }
function?
Thanks in advance.

Although not essential in this case, I would recommend using Moment.js, it makes working with dates and times in Javascript a breeze.
You can install the package from Atmosphere or download the script into your client dir then use a helper similar to the one below:-
Template.Messages.helpers({
created: function() {
var time = moment(this.timestamp);
return time.format('h:mm a');
}
});
NB: I've assumed timestamp is a var on the context object.

I use this library. It gives you all the date formatting you will ever need. With meteor just drop it in and you can use it in any helper to return the formatted date.
http://stevenlevithan.com/assets/misc/date.format.js

If you want to avoid libraries and manipulate with Javascript Date object I would suggest (this assumes that date is in ISO format 2010-06-15T00:00:00, wich you can get from Date.toISOString()):
Implement format method (thanks JavaScript equivalent to printf/string.format), put it in i.e. lib/utils.js:
String.prototype.format = function(args, index) {
return this.replace(/{(\w+)}/g, function(match, number) {
return typeof args[index[number]] != 'undefined'
? args[index[number]]
: match
;
});
};
Create helper (put it into client/client.js)
Handlebars.registerHelper('formatDate',function(input, pattern){
var iso = /^(\d{4})(?:-?W(\d+)(?:-?(\d+)D?)?|(?:-(\d+))?-(\d+))(?:[T ](\d+):(\d+)(?::(\d+)(?:\.(\d+))?)?)?(?:Z(-?\d*))?$/;
if(this[input]) {
var parts = this[input].match(iso);
return pattern.format(parts, {yyyy:1,MM:4,dd:5,hh:6,mm:7,ss:8,SSS:9});
}
return this[input];
});
Use the helper:
{{#each logs}}
<tr>
<td>{{formatDate 'ts' '{yyyy}-{MM}-{dd} {hh}:{mm}:{ss}'}}</td>

Have a look at this package swag which offers lots of useful handlebars helpers.
Checkout its date/time helpers: https://github.com/elving/swag#dates
You can format date/time as easily like:
var date = new Date()
{{formatDate date "%m/%d/%Y"}}
{{formatDate date "%I:%M%p"}}
{{formatDate date "%F"}}
{{formatDate date "%Y%m%dT%H%M%S%z"}}
07/26/2015
11:38PM
2015-08-28
20150828T233805-0004

Have a look at Template helpers and the JavaScript Date object.

Related

chrome.storage.sync.get always returns default value

I am developing a chrome extension and it requires me to keep track of the last date that the extension was run. To do so, I am using chrome.storage.sync, however, the get call always returns the value that I have set as the default. Below is the code.
chrome.storage.sync.get({theDate: {}}, function (dateResult) {
let currentDate = new Date();
let setDate = dateResult.theDate; // always set to {}
if (Object.keys(setDate).length === 0){ //if date has never been set before
setDate = currentDate;
}
if (setDate.toLocaleDateString() !== currentDate.toLocaleDateString()){
//do stuff if it is a different day than the last time extension was run
}
chrome.storage.sync.set({theDate: currentDate}, function () {
console.log("Current date set.");
});
});
Chrome extension storage API supports only JSON-compatible types such as strings, numbers, booleans, and arrays/objects that consist of those primitive types.
A Date object isn't JSON'ifiable so it can't be stored.
You can store Date.now() which is a number.
chrome.storage.sync.get({theDate: Date.now()}, ({theDate}) => {
if (new Date(theDate).toLocaleDateString() !== new Date().toLocaleDateString()) {
// do stuff if it is a different day than the last time extension was run
}
chrome.storage.sync.set({theDate: Date.now()});
});
You need to stringify the Date objects before storing them. Use JSON.stringify or the String constructor. Alternatively, you can call Date as a normal function rather than a constructor to get string objects rather than a Unix Time Stamp; or, better yet as wOxxOm suggests, use Date.now() to get the date as a number in milliseconds. 1
I must also note that in the first conditional, you check if the Date object retrieved from storage has any keys, but it should not, even if you could store the raw Date object. You may be misunderstanding how data is set in storage. Essentially dateResult === {theDate: currentDate}, and dateResult.theDate === currentDate. 2
edit: include wOxxOm's suggestion for completeness.

SuiteScript 2.0 Apply Time Zone to field

I need to "GET" a date field from a "Record" and apply a timezone, in 1.0 it was just using the getDateTimeValue and passing the timezone as the second parameter. In 2.0 you only have the generic getValue and when passing the TZ as the second value or passing it in the options package, it seems to just ignore it. Anyone have an idea? I can't find it in the docs.
thanks in advance
In SuiteScript 2.0 you need to use the N/format module to apply the timezone to the raw date.
An example of usage is as follows:
require(['N/format'], function () {
var format = require('N/format');
var now = new Date();
console.log(now);
var nyTime = format.format({
value:now,
type:format.Type.DATETIME,
timezone:format.Timezone.AMERICA_NEWYORK
});
console.log('NY time is ' + nyTime);
var gmt = format.format({
value:now,
type:format.Type.DATETIME,
timezone:format.Timezone.GMT
});
console.log('London time is ' + gmt);
});
You can paste the above into the console of a new transaction page and run it to demonstrate how it's used.

How to display the time from now for date retrieved by MongoDB using momentjs?

I am using moment.js to format the date to relative time retrieved from the mongodb passed to the view from the express router.
Here is my .pug file:
extends ../LoginLayout/LoginLayout
block content
- var createdAt = requser.local.profile.createdAt
script(type="text/javascript").
$(document).ready(function() {
var createdAt = createdAt;
$('.memberSince')[0].innerHTML = moment().startOf(createdAt).fromNow(true);
});
.parallax-container.display
.parallax
img(src='http://lorempixel.com/1920/900')
.container.white-text.center
img.circle(src=requser.local.profile.dp style='width: 200px;')
h1 #{requser.local.name}
h6 Member Since #[span.memberSince #{createdAt}]
This the screenshot of the output in the browser:
MORE INFO
If I comment out this line from .pug file, this is the output (I guess pug automatically formats the date)
// $('.memberSince')[0].innerHTML = moment().startOf(createdAt).fromNow(true);
Any help would be appreciated, thanks.
And the actual date stored in my MongoDB database is in the format:
I solved this myself.
Actually, what I did miss was I would have to pass String to the moment.
Here is the solved .pug:
- var createdAt = requser.local.profile.createdAt
script(type="text/javascript").
$(document).ready(function() {
var createdAt = Date.parse('!{createdAt}');
console.log(createdAt);
$('.memberSince')[0].innerHTML = moment(createdAt).fromNow(true);
})
I was also getting the output by simply using var createdAt = '!{createdAt}', but in browser's developer console, it showed some depreciated warning of the passed string, so I parsed it to date using Date.parse(), and then passed the value as a string to moment().
Also, you can see that there was no need of .startOf() and I am passing the true param to fromNow() as it simply removes the suffix ago from the output, as per docs.

Dynamically refresh a div without a straightful DOM manipulation

I have to update for example a table, a list if some values. I can insert new values and try to reload a entire page to show table or list values again.
If I give a try on Ajax updates I have to manipulate DOM, creating a bunch of new tags, concatenate and inject the new HTML on old one. This not a painful way, you even must re-type the code created before to exhibit new entries.
E.g: this is a fictitious example and illustrates what I mean:
$.ajax({
url: '/post/addComment/',
type: 'POST',
data: 'comment=' + comment,
beforeSend : function() {
//waiting message
$('#some_information_div').html('<strong>Updating...</strong>');
}
}).done(function(data) {
//new data comes here (by JSON, plain text, whatever...)
if (data.status == 'OK') {
//OHHH MAN WE HAVE TO POPULATE MANUALLY IT AGAIN
var c = '';
c = '<table>'
data.content.forEach(function(e) {
c += '<tr><td>' + e.name + '</td></tr>';
});
c += '</table>'
//update with new values
$('#some_information_div').html('');
$('#destination_table').html(c);
}
});
Unfortunately I have to do all the time with my lists and tables and somehow I have to re-type codes and manipulate it all by the javascript. I figured out something might be useful like does jQuery.load(), maybe it can fit what I want to, I have not tried it.
Some other languages and frameworks like JSF do it easily with "render technique", you directly update content without have to create and manipulate DOM in manually way.
Please, any kind of suggestion, any clue to this approach will be very helpful.
P.S.: The code sample tag doesn't work well here.
This can be done by using .load() jquery function. I have illustrated for some page 1.php and some table having id mytable
$('table#mytable').load('./1.php #mytable');
for constant refreshing --
setInterval(function() {
$('tablev#mytable').load('./1.php #mytable');
}, 5000);

jade (for nodejs) substrings in templates

Would anyone please advise how in jade for nodejs I can truncate a string to a number of characters/words, ideally conscious about the HTML markup within the string?
This should be similar to Django's truncatechars/truncatewords and truncatechars_html/truncatewords_html filters.
If this doesn't exist in jade, which way is right to go? I'm starting my first nodejs+express+CouchDB app, and could do it within nodejs code but it seems that filters are much more appropriate.
I would also consider writing a filter like this (and others) if I knew how :))
Just a quick illustration:
// in nodejs:
// body variable comes from CouchDB
res.render('home.jade', { title : "test", featuredNews : eval(body)});
// in home.jade template:
ul.thumbnails
each article in featuredNews.rows
a(href="#"+article.slug)
li.span4
div.value.thumbnail
img(align='left',src='http://example.com/image.png')
p!= article.value.description:truncatewords_html(30)
So I've made up the truncatewords_html(30) thing to illustrate what I think it should be similar to.
Will appreciate any ideas!
Thanks,
Igor
Here is a little "truncate_words" function:
function truncate( value, arg ) {
var value_arr = value.split( ' ' );
if( arg < value_arr.length ) {
value = value_arr.slice( 0, arg ).join( ' ' );
}
return value;
}
You can use it before sending the string to the template, or in the template using a helper method.
cheerio is a nice little library that does a subset of jquery and jsdom. Then it's easy:
app.helpers({
truncateWords_html : function(html, words){
return cheerio(html).text().split(/\s/).slice(0, words).join(" ")
}
})
Then, in a jade template use:
#{truncateWords_html(article.value.description, 30)}
This looks like a generic way to add any filters, hurray! :))

Resources