/** Tracker View
* @namespace nt.Views
* @class nt.Views.Tracker
* @memberof! <global>
* @extends Backbone.View */
nt.Views.Tracker = Backbone.View.extend(/** @lends nt.Views.Tracker# */{
el: '#tracker',
trackedTemplate: Handlebars.Templates.tracked,
emptyMessage: '<p>No foods are being tracked.</p><p>Do a search and add something!</p>',
emptyDate: '<p>There are no foods being tracked on this date.</p><p>Select another date or add a food.</p>',
events: {
'click #dtBack': 'dateBack',
'click #dtForward': 'dateForward',
'click #dtDisplay': 'dateDisplay',
'click .options a': 'setOption',
'click .tracked-delete': 'deleteFood',
'click .tracked-edit': 'openFood',
},
/** Setup Helpers, DOM ref, listener, datepicker, and fetch collection from localStorage */
initialize: function() {
_.bindAll(this, 'sumCals', 'sumFat', 'sumCarbs', 'sumProt');
Handlebars.registerHelper({
title: this.title,
sumCals: this.sumCals,
sumFat: this.sumFat,
sumCarbs: this.sumCarbs,
sumProt: this.sumProt,
show: this.show
});
this.$trackerResults = $('#tracker-results');
this.$dtp = $('#dtPicker');
this.listenTo(this.collection, 'update', this.render);
this.duration = moment.duration({'days' : 1});
this.initDatePicker();
this.collection.fetch();
}, // initialize
/** Display date tooltip if displayAll option is true */
title: function(date) {
if(nt.Option.displayAll) return new Handlebars.SafeString('title="' + date + '"');
}, // all
/** Sum of calories */
sumCals: function() {
return this.collection.calculateSum('valueCalories');
}, // sumCals
/** Sum of fats */
sumFat: function() {
return this.collection.calculateSum('valueTotalFat');
}, // sumFat
/** Sum of carbs */
sumCarbs: function() {
return this.collection.calculateSum('valueTotalCarb');
}, // sumCarbs
/** Sum of proteins */
sumProt: function() {
return this.collection.calculateSum('valueProteins');
}, // sumProt
/** Show nutrition value by number of servings */
show: function(attributeValue) {
var servings = this.attributes.servingCount;
var showValue = 0;
if(servings > 1) {
showValue = attributeValue * servings;
// If it's not a whole number, show only 2 decimal places
if(!Number.isInteger(showValue))
return Number(showValue).toFixed(2);
else
return showValue;
} // if servings > 1
else
return attributeValue;
}, // show
/** Check which render to run and update url route if in tracker view */
render: function() {
var isTracker = $('#tracker').hasClass('active');
if(nt.Option.displayAll) {
this.renderAll();
if(isTracker) nt.Router.Instance.navigate('tracker/all');
} else {
this.renderDate();
if(isTracker) nt.Router.Instance.navigate('tracker/date/' + nt.Option.trackerDate);
}
}, // render
/** Render all */
renderAll: function() {
this.$trackerResults.html('');
if(!this.collection.length)
this.$trackerResults.html( this.emptyMessage );
else
this.$trackerResults.append( this.trackedTemplate( this.collection ));
return this;
}, // renderAll
/** Render the tracker collection by date */
renderDate: function() {
// Clear previous list
this.$trackerResults.html('');
// Check if the Collection is empty
if(!this.collection.length)
this.$trackerResults.html( this.emptyMessage );
else {
var group = this.collection.getModelsByDate();
// Check if there are models for the date chosen
if(!group.length)
this.$trackerResults.html( this.emptyDate );
else
this.$trackerResults.append( this.trackedTemplate( group ));
}
return this;
}, // renderDate
/** Activate the date picker plugin */
initDatePicker: function() {
this.$dtp.datetimepicker({
format: 'MMMM D, YYYY',
defaultDate: nt.Option.trackerDate,
allowInputToggle: true
});
var self = this;
$('#dtPicker').on('dp.change', function(e) {
// Grab the current date from the date picker and set the tracker date option
nt.Option.trackerDate = $(this).data('DateTimePicker').date().format('YYYY-MM-DD');
// Re-render the view to display only models with the date selected
self.render();
});
}, // initDatePicker
/** Add a day to the current date */
dateBack: function() {
var currDate = this.$dtp.data('DateTimePicker').date();
var backDate = currDate.subtract(this.duration);
this.$dtp.data('DateTimePicker').date(backDate);
}, // dateBack
/** Subtract a day from the current date */
dateForward: function() {
var currDate = this.$dtp.data('DateTimePicker').date();
var forwardDate = currDate.add(this.duration);
this.$dtp.data('DateTimePicker').date(forwardDate);
}, // dateForward
/** Tracker display options */
dateDisplay: function() {
// Bold the current option
if(nt.Option.displayAll) {
$('#optAll').addClass('bold');
$('#optDate').removeClass('bold');
} else {
$('#optAll').removeClass('bold');
$('#optDate').addClass('bold');
}
}, // dateDisplay
/** Set tracker display option and re-render view */
setOption: function(e) {
e.preventDefault();
var id = $(e.target).attr('id');
// Show/hide the date picker and navigation
if(id === 'optDate') {
$('#dtContainer').show();
nt.Option.displayAll = false;
} else {
$('#dtContainer').hide();
nt.Option.displayAll = true;
}
// Re-render this view
this.render();
}, // setOption
/** Delete food model using id */
deleteFood: function(e) {
var id = $(e.target).data('id');
var food = this.collection.get(id);
food.destroy();
}, // deleteFood
/** Open nutrition view and style row in the tracker table */
openFood: function(e) {
var row = $(e.target).closest('.tracked-row');
// Open nutrition view
nt.Views.nutrition.openNutrition(e);
// Highlight row
row.css('background-color', '#b8dec0').addClass('highlight');
// Hide the tracker delete icons
$('.tracked-delete').hide();
} // openFood
});