Source: views/nutritionEditorView.js

/** Tracker Editor View
 * @namespace  nt.Views
 * @class nt.Views.Editor
 * @memberof! <global>
 * @extends Backbone.View */
nt.Views.Editor = Backbone.View.extend(/** @lends nt.Views.Editor# */{

    tagName: 'div',

    className: 'edit-item',

    editorTemplate: Handlebars.Templates.editor,

    count: 1,

    events: {
        'click #foodSave': 'saveFood',
        'click #foodClose': 'close',
        'click #servingIncrease': 'servingIncrease',
        'click #servingDecrease': 'servingDecrease'
    },

    /** Create a new food model this view will display and listen for changes */
    initialize: function() {
        this.createFood().listenTo(this.food, 'change', this.updateView);
    }, // initialize

    /** Re-render the editor view */
    updateView: function() {
        var prev = $('#dateTimePicker').data('DateTimePicker').date();
        $('#dateTimePicker').data('DateTimePicker').destroy();
        this.render().renderDatePicker();

        // If there was a date set, then set it to the previous value
        if(prev)
            this.$el.find('#dateTimePicker').data('DateTimePicker').date(prev);

    }, // updateView

    /** Render food */
    render: function() {
        // Populate nutrition inputs
        this.$el.html(this.editorTemplate( this.food.toJSON() ));

        // Enable chaining
        return this;

    }, // render

    /** Activate the date picker plugin */
    renderDatePicker: function() {
        // Use this.$el since template html is inserted in the DOM later
        this.$el.find('#dateTimePicker').datetimepicker({
            format: 'YYYY-MM-DD',
            allowInputToggle: true,
            widgetPositioning: { horizontal: 'right' }
        });

        return this;

    }, // renderDatePicker

    /** Display validation error */
    renderError: function(message) {
        var error = '<p class="bs-callout bs-callout-danger alert-danger"><i class="glyphicon glyphicon-exclamation-sign"></i> ' + message + '</p>';
        this.$el.find('#editor-top').append(error);

    }, // renderError

    /** Remove error message */
    removeError: function() {
        this.$el.find('.bs-callout').remove();
    }, // removeError

    /** Get original food attribute values from the nutrition view model */
    getFoodAttributes: function() {
        return this.model.toJSON();
    }, // getFoodAttributes

    /** Get the latest values for user editable attributes */
    userAttributes: function() {
        return {
            trackDate:  this.$el.find('#foodTrackDate').val().trim(),
            itemName: this.$el.find('#foodName').val().trim(),
            servingCount: this.count,
            moreThanOne: this.count > 1
        };

    }, // newAttributes

    /** Create a new model for the Tracker and copy the nutritionView's data to it */
    createFood: function() {
        var attrs = this.getFoodAttributes();

        // Create a new nutrition Model
        this.food = new nt.Models.Nutrition();

        // Add nutrition data
        this.food.set( attrs );

        var servings = this.food.get('servingCount');

        // Check the serving count and update the values
        if(servings > 1) {
            this.count = servings;
            this.food.valueUpdate(attrs, servings);
        }

        return this;

    }, // createFood

    /** Save the model to the collection and close the view */
    saveFood: function(e) {
        e.preventDefault();

        this.removeError();

        // Reset attribute values if serving count was changed
        if(this.count > 1)
            this.food.valueUpdate(this.getFoodAttributes(), 1);

        var userAttr = this.userAttributes();

        // Set user editable attributes
        this.food.set( userAttr, {validate: true} );

        var notValid = this.food.validationError;

        if(notValid) {
            this.renderError(notValid);
        } else {
            // Add and save food to tracker Collection
            nt.Collections.tracker.create(this.food, {merge: true});

            // Tell the Nutrition View the food was saved
            this.model.trigger('foodsaved');

            // Close this view
            this.close();
        }

    }, // saveFood

    /** Destroy date picker and this view */
    close: function() {
        $('#dateTimePicker').data('DateTimePicker').destroy();
        this.remove();
    }, // close

    /** Increase serving amount and update values */
    servingIncrease: function() {
        if(this.count >= 1) this.count++;

        this.food.valueUpdate(this.getFoodAttributes(), this.count);

    }, // servingIncrease

    /** Decrease serving amount and update values */
    servingDecrease: function() {
        if(this.count >= 2) this.count--;

        this.food.valueUpdate(this.getFoodAttributes(), this.count);

    } // servingDecrease

});