2

I'm using this pretty handy JavaScript template library: https://github.com/blueimp/JavaScript-Templates. I can create elements and add data to them as many are doing with underscore.js and mustache.js.

My problem comes when I want to add my own functions and not just strings to the object that will populate the template's various nodes. What i'd like to do is run the function nicetime() to update the time of my newly inserted <div>'s instead of just showing the time once.

Here's the code, and a full demo.

HTML:

<button data-id="1">1</button>
<div data-id="1"></div>
<div id="time_since"></div>

JS:

$(document.body).on('click', 'button', function(){
 var id= $(this).data('id');
 var data={id:id, string: "just now...", fxn: nicetime()};       
 var result = tmpl('<div id="string" data-id="'+id+'">{%=o.string%}</div>  
            <div id="function" data-id="'+id+'">{%=o.fxn%}</div>', data);      
   $('div[data-id="'+id+'"]').html(result);   
   nicetime();
});

function nicetime(){
  var time =  new Date();
  var comment_date = setInterval(function() { 
  var time2 = time_since(time.getTime()/1000);
       $('#time_since').html(time2); 
       return time2; 
    }, 
    1000);
}

note: inside nicetime() there is a function time_since() which is available on the jsfiddle. It is for formatting the date like this: "1 second ago...".

1 Answer 1

1

In javascript functions are objects just like any other variable.

Your problem is that you are invoking the function instead of assigning it to a property.

var data={id:id, string: "just now...", fxn: nicetime()}; 

instead use only the function name (without the parenthesis)

var data={id:id, string: "just now...", fxn: nicetime}; 

EDIT Actually I would take a different approach anyway. Instead of using a timer, just invoke the method as you previously were:

var data={id:id, string: "just now...", fxn: nicetime(this)};       

$('div[data-id="'+id+'"]').html(result);   
nicetime(this);

I modified nicetime to take the element that tracks the time (i assumed there was a button for each node (otherwise the data would be stored on each node)

function nicetime(el){
    var time =  $(el).data('start') || new Date();
    var time2 = time_since(time.getTime()/1000);
    $('#time_since').html(time2); 
    var comment_date = time2; //still need to figure out where to put this value
    $(el).data('start', time)
    return comment_date;
}
Sign up to request clarification or add additional context in comments.

6 Comments

oh yeah! duh, tim. thanks. hmm, the template is outputting the function as a string and not just returning the value. would you mind looking at the jsfiddle: jsfiddle.net/trpeters1/SpYXM/21 to help?
hi @jermel, thanks so much! can you re-include the setInterval() so that the time gets updated every second? The button is just for demo purposes to create the <div> which will be periodically updated (to be used in posting a comment, user can post many comments). I'd like to have the time update automatically without user input.
btw, really nice solution. I'd hadn't realized you could do something like this (i.e., the button keeping track of the time). Beautiful. I'll definitely keep this in mind in the future. But yeah, instead of clicking the button to update the time, it'd be nice if the time just updated automatically. thanks!
one other thing, what's the || notation mean? I've seen people use this but don't really understand it.
|| is a Logical OR operator. It returns the first value that is true, otherwise it returns false. A value is false if is false, null, undefined, empty string, 0, or NaN. You have to track intervals, but something like this would work ... clearInterval($(this).data('myinterval')); var btn = this; setInterval(function() {nicetime(btn);}, 1000);
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.