/*global define */ define(['jquery', 'underscore', 'backbone', 'models/filters/ToggleFilter', 'views/filters/FilterView', 'text!templates/filters/toggleFilter.html', 'text!templates/filters/booleanFilter.html'], function($, _, Backbone, ToggleFilter, FilterView, Template, BooleanTemplate) { 'use strict'; /** * @class ToggleFilterView * @classdesc Render a view of a single ToggleFilter model * @classcategory Views/Filters * @extends FilterView */ var ToggleFilterView = FilterView.extend( /** @lends ToggleFilterView.prototype */{ /** * A ToggleFilter model to be rendered in this view * @type {ToggleFilter} */ model: null, className: "filter toggle", template: _.template(Template), booleanTemplate: _.template(BooleanTemplate), events: { "change input" : "updateModel" }, initialize: function (options) { if( !options || typeof options != "object" ){ var options = {}; } this.model = options.model || new ToggleFilter(); }, render: function () { var modelJSON = this.model.toJSON(); modelJSON.id = this.model.cid; if( !this.model.get("falseLabel") ){ //If the value is the same as the trueValue, the checkbox should be checked modelJSON.checked = (this.model.get("values")[0] == this.model.get("trueValue"))? true : false; //Use the BooleanFilter template for toggles with only a true value this.$el.html( this.booleanTemplate( modelJSON ) ) .addClass("boolean"); } else{ this.$el.html( this.template( modelJSON ) ); } this.listenTo(this.model, "change:values", this.updateToggle); }, /** * Actions to perform after the render() function has completed and this view's * element is added to the webpage. */ postRender: function(){ this.setToggleWidth(); }, updateToggle: function(){ //If the model is set to true if( this.model.get("values").length && this.model.get("values")[0] == this.model.get("trueValue") ){ this.$("input").prop("checked", true); } else if( this.model.get("values").length && this.model.get("values")[0] == this.model.get("falseValue") ){ this.$("input").prop("checked", false); } else if( !this.model.get("values").length ){ this.$("input").prop("checked", false); } this.setToggleWidth(); }, /** * Gets the width of the toggle labels and sets the various CSS attributes * necessary for the switch to fully display each label */ setToggleWidth: function(){ //If there is no toggle element, exit now if( !this.$(".can-toggle-switch").length ){ return; } //Get the padding and widths of the switch elements var switchPadding = 24, onSwitchWidth = this.$(".true-label").width(), offSwitchWidth = this.$(".false-label").width(), totalSwitchWidth = onSwitchWidth + offSwitchWidth + (switchPadding * 2) + 2, isChecked = this.$("input[type='checkbox']").prop("checked"); //Set the width on the whole view this.$el.width(totalSwitchWidth + "px"); //Get the toggle switch element var toggleSwitch = this.$(".can-toggle-switch"); //Add an identifier to the toggle switch element toggleSwitch.attr("id", "toggle-" + this.model.cid); //Change the width of the toggle switch toggleSwitch.css("flex", "0 0 " + totalSwitchWidth + "px"); //Create CSS for the :before and :after pseudo elements, which is best done // by adding a style tag directly to the DOM if( isChecked ){ var newCSS = "#" + "toggle-" + this.model.cid + ":before{ " + "transform: translate3d(" + (onSwitchWidth + switchPadding) + "px, 0, 0);" + "width: " + (offSwitchWidth + switchPadding) + "px ;" + "}" + "#" + "toggle-" + this.model.cid + ":after{ " + "width: " + (onSwitchWidth + switchPadding) + "px;" + "transform: translate3d(0px, 0, 0);" + "}"; } else{ var newCSS = "#" + "toggle-" + this.model.cid + ":before{ " + "width: " + (offSwitchWidth + switchPadding) + "px ;" + "left: 0px ;" + "}" + "#" + "toggle-" + this.model.cid + ":after{ " + "width: " + (onSwitchWidth + switchPadding) + "px;" + "transform: translate3d(" + (offSwitchWidth + switchPadding) + "px, 0, 0);" + "}"; } //Get or create a style tag var styleTag = toggleSwitch.children("style"); if( !styleTag.length ){ styleTag = $(document.createElement("style")); toggleSwitch.append(styleTag); } //Add the CSS to the style tag styleTag.html(newCSS); }, /** * Updates the value set on the ToggleFilter Model associated with this view. * The filter value is grabbed from the checkbox element in this view. * */ updateModel: function(){ //Check if the checkbox is checked var isChecked = this.$("input").prop("checked"); //If the toggle is checked, then set the true toggle value on the model if( isChecked ){ if( this.model.get("values")[0] !== this.model.get("trueValue") ){ this.model.set("values", [ this.model.get("trueValue") ]); } } //If the toggle is not checked and there is no false value specified, // then remove the value from the model completely else if(!this.model.get("falseValue")){ if( this.model.get("values").length > 0 ){ this.model.set("values", []); } } //If the toggle is not checked and there is a false value specified, // then set the false toggle value on the model else{ if( this.model.get("values")[0] !== this.model.get("falseValue") ){ this.model.set("values", [ this.model.get("falseValue") ]); } } } }); return ToggleFilterView; });