Fixed UI surrounding day separators.

* Reworked separator display. Now it is handled by the
  `EntryListView.renderOne` function instead of `EntryListView.render`. This
  way the proper separator is inserted even if we are only adding one new entry
  (like when creating a new entry) and not only when we refresh the list.
* Added a periodic refresh function that is triggered every minute. It
  refreshes the current entry so the duration is current, and refreshes te main
  list when a new day begins.
This commit is contained in:
Jonathan Bernard 2013-10-24 14:55:08 +00:00
parent f4eeb91d1a
commit c42a3805c2
3 changed files with 35 additions and 317 deletions

View File

@ -91,14 +91,6 @@ $(document).ready(function(){
_.bindAll(this, "url", "create"); },
/*create: function(model, options) {
if (!(model instanceof Backbone.Model)) {
model.user_id = this.timelineModel.get('user_id');
model.timeline_id = this.timelineModel.get('timeline_id'); }
else {
model.set('user_id') = this.timelineModel.get('user_id')
},*/
url: function() {
return "/ts_api/entries/" + this.timelineModel.get('user_id') + "/"
+ this.timelineModel.get('id'); } });
@ -338,6 +330,14 @@ $(document).ready(function(){
// add it to the container after the topmost separator ("Today")
this.topSeparator.after(el);
// If this entry and the next entry are not on the same day, put a
// day separator between them.
var nextDay = nextEntry ? nextEntry.get("timestamp") : new Date();
if (entry.get("timestamp").getDate() != nextDay.getDate()) {
this.topSeparator.after(ich.daySeparatorTemplate(
{separatorLabel: this.formatDaySeparator(
TS.app.currentDay, entry.get("timestamp")) })); }
// hide it if excluded
if (excluded) {
$(el).fadeOut('slow');
@ -379,14 +379,10 @@ $(document).ready(function(){
// clear existing elements in the view container
this.entryContainer.empty();
// last day we have printed a separator for
var today = new Date()
var currentDay = this.collection.at(0) ?
this.collection.at(0).get("timestamp"): today;
// add the top-most day separator
// add the top-most day separator; should always be "Today"
this.topSeparator = ich.daySeparatorTemplate({
separatorLabel: this.formatDaySeparator(today, today) });
separatorLabel: this.formatDaySeparator(
TS.app.currentDay, new Date()) });
this.entryContainer.prepend(this.topSeparator);
// iterate through the collection and render the elements.
@ -394,13 +390,6 @@ $(document).ready(function(){
var entry = this.collection.at(i);
var nextEntry = (i + 1 < len ? this.collection.at(i + 1) : null);
// we are rendering buttom up, which means we need to insert the
// day separator before the first entry of the *next* period
if (currentDay.getDate() != entry.get("timestamp").getDate()) {
this.topSeparator.after(ich.daySeparatorTemplate(
{separatorLabel: this.formatDaySeparator(today, currentDay)}));
currentDay = entry.get('timestamp'); }
this.renderOne(entry, nextEntry); } },
formatDaySeparator: function(today, labelDay) {
@ -415,27 +404,27 @@ $(document).ready(function(){
var monthDiff = today.getMonth() - labelDay.getMonth();
var dayDiff = today.getDate() - labelDay.getDate();
// more than a calendar year old
// more than a calendar year old: Weekday, Month Date, Year
if (yearDiff > 0) {
return days[labelDay.getDay()] + ", " +
months[labelDay.getMonth()] + " " + labelDay.getDate() +
", " + labelDay.getFullYear(); }
// same calendar year, more than a week ago
// same calendar year, more than a week ago: Weekday, Month Date
else if (monthDiff > 0 || dayDiff > 7) {
return days[labelDay.getDay()] + ", " +
months[labelDay.getMonth()] + " " + labelDay.getDate(); }
// less than a week ago, more than yesterday
// less than a week ago, more than yesterday, Last Weekday
else if (dayDiff > 1) {
return "Last " + days[labelDay.getDay()]; }
// yesterday
// Yesterday
else if (dayDiff == 1) { return "Yesterday"; }
// today
// Today
else if (dayDiff == 0) { return "Today"; } } });
TS.TimelineListView = Backbone.View.extend({
@ -536,9 +525,10 @@ $(document).ready(function(){
initialize: function() {
_.bindAll(this, 'initializeViews', 'loadInitialData',
'selectTimeline');
'periodicRefresh', 'selectTimeline');
appThis = this;
TS.app = this;
TS.app.currentDay = new Date();
// create the login dialog
this.loginDialog = new TS.LoginView
@ -548,12 +538,13 @@ $(document).ready(function(){
else {
// this is async (waiting for user input)
this.loginDialog.authenticate(function() {
appThis.initializeData(appThis.loadInitialData())}); } },
TS.app.initializeData(TS.app.loadInitialData())}); }
// Schedule our update function.
setInterval(this.periodicRefresh, 60000); },
initializeData: function(data) {
TS.app = this;
// create user data
this.user = {};
this.user.model = new TS.UserModel(data.user);
@ -610,6 +601,18 @@ $(document).ready(function(){
return data; },
periodicRefresh: function() {
var now = new Date();
if (this.currentDay.getDate() != now.getDate()) {
// It's a new day! Rerender our whole list.
this.entries.render(); }
else {
// Refresh our latest entry view so the duration is up to date.
var models = this.entries.collection.models;
models[models.length - 1].view.render(); } },
selectTimeline: function(e) {
if (e) {
// get the timeline model

View File

@ -1,247 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>TimeStamper - Simple Time Tracking</title>
<link href='http://fonts.googleapis.com/css?family=Arvo|Bentham|Cuprum|Cantarell|Geo|Josefin+Sans' rel='stylesheet' type='text/css'>
<link rel="stylesheet" media="screen" href="css/ts-screen.css" type="text/css"/>
<script type="text/javascript" src="js/jquery-1.5.js"></script>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
</head>
<body>
<div id="top">
<div id="timeline">
<span class="timeline-desc">Work-related activities.</span>
<input class="timeline-desc-input" type="text"/>
<div class="drop-menu">
<div class="timeline-id">(&nbsp;work&nbsp;)</div>
<input class="timeline-id-input" type="text"/>
<ul class="drop-menu-items">
<li class="timeline-link"><a href="#">jdb-labs</a></li>
<li class="timeline-link"><a href="#">personal</a></li>
<li class="timeline-link"><a href="#">vbs-suite</a></li>
</ul>
</div>
</div>
<div id="user">
<div class="fullname">Jonathan Bernard</div>
<input class='fullname-input' type='text'/>
<div class='drop-menu'>
<div class="username"> - jdbernard</div>
<ul class="drop-menu-items">
<li><a href="#">logout</a></li>
<li><a href="#">user info</a></li>
</ul>
</div>
</div>
</div>
<div id="entry-list">
<div class="day-seperator">
<h4 class='mark'>Today</h4>
<h5 class='timestamp'>start</h5>
<h5 class='duration'>duration</h5>
</div>
<div id="new-entry">
<input id="new-entry-input" class="mark-input"
placeholder="Start a new task..." type="text" />
</div>
<div id="entries">
<div class="entry">
<div class="mark"><img src="img/round_delete_icon&16.png" class="delete-icon"/><span>ITHelp: Entering tickets.</span><img src="img/notepad_2_icon&16.png" class="notes-icon"/></div>
<input class="mark-input" type="text"/>
<div class="timestamp">12:32</div>
<input class="timestamp-input" type="text"/>
<div class="duration">4<span class="tick-tock">hr </span>3<span class="tick-tock">m </span></div>
<div class="notes">Some notes should go here, but they should be hidden by default</div>
</div>
<div class="entry">
<div class="mark"><img src="img/round_delete_icon&16.png" class="delete-icon"/><span>ITHelp: Helping Steve wth WR Updates.</span><img src="img/notepad_2_icon&16.png" class="notes-icon"/></div>
<input class="mark-input" type="text"/>
<div class="timestamp">9:56</div>
<input class="timestamp-input" type="text"/>
<div class="duration">1<span class="tick-tock">hr </span>15<span class="tick-tock">m </span></div>
<div class="notes">Some notes should go here, but they should be hidden by default</div>
</div>
<div class="entry">
<div class="mark"><img src="img/round_delete_icon&16.png" class="delete-icon"/><span>Email</span><img src="img/notepad_2_icon&16.png" class="notes-icon"/></div>
<input class="mark-input" type="text"/>
<div class="timestamp">9:10</div>
<input class="timestamp-input" type="text"/>
<div class="duration">47<span class="tick-tock">m </span></div>
<div class="notes">Some notes should go here, but they should be hidden by default</div>
</div>
<div class="day-seperator">
<h4 class='mark'>Yesterday</h4>
<h5 class='timestamp'>start</h5>
<h5 class='duration'>duration</h5>
</div>
<div class="entry">
<div class="mark"><img src="img/round_delete_icon&16.png" class="delete-icon"/><span>ITHelp: Working #7801.</span><img src="img/notepad_2_icon&16.png" class="notes-icon"/></div>
<input class="mark-input" type="text"/>
<div class="timestamp">3:12 pm</div>
<input class="timestamp-input" type="text"/>
<div class="duration">12<span class="tick-tock">m </span></div>
<div class="notes">Some notes should go here, but they should be hidden by default</div>
</div>
<div class="entry">
<div class="mark"><img src="img/round_delete_icon&16.png" class="delete-icon"/><span>Lunch.</span><img src="img/notepad_2_icon&16.png" class="notes-icon"/></div>
<input class="mark-input" type="text"/>
<div class="timestamp">11:47 am</div>
<input class="timestamp-input" type="text"/>
<div class="duration">3<span class="tick-tock">hr </span>25<span class="tick-tock">m </span></div>
<div class="notes">Some notes should go here, but they should be hidden by default</div>
</div>
<div class="entry">
<div class="mark"><img src="img/round_delete_icon&16.png" class="delete-icon"/><span>ITHelp: Entering tickets.</span><img src="img/notepad_2_icon&16.png" class="notes-icon"/></div>
<input class="mark-input" type="text"/>
<div class="timestamp">9:20 am</div>
<input class="timestamp-input" type="text"/>
<div class="duration">2<span class="tick-tock">hr </span>27<span class="tick-tock">m </span></div>
<div class="notes">Some notes should go here, but they should be hidden by default</div>
</div>
<div class="entry">
<div class="mark"><img src="img/round_delete_icon&16.png" class="delete-icon"/><span>ITHelp: Reproducing #7796.</span><img src="img/notepad_2_icon&16.png" class="notes-icon"/></div>
<input class="mark-input" type="text"/>
<div class="timestamp">9:11 am</div>
<input class="timestamp-input" type="text"/>
<div class="duration">9<span class="tick-tock">m </span></div>
<div class="notes">Some notes should go here, but they should be hidden by default</div>
</div>
<div class="day-seperator">
<h4 class='mark'>Monday</h4>
<h5 class='timestamp'>start</h5>
<h5 class='duration'>duration</h5>
</div>
<div class="entry">
<div class="mark"><img src="img/round_delete_icon&16.png" class="delete-icon"/><span>ITHelp: Working #7733.</span><img src="img/notepad_2_icon&16.png" class="notes-icon"/></div>
<input class="mark-input" type="text"/>
<div class="timestamp">16:41</div>
<input class="timestamp-input" type="text"/>
<div class="duration">1<span class="tick-tock">hr </span>8<span class="tick-tock">m </span></div>
<div class="notes">Some notes should go here, but they should be hidden by default</div>
</div>
<div class="entry">
<div class="mark"><img src="img/round_delete_icon&16.png" class="delete-icon"/><span>Zend Training: Building Security Into Your PHP Applications</span><img src="img/notepad_2_icon&16.png" class="notes-icon"/></div>
<input class="mark-input" type="text"/>
<div class="timestamp">10:30</div>
<input class="timestamp-input" type="text"/>
<div class="duration">4<span class="tick-tock">hr </span>11<span class="tick-tock">m </span></div>
<div class="notes">Some notes should go here, but they should be hidden by default</div>
</div>
<div class="entry">
<div class="mark"><img src="img/round_delete_icon&16.png" class="delete-icon"/><span>ITHelp.</span><img src="img/notepad_2_icon&16.png" class="notes-icon"/></div>
<input class="mark-input" type="text"/>
<div class="timestamp">8:40</div>
<input class="timestamp-input" type="text"/>
<div class="duration">1<span class="tick-tock">hr </span>50<span class="tick-tock">m </span></div>
<div class="notes">Some notes should go here, but they should be hidden by default</div>
</div>
<div class="day-seperator">
<h4 class='mark'>Friday, April 29th</h4>
<h5 class='timestamp'>start</h5>
<h5 class='duration'>duration</h5>
</div>
<div class="entry">
<div class="mark"><img src="img/round_delete_icon&16.png" class="delete-icon"/><span>Training Steve: Databases and SQL</span><img src="img/notepad_2_icon&16.png" class="notes-icon"/></div>
<input class="mark-input" type="text"/>
<div class="timestamp">16:09</div>
<input class="timestamp-input" type="text"/>
<div class="duration">55<span class="tick-tock">m </span></div>
<div class="notes">Some notes should go here, but they should be hidden by default</div>
</div>
<div class="entry">
<div class="mark"><img src="img/round_delete_icon&16.png" class="delete-icon"/><span>Preparing Instructional Material: Database Basics</span><img src="img/notepad_2_icon&16.png" class="notes-icon"/></div>
<input class="mark-input" type="text"/>
<div class="timestamp">15:12</div>
<input class="timestamp-input" type="text"/>
<div class="duration">57<span class="tick-tock">m </span></div>
<div class="notes">Some notes should go here, but they should be hidden by default</div>
</div>
<div class="entry">
<div class="mark"><img src="img/round_delete_icon&16.png" class="delete-icon"/><span>ITHelp: Working #7729.</span><img src="img/notepad_2_icon&16.png" class="notes-icon"/></div>
<input class="mark-input" type="text"/>
<div class="timestamp">15:09</div>
<input class="timestamp-input" type="text"/>
<div class="duration">3<span class="tick-tock">m </span></div>
<div class="notes">Some notes should go here, but they should be hidden by default</div>
</div>
<div class="entry">
<div class="mark"><img src="img/round_delete_icon&16.png" class="delete-icon"/><span>ITHelp.</span><img src="img/notepad_2_icon&16.png" class="notes-icon"/></div>
<input class="mark-input" type="text"/>
<div class="timestamp">14:44</div>
<input class="timestamp-input" type="text"/>
<div class="duration">25<span class="tick-tock">m </span></div>
<div class="notes">Some notes should go here, but they should be hidden by default</div>
</div>
<div class="entry">
<div class="mark"><img src="img/round_delete_icon&16.png" class="delete-icon"/><span>ITHelp: Working #7728.</span><img src="img/notepad_2_icon&16.png" class="notes-icon"/></div>
<input class="mark-input" type="text"/>
<div class="timestamp">14:41</div>
<input class="timestamp-input" type="text"/>
<div class="duration">3<span class="tick-tock">m </span></div>
<div class="notes">Some notes should go here, but they should be hidden by default</div>
</div>
<div class="entry">
<div class="mark"><img src="img/round_delete_icon&16.png" class="delete-icon"/><span>ITHelp.</span><img src="img/notepad_2_icon&16.png" class="notes-icon"/></div>
<input class="mark-input" type="text"/>
<div class="timestamp">14:00</div>
<input class="timestamp-input" type="text"/>
<div class="duration">41<span class="tick-tock">m </span></div>
<div class="notes">Some notes should go here, but they should be hidden by default</div>
</div>
<div class="entry">
<div class="mark"><img src="img/round_delete_icon&16.png" class="delete-icon"/><span>Lunch.</span><img src="img/notepad_2_icon&16.png" class="notes-icon"/></div>
<input class="mark-input" type="text"/>
<div class="timestamp">13:05</div>
<input class="timestamp-input" type="text"/>
<div class="duration">55<span class="tick-tock">m </span></div>
<div class="notes">Some notes should go here, but they should be hidden by default</div>
</div>
<div class="entry">
<div class="mark"><img src="img/round_delete_icon&16.png" class="delete-icon"/><span>ITHelp: Working #7725.</span><img src="img/notepad_2_icon&16.png" class="notes-icon"/></div>
<input class="mark-input" type="text"/>
<div class="timestamp">12:40</div>
<input class="timestamp-input" type="text"/>
<div class="duration">20<span class="tick-tock">m </span></div>
<div class="notes">Some notes should go here, but they should be hidden by default</div>
</div>
<div class="entry">
<div class="mark"><img src="img/round_delete_icon&16.png" class="delete-icon"/><span>Zend Training: Building Security Into You PHP Applications.</span><img src="img/notepad_2_icon&16.png" class="notes-icon"/></div>
<input class="mark-input" type="text"/>
<div class="timestamp">10:30</div>
<input class="timestamp-input" type="text"/>
<div class="duration">2<span class="tick-tock">hr </span>10<span class="tick-tock">m </span></div>
<div class="notes">Some notes should go here, but they should be hidden by default</div>
</div>
<div class="entry">
<div class="mark"><img src="img/round_delete_icon&16.png" class="delete-icon"/><span>Zend Training: Preparing for security training.</span><img src="img/notepad_2_icon&16.png" class="notes-icon"/></div>
<input class="mark-input" type="text"/>
<div class="timestamp">09:25</div>
<input class="timestamp-input" type="text"/>
<div class="duration">1<span class="tick-tock">hr </span>5<span class="tick-tock">m </span></div>
<div class="notes">Some notes should go here, but they should be hidden by default</div>
</div>
<div class="entry">
<div class="mark"><img src="img/round_delete_icon&16.png" class="delete-icon"/><span>ITHelp: Working #7700.</span><img src="img/notepad_2_icon&16.png" class="notes-icon"/></div>
<input class="mark-input" type="text"/>
<div class="timestamp">09:17</div>
<input class="timestamp-input" type="text"/>
<div class="duration">8<span class="tick-tock">m </span></div>
<div class="notes">Some notes should go here, but they should be hidden by default</div>
</div>
</div>
</div>
<div class="footer">
Copyright 2011 <a href="http://www.jdb-labs.com"><span class="logo">JDB Labs</span> LLC.</a>
</div>
</body>
</html>

View File

@ -1,38 +0,0 @@
<html>
<head>
<title>Testing Backbone.js</title>
<link rel="stylesheet" media="screen" href="/css/dot-luv/jquery-ui-1.8.10.custom.css" type="text/css"/>
<script type="text/javascript" src="/js/jquery-1.5.min.js"></script>
<script type="text/javascript" src="/js/jquery-ui-1.8.10.custom.min.js"></script>
<script type="text/javascript" src="/js/underscore-min.js"></script>
<script type="text/javascript" src="/js/ICanHaz.js"></script>
<script type="text/javascript" src="/js/backbone-min.js"></script>
<script type="text/javascript" src="/js/test.js"></script>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
</head>
<body>
<div id="user">
<div class="username">username</div>
<div class="fullname">fullname</div>
</div>
<div id="entry-list"></div>
<div id="login-dialog" title="Login">
<form>
<fieldset>
<label for="login-name">Username:</label>
<input type="text" name="login-name" id="login-name"
class="text ui-widget-content ui-corner-all"></input>
<label for="login-password">Password:</label>
<input type="password" name="login-password" id="login-password"
class="text ui-widget-content ui-corner-all"></input>
</fieldset>
</form>
<p class="validate-tips"></p>
</div>
</body>
</html>