/files/fuelux/3.5.0/js/fuelux.js
JavaScript | 1787 lines | 1323 code | 325 blank | 139 comment | 250 complexity | 8bdb8cb8e43d61a88e0dfa9eaf66d108 MD5 | raw file
- /*!
- * Fuel UX v3.5.0
- * Copyright 2012-2015 ExactTarget
- * Licensed under the BSD-3-Clause license ()
- */
- // For more information on UMD visit: https://github.com/umdjs/umd/
- ( function( factory ) {
- if ( typeof define === 'function' && define.amd ) {
- define( [ 'jquery', 'bootstrap' ], factory );
- } else {
- factory( jQuery );
- }
- }( function( jQuery ) {
- if ( typeof jQuery === 'undefined' ) {
- throw new Error( 'Fuel UX\'s JavaScript requires jQuery' )
- }
- if ( typeof jQuery.fn.dropdown === 'undefined' || typeof jQuery.fn.collapse === 'undefined' ) {
- throw new Error( 'Fuel UX\'s JavaScript requires Bootstrap' )
- }
- ( function( $ ) {
- /*
- * Fuel UX Checkbox
- * https://github.com/ExactTarget/fuelux
- *
- * Copyright (c) 2014 ExactTarget
- * Licensed under the BSD New license.
- */
- // -- BEGIN MODULE CODE HERE --
- var old = $.fn.checkbox;
- // CHECKBOX CONSTRUCTOR AND PROTOTYPE
- var Checkbox = function( element, options ) {
- this.options = $.extend( {}, $.fn.checkbox.defaults, options );
- // cache elements
- this.$element = $( element ).is( 'input[type="checkbox"]' ) ? $( element ) : $( element ).find( 'input[type="checkbox"]:first' );
- this.$label = this.$element.parent();
- this.$parent = this.$label.parent( '.checkbox' );
- this.$toggleContainer = this.$element.attr( 'data-toggle' );
- this.state = {
- disabled: false,
- checked: false
- };
- if ( this.$parent.length === 0 ) {
- this.$parent = null;
- }
- if ( Boolean( this.$toggleContainer ) ) {
- this.$toggleContainer = $( this.$toggleContainer );
- } else {
- this.$toggleContainer = null;
- }
- // handle events
- this.$element.on( 'change.fu.checkbox', $.proxy( this.itemchecked, this ) );
- this.$label.on( 'click', $.proxy( this.toggle, this ) ); //make repeated label clicks work
- // set default state
- this.setState();
- };
- Checkbox.prototype = {
- constructor: Checkbox,
- setState: function( $chk ) {
- $chk = $chk || this.$element;
- this.state.disabled = Boolean( $chk.prop( 'disabled' ) );
- this.state.checked = Boolean( $chk.is( ':checked' ) );
- this._resetClasses();
- // set state of checkbox
- this._toggleCheckedState();
- this._toggleDisabledState();
- //toggle container
- this.toggleContainer();
- },
- enable: function() {
- this.state.disabled = false;
- this.$element.attr( 'disabled', false );
- this._resetClasses();
- this.$element.trigger( 'enabled.fu.checkbox' );
- },
- disable: function() {
- this.state.disabled = true;
- this.$element.attr( 'disabled', true );
- this._setDisabledClass();
- this.$element.trigger( 'disabled.fu.checkbox' );
- },
- check: function() {
- this.state.checked = true;
- this.$element.prop( 'checked', true );
- this.$element.attr( 'checked', 'checked' );
- this._setCheckedClass();
- this.$element.trigger( 'checked.fu.checkbox' );
- },
- uncheck: function() {
- this.state.checked = false;
- this.$element.prop( 'checked', false );
- this.$element.removeAttr( 'checked' );
- this._resetClasses();
- this.$element.trigger( 'unchecked.fu.checkbox' );
- },
- isChecked: function() {
- return this.state.checked;
- },
- toggle: function( e ) {
- //keep event from firing twice in Chrome
- if ( !e || ( e.target === e.originalEvent.target ) ) {
- this.state.checked = !this.state.checked;
- this._toggleCheckedState();
- if ( Boolean( e ) ) {
- //stop bubbling, otherwise event fires twice in Firefox.
- e.preventDefault();
- //make change event still fire (prevented by preventDefault to avoid firefox bug, see preceeding line)
- this.$element.trigger( 'change', e );
- }
- }
- },
- toggleContainer: function() {
- if ( Boolean( this.$toggleContainer ) ) {
- if ( this.state.checked ) {
- this.$toggleContainer.removeClass( 'hide' );
- this.$toggleContainer.attr( 'aria-hidden', 'false' );
- } else {
- this.$toggleContainer.addClass( 'hide' );
- this.$toggleContainer.attr( 'aria-hidden', 'true' );
- }
- }
- },
- itemchecked: function( element ) {
- this.setState( $( element.target ) );
- },
- destroy: function() {
- this.$parent.remove();
- // remove any external bindings
- // [none]
- // empty elements to return to original markup
- // [none]
- return this.$parent[ 0 ].outerHTML;
- },
- _resetClasses: function() {
- var classesToRemove = [];
- if ( !this.state.checked ) {
- classesToRemove.push( 'checked' );
- }
- if ( !this.state.disabled ) {
- classesToRemove.push( 'disabled' );
- }
- classesToRemove = classesToRemove.join( ' ' );
- this.$label.removeClass( classesToRemove );
- if ( this.$parent ) {
- this.$parent.removeClass( classesToRemove );
- }
- },
- _toggleCheckedState: function() {
- if ( this.state.checked ) {
- this.check();
- } else {
- this.uncheck();
- }
- },
- _toggleDisabledState: function() {
- if ( this.state.disabled ) {
- this.disable();
- } else {
- this.enable();
- }
- },
- _setCheckedClass: function() {
- this.$label.addClass( 'checked' );
- if ( this.$parent ) {
- this.$parent.addClass( 'checked' );
- }
- },
- _setDisabledClass: function() {
- this.$label.addClass( 'disabled' );
- if ( this.$parent ) {
- this.$parent.addClass( 'disabled' );
- }
- }
- };
- // CHECKBOX PLUGIN DEFINITION
- $.fn.checkbox = function( option ) {
- var args = Array.prototype.slice.call( arguments, 1 );
- var methodReturn;
- var $set = this.each( function() {
- var $this = $( this );
- var data = $this.data( 'fu.checkbox' );
- var options = typeof option === 'object' && option;
- if ( !data ) {
- $this.data( 'fu.checkbox', ( data = new Checkbox( this, options ) ) );
- }
- if ( typeof option === 'string' ) {
- methodReturn = data[ option ].apply( data, args );
- }
- } );
- return ( methodReturn === undefined ) ? $set : methodReturn;
- };
- $.fn.checkbox.defaults = {};
- $.fn.checkbox.Constructor = Checkbox;
- $.fn.checkbox.noConflict = function() {
- $.fn.checkbox = old;
- return this;
- };
- // DATA-API
- $( document ).on( 'mouseover.fu.checkbox.data-api', '[data-initialize=checkbox]', function( e ) {
- var $control = $( e.target ).closest( '.checkbox' ).find( '[type=checkbox]' );
- if ( !$control.data( 'fu.checkbox' ) ) {
- $control.checkbox( $control.data() );
- }
- } );
- // Must be domReady for AMD compatibility
- $( function() {
- $( '[data-initialize=checkbox] [type=checkbox]' ).each( function() {
- var $this = $( this );
- if ( !$this.data( 'fu.checkbox' ) ) {
- $this.checkbox( $this.data() );
- }
- } );
- } );
- } )( jQuery );
- ( function( $ ) {
- /*
- * Fuel UX Combobox
- * https://github.com/ExactTarget/fuelux
- *
- * Copyright (c) 2014 ExactTarget
- * Licensed under the BSD New license.
- */
- // -- BEGIN MODULE CODE HERE --
- var old = $.fn.combobox;
- // COMBOBOX CONSTRUCTOR AND PROTOTYPE
- var Combobox = function( element, options ) {
- this.$element = $( element );
- this.options = $.extend( {}, $.fn.combobox.defaults, options );
- this.$dropMenu = this.$element.find( '.dropdown-menu' );
- this.$input = this.$element.find( 'input' );
- this.$button = this.$element.find( '.btn' );
- this.$element.on( 'click.fu.combobox', 'a', $.proxy( this.itemclicked, this ) );
- this.$element.on( 'change.fu.combobox', 'input', $.proxy( this.inputchanged, this ) );
- this.$element.on( 'shown.bs.dropdown', $.proxy( this.menuShown, this ) );
- // set default selection
- this.setDefaultSelection();
- };
- Combobox.prototype = {
- constructor: Combobox,
- destroy: function() {
- this.$element.remove();
- // remove any external bindings
- // [none]
- // set input value attrbute in markup
- this.$element.find( 'input' ).each( function() {
- $( this ).attr( 'value', $( this ).val() );
- } );
- // empty elements to return to original markup
- // [none]
- return this.$element[ 0 ].outerHTML;
- },
- doSelect: function( $item ) {
- if ( typeof $item[ 0 ] !== 'undefined' ) {
- this.$selectedItem = $item;
- this.$input.val( this.$selectedItem.text().trim() );
- } else {
- this.$selectedItem = null;
- }
- },
- menuShown: function() {
- if ( this.options.autoResizeMenu ) {
- this.resizeMenu();
- }
- },
- resizeMenu: function() {
- var width = this.$element.outerWidth();
- this.$dropMenu.outerWidth( width );
- },
- selectedItem: function() {
- var item = this.$selectedItem;
- var data = {};
- if ( item ) {
- var txt = this.$selectedItem.text().trim();
- data = $.extend( {
- text: txt
- }, this.$selectedItem.data() );
- } else {
- data = {
- text: this.$input.val()
- };
- }
- return data;
- },
- selectByText: function( text ) {
- var $item = $( [] );
- this.$element.find( 'li' ).each( function() {
- if ( ( this.textContent || this.innerText || $( this ).text() || '' ).toLowerCase() === ( text || '' ).toLowerCase() ) {
- $item = $( this );
- return false;
- }
- } );
- this.doSelect( $item );
- },
- selectByValue: function( value ) {
- var selector = 'li[data-value="' + value + '"]';
- this.selectBySelector( selector );
- },
- selectByIndex: function( index ) {
- // zero-based index
- var selector = 'li:eq(' + index + ')';
- this.selectBySelector( selector );
- },
- selectBySelector: function( selector ) {
- var $item = this.$element.find( selector );
- this.doSelect( $item );
- },
- setDefaultSelection: function() {
- var selector = 'li[data-selected=true]:first';
- var item = this.$element.find( selector );
- if ( item.length > 0 ) {
- // select by data-attribute
- this.selectBySelector( selector );
- item.removeData( 'selected' );
- item.removeAttr( 'data-selected' );
- }
- },
- enable: function() {
- this.$element.removeClass( 'disabled' );
- this.$input.removeAttr( 'disabled' );
- this.$button.removeClass( 'disabled' );
- },
- disable: function() {
- this.$element.addClass( 'disabled' );
- this.$input.attr( 'disabled', true );
- this.$button.addClass( 'disabled' );
- },
- itemclicked: function( e ) {
- this.$selectedItem = $( e.target ).parent();
- // set input text and trigger input change event marked as synthetic
- this.$input.val( this.$selectedItem.text().trim() ).trigger( 'change', {
- synthetic: true
- } );
- // pass object including text and any data-attributes
- // to onchange event
- var data = this.selectedItem();
- // trigger changed event
- this.$element.trigger( 'changed.fu.combobox', data );
- e.preventDefault();
- // return focus to control after selecting an option
- this.$element.find( '.dropdown-toggle' ).focus();
- },
- inputchanged: function( e, extra ) {
- // skip processing for internally-generated synthetic event
- // to avoid double processing
- if ( extra && extra.synthetic ) return;
- var val = $( e.target ).val();
- this.selectByText( val );
- // find match based on input
- // if no match, pass the input value
- var data = this.selectedItem();
- if ( data.text.length === 0 ) {
- data = {
- text: val
- };
- }
- // trigger changed event
- this.$element.trigger( 'changed.fu.combobox', data );
- }
- };
- // COMBOBOX PLUGIN DEFINITION
- $.fn.combobox = function( option ) {
- var args = Array.prototype.slice.call( arguments, 1 );
- var methodReturn;
- var $set = this.each( function() {
- var $this = $( this );
- var data = $this.data( 'fu.combobox' );
- var options = typeof option === 'object' && option;
- if ( !data ) $this.data( 'fu.combobox', ( data = new Combobox( this, options ) ) );
- if ( typeof option === 'string' ) methodReturn = data[ option ].apply( data, args );
- } );
- return ( methodReturn === undefined ) ? $set : methodReturn;
- };
- $.fn.combobox.defaults = {
- autoResizeMenu: true
- };
- $.fn.combobox.Constructor = Combobox;
- $.fn.combobox.noConflict = function() {
- $.fn.combobox = old;
- return this;
- };
- // DATA-API
- $( document ).on( 'mousedown.fu.combobox.data-api', '[data-initialize=combobox]', function( e ) {
- var $control = $( e.target ).closest( '.combobox' );
- if ( !$control.data( 'fu.combobox' ) ) {
- $control.combobox( $control.data() );
- }
- } );
- // Must be domReady for AMD compatibility
- $( function() {
- $( '[data-initialize=combobox]' ).each( function() {
- var $this = $( this );
- if ( !$this.data( 'fu.combobox' ) ) {
- $this.combobox( $this.data() );
- }
- } );
- } );
- } )( jQuery );
- ( function( $ ) {
- /*
- * Fuel UX Datepicker
- * https://github.com/ExactTarget/fuelux
- *
- * Copyright (c) 2014 ExactTarget
- * Licensed under the BSD New license.
- */
- // -- BEGIN MODULE CODE HERE --
- var INVALID_DATE = 'Invalid Date';
- var MOMENT_NOT_AVAILABLE = 'moment.js is not available so you cannot use this function';
- var datepickerStack = [];
- var moment = false;
- var old = $.fn.datepicker;
- var requestedMoment = false;
- var runStack = function() {
- var i, l;
- requestedMoment = true;
- for ( i = 0, l = datepickerStack.length; i < l; i++ ) {
- datepickerStack[ i ].init.call( datepickerStack[ i ].scope );
- }
- datepickerStack = [];
- };
- //only load moment if it's there. otherwise we'll look for it in window.moment
- if ( typeof define === 'function' && define.amd ) { //check if AMD is available
- require( [ 'moment' ], function( amdMoment ) {
- moment = amdMoment;
- runStack();
- }, function( err ) {
- var failedId = err.requireModules && err.requireModules[ 0 ];
- if ( failedId === 'moment' ) {
- runStack();
- }
- } );
- } else {
- runStack();
- }
- // DATEPICKER CONSTRUCTOR AND PROTOTYPE
- var Datepicker = function( element, options ) {
- this.$element = $( element );
- this.options = $.extend( true, {}, $.fn.datepicker.defaults, options );
- this.$calendar = this.$element.find( '.datepicker-calendar' );
- this.$days = this.$calendar.find( '.datepicker-calendar-days' );
- this.$header = this.$calendar.find( '.datepicker-calendar-header' );
- this.$headerTitle = this.$header.find( '.title' );
- this.$input = this.$element.find( 'input' );
- this.$wheels = this.$element.find( '.datepicker-wheels' );
- this.$wheelsMonth = this.$element.find( '.datepicker-wheels-month' );
- this.$wheelsYear = this.$element.find( '.datepicker-wheels-year' );
- this.artificialScrolling = false;
- this.formatDate = this.options.formatDate || this.formatDate;
- this.inputValue = null;
- this.moment = false;
- this.momentFormat = null;
- this.parseDate = this.options.parseDate || this.parseDate;
- this.preventBlurHide = false;
- this.restricted = this.options.restricted || [];
- this.restrictedParsed = [];
- this.restrictedText = this.options.restrictedText;
- this.sameYearOnly = this.options.sameYearOnly;
- this.selectedDate = null;
- this.yearRestriction = null;
- this.$calendar.find( '.datepicker-today' ).on( 'click.fu.datepicker', $.proxy( this.todayClicked, this ) );
- this.$days.on( 'click.fu.datepicker', 'tr td button', $.proxy( this.dateClicked, this ) );
- this.$element.find( '.dropdown-menu' ).on( 'mousedown.fu.datepicker', $.proxy( this.dropdownMousedown, this ) );
- this.$header.find( '.next' ).on( 'click.fu.datepicker', $.proxy( this.next, this ) );
- this.$header.find( '.prev' ).on( 'click.fu.datepicker', $.proxy( this.prev, this ) );
- this.$headerTitle.on( 'click.fu.datepicker', $.proxy( this.titleClicked, this ) );
- this.$input.on( 'blur.fu.datepicker', $.proxy( this.inputBlurred, this ) );
- this.$input.on( 'focus.fu.datepicker', $.proxy( this.inputFocused, this ) );
- this.$wheels.find( '.datepicker-wheels-back' ).on( 'click.fu.datepicker', $.proxy( this.backClicked, this ) );
- this.$wheels.find( '.datepicker-wheels-select' ).on( 'click.fu.datepicker', $.proxy( this.selectClicked, this ) );
- this.$wheelsMonth.on( 'click.fu.datepicker', 'ul button', $.proxy( this.monthClicked, this ) );
- this.$wheelsYear.on( 'click.fu.datepicker', 'ul button', $.proxy( this.yearClicked, this ) );
- this.$wheelsYear.find( 'ul' ).on( 'scroll.fu.datepicker', $.proxy( this.onYearScroll, this ) );
- var init = function() {
- if ( this.checkForMomentJS() ) {
- moment = moment || window.moment; // need to pull in the global moment if they didn't do it via require
- this.moment = true;
- this.momentFormat = this.options.momentConfig.format;
- this.setCulture( this.options.momentConfig.culture );
- // support moment with lang (< v2.8) or locale
- moment.locale = moment.locale || moment.lang;
- }
- this.setRestrictedDates( this.restricted );
- if ( !this.setDate( this.options.date ) ) {
- this.$input.val( '' );
- this.inputValue = this.$input.val();
- }
- if ( this.sameYearOnly ) {
- this.yearRestriction = ( this.selectedDate ) ? this.selectedDate.getFullYear() : new Date().getFullYear();
- }
- };
- if ( requestedMoment ) {
- init.call( this );
- } else {
- datepickerStack.push( {
- init: init,
- scope: this
- } );
- }
- };
- Datepicker.prototype = {
- constructor: Datepicker,
- backClicked: function() {
- this.changeView( 'calendar' );
- },
- changeView: function( view, date ) {
- if ( view === 'wheels' ) {
- this.$calendar.hide().attr( 'aria-hidden', 'true' );
- this.$wheels.show().removeAttr( 'aria-hidden', '' );
- if ( date ) {
- this.renderWheel( date );
- }
- } else {
- this.$wheels.hide().attr( 'aria-hidden', 'true' );
- this.$calendar.show().removeAttr( 'aria-hidden', '' );
- if ( date ) {
- this.renderMonth( date );
- }
- }
- },
- checkForMomentJS: function() {
- if (
- ( $.isFunction( window.moment ) || ( typeof moment !== 'undefined' && $.isFunction( moment ) ) ) &&
- $.isPlainObject( this.options.momentConfig ) &&
- this.options.momentConfig.culture && this.options.momentConfig.format
- ) {
- return true;
- } else {
- return false;
- }
- },
- dateClicked: function( e ) {
- var $td = $( e.currentTarget ).parents( 'td:first' );
- var date;
- if ( $td.hasClass( 'restricted' ) ) {
- return;
- }
- this.$days.find( 'td.selected' ).removeClass( 'selected' );
- $td.addClass( 'selected' );
- date = new Date( $td.attr( 'data-year' ), $td.attr( 'data-month' ), $td.attr( 'data-date' ) );
- this.selectedDate = date;
- this.$input.val( this.formatDate( date ) );
- this.inputValue = this.$input.val();
- this.$input.focus();
- this.$element.trigger( 'dateClicked.fu.datepicker', date );
- },
- destroy: function() {
- this.$element.remove();
- // any external bindings
- // [none]
- // empty elements to return to original markup
- this.$days.find( 'tbody' ).empty();
- this.$wheelsYear.find( 'ul' ).empty();
- return this.$element[ 0 ].outerHTML;
- },
- disable: function() {
- this.$element.addClass( 'disabled' );
- this.$element.find( 'input, button' ).attr( 'disabled', 'disabled' );
- this.$element.find( '.input-group-btn' ).removeClass( 'open' );
- },
- dropdownMousedown: function() {
- var self = this;
- this.preventBlurHide = true;
- setTimeout( function() {
- self.preventBlurHide = false;
- }, 0 );
- },
- enable: function() {
- this.$element.removeClass( 'disabled' );
- this.$element.find( 'input, button' ).removeAttr( 'disabled' );
- },
- formatDate: function( date ) {
- var padTwo = function( value ) {
- var s = '0' + value;
- return s.substr( s.length - 2 );
- };
- if ( this.moment ) {
- return moment( date ).format( this.momentFormat );
- } else {
- return padTwo( date.getMonth() + 1 ) + '/' + padTwo( date.getDate() ) + '/' + date.getFullYear();
- }
- },
- getCulture: function() {
- if ( this.moment ) {
- return moment.locale();
- } else {
- throw MOMENT_NOT_AVAILABLE;
- }
- },
- getDate: function() {
- return ( !this.selectedDate ) ? new Date( NaN ) : this.selectedDate;
- },
- getFormat: function() {
- if ( this.moment ) {
- return this.momentFormat;
- } else {
- throw MOMENT_NOT_AVAILABLE;
- }
- },
- getFormattedDate: function() {
- return ( !this.selectedDate ) ? INVALID_DATE : this.formatDate( this.selectedDate );
- },
- getRestrictedDates: function() {
- return this.restricted;
- },
- inputBlurred: function( e ) {
- var inputVal = this.$input.val();
- var date;
- if ( inputVal !== this.inputValue ) {
- date = this.setDate( inputVal );
- if ( date === null ) {
- this.$element.trigger( 'inputParsingFailed.fu.datepicker', inputVal );
- } else if ( date === false ) {
- this.$element.trigger( 'inputRestrictedDate.fu.datepicker', date );
- } else {
- this.$element.trigger( 'changed.fu.datepicker', date );
- }
- }
- if ( !this.preventBlurHide ) {
- this.$element.find( '.input-group-btn' ).removeClass( 'open' );
- }
- },
- inputFocused: function( e ) {
- this.$element.find( '.input-group-btn' ).addClass( 'open' );
- },
- isInvalidDate: function( date ) {
- var dateString = date.toString();
- if ( dateString === INVALID_DATE || dateString === 'NaN' ) {
- return true;
- }
- return false;
- },
- isRestricted: function( date, month, year ) {
- var restricted = this.restrictedParsed;
- var i, from, l, to;
- if ( this.sameYearOnly && this.yearRestriction !== null && year !== this.yearRestriction ) {
- return true;
- }
- for ( i = 0, l = restricted.length; i < l; i++ ) {
- from = restricted[ i ].from;
- to = restricted[ i ].to;
- if (
- ( year > from.year || ( year === from.year && month > from.month ) || ( year === from.year && month === from.month && date >= from.date ) ) &&
- ( year < to.year || ( year === to.year && month < to.month ) || ( year === to.year && month === to.month && date <= to.date ) )
- ) {
- return true;
- }
- }
- return false;
- },
- monthClicked: function( e ) {
- this.$wheelsMonth.find( '.selected' ).removeClass( 'selected' );
- $( e.currentTarget ).parent().addClass( 'selected' );
- },
- next: function() {
- var month = this.$headerTitle.attr( 'data-month' );
- var year = this.$headerTitle.attr( 'data-year' );
- month++;
- if ( month > 11 ) {
- if ( this.sameYearOnly ) {
- return;
- }
- month = 0;
- year++;
- }
- this.renderMonth( new Date( year, month, 1 ) );
- },
- onYearScroll: function( e ) {
- if ( this.artificialScrolling ) {
- return;
- }
- var $yearUl = $( e.currentTarget );
- var height = ( $yearUl.css( 'box-sizing' ) === 'border-box' ) ? $yearUl.outerHeight() : $yearUl.height();
- var scrollHeight = $yearUl.get( 0 ).scrollHeight;
- var scrollTop = $yearUl.scrollTop();
- var bottomPercentage = ( height / ( scrollHeight - scrollTop ) ) * 100;
- var topPercentage = ( scrollTop / scrollHeight ) * 100;
- var i, start;
- if ( topPercentage < 5 ) {
- start = parseInt( $yearUl.find( 'li:first' ).attr( 'data-year' ), 10 );
- for ( i = ( start - 1 ); i > ( start - 11 ); i-- ) {
- $yearUl.prepend( '<li data-year="' + i + '"><button type="button">' + i + '</button></li>' );
- }
- this.artificialScrolling = true;
- $yearUl.scrollTop( ( $yearUl.get( 0 ).scrollHeight - scrollHeight ) + scrollTop );
- this.artificialScrolling = false;
- } else if ( bottomPercentage > 90 ) {
- start = parseInt( $yearUl.find( 'li:last' ).attr( 'data-year' ), 10 );
- for ( i = ( start + 1 ); i < ( start + 11 ); i++ ) {
- $yearUl.append( '<li data-year="' + i + '"><button type="button">' + i + '</button></li>' );
- }
- }
- },
- //some code ripped from http://stackoverflow.com/questions/2182246/javascript-dates-in-ie-nan-firefox-chrome-ok
- parseDate: function( date ) {
- var self = this;
- var BAD_DATE = new Date( NaN );
- var dt, isoExp, momentParse, momentParseWithFormat, tryMomentParseAll, month, parts, use;
- if ( date ) {
- if ( this.moment ) { //if we have moment, use that to parse the dates
- momentParseWithFormat = function( d ) {
- var md = moment( d, self.momentFormat );
- return ( true === md.isValid() ) ? md.toDate() : BAD_DATE;
- };
- momentParse = function( d ) {
- var md = moment( new Date( d ) );
- return ( true === md.isValid() ) ? md.toDate() : BAD_DATE;
- };
- tryMomentParseAll = function( d, parseFunc1, parseFunc2 ) {
- var pd = parseFunc1( d );
- if ( !self.isInvalidDate( pd ) ) {
- return pd;
- }
- pd = parseFunc2( pd );
- if ( !self.isInvalidDate( pd ) ) {
- return pd;
- }
- return BAD_DATE;
- };
- if ( 'string' === typeof( date ) ) {
- // Attempts to parse date strings using this.momentFormat, falling back on newing a date
- return tryMomentParseAll( date, momentParseWithFormat, momentParse );
- } else {
- // Attempts to parse date by newing a date object directly, falling back on parsing using this.momentFormat
- return tryMomentParseAll( date, momentParse, momentParseWithFormat );
- }
- } else { //if moment isn't present, use previous date parsing strategy
- if ( typeof( date ) === 'string' ) {
- dt = new Date( Date.parse( date ) );
- if ( !this.isInvalidDate( dt ) ) {
- return dt;
- } else {
- date = date.split( 'T' )[ 0 ];
- isoExp = /^\s*(\d{4})-(\d\d)-(\d\d)\s*$/;
- parts = isoExp.exec( date );
- if ( parts ) {
- month = parseInt( parts[ 2 ], 10 );
- dt = new Date( parts[ 1 ], month - 1, parts[ 3 ] );
- if ( month === ( dt.getMonth() + 1 ) ) {
- return dt;
- }
- }
- }
- } else {
- dt = new Date( date );
- if ( !this.isInvalidDate( dt ) ) {
- return dt;
- }
- }
- }
- }
- return new Date( NaN );
- },
- prev: function() {
- var month = this.$headerTitle.attr( 'data-month' );
- var year = this.$headerTitle.attr( 'data-year' );
- month--;
- if ( month < 0 ) {
- if ( this.sameYearOnly ) {
- return;
- }
- month = 11;
- year--;
- }
- this.renderMonth( new Date( year, month, 1 ) );
- },
- renderMonth: function( date ) {
- date = date || new Date();
- var firstDay = new Date( date.getFullYear(), date.getMonth(), 1 ).getDay();
- var lastDate = new Date( date.getFullYear(), date.getMonth() + 1, 0 ).getDate();
- var lastMonthDate = new Date( date.getFullYear(), date.getMonth(), 0 ).getDate();
- var $month = this.$headerTitle.find( '.month' );
- var month = date.getMonth();
- var now = new Date();
- var nowDate = now.getDate();
- var nowMonth = now.getMonth();
- var nowYear = now.getFullYear();
- var selected = this.selectedDate;
- var $tbody = this.$days.find( 'tbody' );
- var year = date.getFullYear();
- var curDate, curMonth, curYear, i, j, rows, stage, $td, $tr;
- if ( selected ) {
- selected = {
- date: selected.getDate(),
- month: selected.getMonth(),
- year: selected.getFullYear()
- };
- }
- $month.find( '.current' ).removeClass( 'current' );
- $month.find( 'span[data-month="' + month + '"]' ).addClass( 'current' );
- this.$headerTitle.find( '.year' ).text( year );
- this.$headerTitle.attr( {
- 'data-month': month,
- 'data-year': year
- } );
- $tbody.empty();
- if ( firstDay !== 0 ) {
- curDate = lastMonthDate - firstDay + 1;
- stage = -1;
- } else {
- curDate = 1;
- stage = 0;
- }
- rows = ( lastDate <= ( 35 - firstDay ) ) ? 5 : 6;
- for ( i = 0; i < rows; i++ ) {
- $tr = $( '<tr></tr>' );
- for ( j = 0; j < 7; j++ ) {
- $td = $( '<td></td>' );
- if ( stage === -1 ) {
- $td.addClass( 'last-month' );
- } else if ( stage === 1 ) {
- $td.addClass( 'next-month' );
- }
- curMonth = month + stage;
- curYear = year;
- if ( curMonth < 0 ) {
- curMonth = 11;
- curYear--;
- } else if ( curMonth > 11 ) {
- curMonth = 0;
- curYear++;
- }
- $td.attr( {
- 'data-date': curDate,
- 'data-month': curMonth,
- 'data-year': curYear
- } );
- if ( curYear === nowYear && curMonth === nowMonth && curDate === nowDate ) {
- $td.addClass( 'current-day' );
- } else if ( curYear < nowYear || ( curYear === nowYear && curMonth < nowMonth ) ||
- ( curYear === nowYear && curMonth === nowMonth && curDate < nowDate ) ) {
- $td.addClass( 'past' );
- if ( !this.options.allowPastDates ) {
- $td.addClass( 'restricted' ).attr( 'title', this.restrictedText );
- }
- }
- if ( this.isRestricted( curDate, curMonth, curYear ) ) {
- $td.addClass( 'restricted' ).attr( 'title', this.restrictedText );
- }
- if ( selected && curYear === selected.year && curMonth === selected.month && curDate === selected.date ) {
- $td.addClass( 'selected' );
- }
- if ( $td.hasClass( 'restricted' ) ) {
- $td.html( '<span><b class="datepicker-date">' + curDate + '</b></span>' );
- } else {
- $td.html( '<span><button type="button" class="datepicker-date">' + curDate + '</button></span>' );
- }
- curDate++;
- if ( stage === -1 && curDate > lastMonthDate ) {
- curDate = 1;
- stage = 0;
- } else if ( stage === 0 && curDate > lastDate ) {
- curDate = 1;
- stage = 1;
- }
- $tr.append( $td );
- }
- $tbody.append( $tr );
- }
- },
- renderWheel: function( date ) {
- var month = date.getMonth();
- var $monthUl = this.$wheelsMonth.find( 'ul' );
- var year = date.getFullYear();
- var $yearUl = this.$wheelsYear.find( 'ul' );
- var i, $monthSelected, $yearSelected;
- if ( this.sameYearOnly ) {
- this.$wheelsMonth.addClass( 'full' );
- this.$wheelsYear.addClass( 'hide' );
- } else {
- this.$wheelsMonth.removeClass( 'full' );
- this.$wheelsYear.removeClass( 'hide' );
- }
- $monthUl.find( '.selected' ).removeClass( 'selected' );
- $monthSelected = $monthUl.find( 'li[data-month="' + month + '"]' );
- $monthSelected.addClass( 'selected' );
- $monthUl.scrollTop( $monthUl.scrollTop() + ( $monthSelected.position().top - $monthUl.outerHeight() / 2 - $monthSelected.outerHeight( true ) / 2 ) );
- $yearUl.empty();
- for ( i = ( year - 10 ); i < ( year + 11 ); i++ ) {
- $yearUl.append( '<li data-year="' + i + '"><button type="button">' + i + '</button></li>' );
- }
- $yearSelected = $yearUl.find( 'li[data-year="' + year + '"]' );
- $yearSelected.addClass( 'selected' );
- this.artificialScrolling = true;
- $yearUl.scrollTop( $yearUl.scrollTop() + ( $yearSelected.position().top - $yearUl.outerHeight() / 2 - $yearSelected.outerHeight( true ) / 2 ) );
- this.artificialScrolling = false;
- $monthSelected.find( 'button' ).focus();
- },
- selectClicked: function() {
- var month = this.$wheelsMonth.find( '.selected' ).attr( 'data-month' );
- var year = this.$wheelsYear.find( '.selected' ).attr( 'data-year' );
- this.changeView( 'calendar', new Date( year, month, 1 ) );
- },
- setCulture: function( cultureCode ) {
- if ( !cultureCode ) {
- return false;
- }
- if ( this.moment ) {
- moment.locale( cultureCode );
- } else {
- throw MOMENT_NOT_AVAILABLE;
- }
- },
- setDate: function( date ) {
- var parsed = this.parseDate( date );
- if ( !this.isInvalidDate( parsed ) ) {
- if ( !this.isRestricted( parsed.getDate(), parsed.getMonth(), parsed.getFullYear() ) ) {
- this.selectedDate = parsed;
- this.renderMonth( parsed );
- this.$input.val( this.formatDate( parsed ) );
- } else {
- this.selectedDate = false;
- this.renderMonth();
- }
- } else {
- this.selectedDate = null;
- this.renderMonth();
- }
- this.inputValue = this.$input.val();
- return this.selectedDate;
- },
- setFormat: function( format ) {
- if ( !format ) {
- return false;
- }
- if ( this.moment ) {
- this.momentFormat = format;
- } else {
- throw MOMENT_NOT_AVAILABLE;
- }
- },
- setRestrictedDates: function( restricted ) {
- var parsed = [];
- var self = this;
- var i, l;
- var parseItem = function( val ) {
- if ( val === -Infinity ) {
- return {
- date: -Infinity,
- month: -Infinity,
- year: -Infinity
- };
- } else if ( val === Infinity ) {
- return {
- date: Infinity,
- month: Infinity,
- year: Infinity
- };
- } else {
- val = self.parseDate( val );
- return {
- date: val.getDate(),
- month: val.getMonth(),
- year: val.getFullYear()
- };
- }
- };
- this.restricted = restricted;
- for ( i = 0, l = restricted.length; i < l; i++ ) {
- parsed.push( {
- from: parseItem( restricted[ i ].from ),
- to: parseItem( restricted[ i ].to )
- } );
- }
- this.restrictedParsed = parsed;
- },
- titleClicked: function( e ) {
- this.changeView( 'wheels', new Date( this.$headerTitle.attr( 'data-year' ), this.$headerTitle.attr( 'data-month' ), 1 ) );
- },
- todayClicked: function( e ) {
- var date = new Date();
- if ( ( date.getMonth() + '' ) !== this.$headerTitle.attr( 'data-month' ) || ( date.getFullYear() + '' ) !== this.$headerTitle.attr( 'data-year' ) ) {
- this.renderMonth( date );
- }
- },
- yearClicked: function( e ) {
- this.$wheelsYear.find( '.selected' ).removeClass( 'selected' );
- $( e.currentTarget ).parent().addClass( 'selected' );
- }
- };
- // DATEPICKER PLUGIN DEFINITION
- $.fn.datepicker = function( option ) {
- var args = Array.prototype.slice.call( arguments, 1 );
- var methodReturn;
- var $set = this.each( function() {
- var $this = $( this );
- var data = $this.data( 'fu.datepicker' );
- var options = typeof option === 'object' && option;
- if ( !data ) $this.data( 'fu.datepicker', ( data = new Datepicker( this, options ) ) );
- if ( typeof option === 'string' ) methodReturn = data[ option ].apply( data, args );
- } );
- return ( methodReturn === undefined ) ? $set : methodReturn;
- };
- $.fn.datepicker.defaults = {
- allowPastDates: false,
- date: new Date(),
- formatDate: null,
- momentConfig: {
- culture: 'en',
- format: 'L' // more formats can be found here http://momentjs.com/docs/#/customization/long-date-formats/.
- },
- parseDate: null,
- restricted: [], //accepts an array of objects formatted as so: { from: {{date}}, to: {{date}} } (ex: [ { from: new Date('12/11/2014'), to: new Date('03/31/2015') } ])
- restrictedText: 'Restricted',
- sameYearOnly: false
- };
- $.fn.datepicker.Constructor = Datepicker;
- $.fn.datepicker.noConflict = function() {
- $.fn.datepicker = old;
- return this;
- };
- // DATA-API
- $( document ).on( 'mousedown.fu.datepicker.data-api', '[data-initialize=datepicker]', function( e ) {
- var $control = $( e.target ).closest( '.datepicker' );
- if ( !$control.data( 'datepicker' ) ) {
- $control.datepicker( $control.data() );
- }
- } );
- //used to prevent the dropdown from closing when clicking within it's bounds
- $( document ).on( 'click.fu.datepicker.data-api', '.datepicker .dropdown-menu', function( e ) {
- var $target = $( e.target );
- if ( !$target.is( '.datepicker-date' ) || $target.closest( '.restricted' ).length ) {
- e.stopPropagation();
- }
- } );
- //used to prevent the dropdown from closing when clicking on the input
- $( document ).on( 'click.fu.datepicker.data-api', '.datepicker input', function( e ) {
- e.stopPropagation();
- } );
- $( function() {
- $( '[data-initialize=datepicker]' ).each( function() {
- var $this = $( this );
- if ( $this.data( 'datepicker' ) ) {
- return;
- }
- $this.datepicker( $this.data() );
- } );
- } );
- } )( jQuery );
- ( function( $ ) {
- /*
- * Fuel UX Dropdown Auto Flip
- * https://github.com/ExactTarget/fuelux
- *
- * Copyright (c) 2014 ExactTarget
- * Licensed under the BSD New license.
- */
- // -- BEGIN MODULE CODE HERE --
- $( document.body ).on( 'click.fu.dropdown-autoflip', '[data-toggle=dropdown][data-flip]', function( event ) {
- if ( $( this ).data().flip === "auto" ) {
- // have the drop down decide where to place itself
- _autoFlip( $( this ).next( '.dropdown-menu' ) );
- }
- } );
- // For pillbox suggestions dropdown
- $( document.body ).on( 'suggested.fu.pillbox', function( event, element ) {
- _autoFlip( $( element ) );
- $( element ).parent().addClass( 'open' );
- } );
- function _autoFlip( menu ) {
- // hide while the browser thinks
- $( menu ).css( {
- visibility: "hidden"
- } );
- // decide where to put menu
- if ( dropUpCheck( menu ) ) {
- menu.parent().addClass( "dropup" );
- } else {
- menu.parent().removeClass( "dropup" );
- }
- // show again
- $( menu ).css( {
- visibility: "visible"
- } );
- }
- function dropUpCheck( element ) {
- // caching container
- var $container = _getContainer( element );
- // building object with measurementsances for later use
- var measurements = {};
- measurements.parentHeight = element.parent().outerHeight();
- measurements.parentOffsetTop = element.parent().offset().top;
- measurements.dropdownHeight = element.outerHeight();
- measurements.containerHeight = $container.overflowElement.outerHeight();
- // this needs to be different if the window is the container or another element is
- measurements.containerOffsetTop = ( !!$container.isWindow ) ? $container.overflowElement.scrollTop() : $container.overflowElement.offset().top;
- // doing the calculations
- measurements.fromTop = measurements.parentOffsetTop - measurements.containerOffsetTop;
- measurements.fromBottom = measurements.containerHeight - measurements.parentHeight - ( measurements.parentOffsetTop - measurements.containerOffsetTop );
- // actual determination of where to put menu
- // false = drop down
- // true = drop up
- if ( measurements.dropdownHeight < measurements.fromBottom ) {
- return false;
- } else if ( measurements.dropdownHeight < measurements.fromTop ) {
- return true;
- } else if ( measurements.dropdownHeight >= measurements.fromTop && measurements.dropdownHeight >= measurements.fromBottom ) {
- // decide which one is bigger and put it there
- if ( measurements.fromTop >= measurements.fromBottom ) {
- return true;
- } else {
- return false;
- }
- }
- }
- function _getContainer( element ) {
- var containerElement, isWindow;
- if ( element.attr( 'data-target' ) ) {
- containerElement = element.attr( 'data-target' );
- isWindow = false;
- } else {
- containerElement = window;
- isWindow = true;
- }
- $.each( element.parents(), function( index, value ) {
- if ( $( value ).css( 'overflow' ) !== 'visible' ) {
- containerElement = value;
- isWindow = false;
- return false;
- }
- } );
- return {
- overflowElement: $( containerElement ),
- isWindow: isWindow
- };
- }
- // register empty plugin
- $.fn.dropdownautoflip = function() { /* empty */ };
- } )( jQuery );
- ( function( $ ) {
- /*
- * Fuel UX Loader
- * https://github.com/ExactTarget/fuelux
- *
- * Copyright (c) 2014 ExactTarget
- * Licensed under the BSD New license.
- */
- // -- BEGIN MODULE CODE HERE --
- var old = $.fn.loader;
- // LOADER CONSTRUCTOR AND PROTOTYPE
- var Loader = function( element, options ) {
- this.$element = $( element );
- this.options = $.extend( {}, $.fn.loader.defaults, options );
- this.begin = ( this.$element.is( '[data-begin]' ) ) ? parseInt( this.$element.attr( 'data-begin' ), 10 ) : 1;
- this.delay = ( this.$element.is( '[data-delay]' ) ) ? parseFloat( this.$element.attr( 'data-delay' ) ) : 150;
- this.end = ( this.$element.is( '[data-end]' ) ) ? parseInt( this.$element.attr( 'data-end' ), 10 ) : 8;
- this.frame = ( this.$element.is( '[data-frame]' ) ) ? parseInt( this.$element.attr( 'data-frame' ), 10 ) : this.begin;
- this.isIElt9 = false;
- this.timeout = {};
- var ieVer = this.msieVersion();
- if ( ieVer !== false && ieVer < 9 ) {
- this.$element.addClass( 'iefix' );
- this.isIElt9 = true;
- }
- this.$element.attr( 'data-frame', this.frame + '' );
- this.play();
- };
- Loader.prototype = {
- constructor: Loader,
- destroy: function() {
- this.$element.remove();
- // any external bindings
- // [none]
- // empty elements to return to original markup
- // [none]
- // returns string of markup
- return this.$element[ 0 ].outerHTML;
- },
- ieRepaint: function() {
- if ( this.isIElt9 ) {
- this.$element.addClass( 'iefix_repaint' ).removeClass( 'iefix_repaint' );
- }
- },
- msieVersion: function() {
- var ua = window.navigator.userAgent;
- var msie = ua.indexOf( 'MSIE ' );
- if ( msie > 0 ) {
- return parseInt( ua.substring( msie + 5, ua.indexOf( ".", msie ) ), 10 );
- } else {
- return false;
- }
- },
- next: function() {
- this.frame++;
- if ( this.frame > this.end ) {
- this.frame = this.begin;
- }
- this.$element.attr( 'data-frame', this.frame + '' );
- this.ieRepaint();
- },
- pause: function() {
- clearTimeout( this.timeout );
- },
- play: function() {
- var self = this;
- clearTimeout( this.timeout );
- this.timeout = setTimeout( function() {
- self.next();
- self.play();
- }, this.delay );
- },
- previous: function() {
- this.frame--;
- if ( this.frame < this.begin ) {
- this.frame = this.end;
- }
- this.$element.attr( 'data-frame', this.frame + '' );
- this.ieRepaint();
- },
- reset: function() {
- this.frame = this.begin;
- this.$element.attr( 'data-frame', this.frame + '' );
- this.ieRepaint();
- }
- };
- // LOADER PLUGIN DEFINITION
- $.fn.loader = function( option ) {
- var args = Array.prototype.slice.call( arguments, 1 );
- var methodReturn;
- var $set = this.each( function() {
- var $this = $( this );
- var data = $this.data( 'fu.loader' );
- var options = typeof option === 'object' && option;
- if ( !data ) $this.data( 'fu.loader', ( data = new Loader( this, options ) ) );
- if ( typeof option === 'string' ) methodReturn = data[ option ].apply( data, args );
- } );
- return ( methodReturn === undefined ) ? $set : methodReturn;
- };
- $.fn.loader.defaults = {};
- $.fn.loader.Constructor = Loader;
- $.fn.loader.noConflict = function() {
- $.fn.loader = old;
- return this;
- };
- // INIT LOADER ON DOMCONTENTLOADED
- $( function() {
- $( '[data-initialize=loader]' ).each( function() {
- var $this = $( this );
- if ( !$this.data( 'fu.loader' ) ) {
- $this.loader( $this.data() );
- }
- } );
- } );
- } )( jQuery );
- ( function( $ ) {
- /*
- * Fuel UX Placard
- * https://github.com/ExactTarget/fuelux
- *
- * Copyright (c) 2014 ExactTarget
- * Licensed under the BSD New license.
- */
- // -- BEGIN MODULE CODE HERE --
- var old = $.fn.placard;
- // PLACARD CONSTRUCTOR AND PROTOTYPE
- var Placard = function( element, options ) {
- var self = this;
- this.$element = $( element );
- this.options = $.extend( {}, $.fn.placard.defaults, options );
- this.$accept = this.$element.find( '.placard-accept' );
- this.$cancel = this.$element.find( '.placard-cancel' );
- this.$field = this.$element.find( '.placard-field' );
- this.$footer = this.$element.find( '.placard-footer' );
- this.$header = this.$element.find( '.placard-header' );
- this.$popup = this.$element.find( '.placard-popup' );
- this.actualValue = null;
- this.clickStamp = '_';
- this.previousValue = '';
- if ( this.options.revertOnCancel === -1 ) {
- this.options.revertOnCancel = ( this.$accept.length > 0 ) ? true : false;
- }
- this.$field.on( 'focus.fu.placard', $.proxy( this.show, this ) );
- this.$accept.on( 'click.fu.placard', $.proxy( this.complete, this, 'accept' ) );
- this.$cancel.on( 'click.fu.placard', function( e ) {
- e.preventDefault();
- self.complete( 'cancel' );
- } );
- this.ellipsis();
- };
- Placard.prototype = {
- constructor: Placard,
- complete: function( action ) {
- var func = this.options[ 'on' + action[ 0 ].toUpperCase() + action.substring( 1 ) ];
- var obj = {
- previousValue: this.previousValue,
- value: this.$field.val()
- };
- if ( func ) {
- func( obj );
- this.$element.trigger( action, obj );
- } else {
- if ( action === 'cancel' && this.options.revertOnCancel ) {
- this.$field.val( this.previousValue );
- }
- this.$element.trigger( action, obj );
- this.hide();
- }
- },
- destroy: function() {
- this.$element.remove();
- // remove any external bindings
- $( document ).off( 'click.fu.placard.externalClick.' + this.clickStamp );
- // set input value attrbute
- this.$element.find( 'input' ).each( function() {
- $( this ).attr( 'value', $( this ).val() );
- } );
- // empty elements to return to original markup
- // [none]
- // return string of markup
- return this.$element[ 0 ].outerHTML;
- },
- disable: function() {
- this.$element.addClass( 'disabled' );
- this.$field.attr( 'disabled', 'disabled' );
- this.hide();
- },
- ellipsis: function() {
- var field, i, str;
- if ( this.$element.attr( 'data-ellipsis' ) === 'true' ) {
- field = this.$field.get( 0 );
- if ( this.$field.is( 'input' ) ) {
- field.scrollLeft = 0;
- } else {
- field.scrollTop = 0;
- if ( field.clientHeight < field.scrollHeight ) {
- this.actualValue = this.$field.val();
- this.$field.val( '' );
- str = '';
- i = 0;
- while ( field.clientHeight >= field.scrollHeight ) {
- str += this.actualValue[ i ];
- this.$field.val( str + '...' );
- i++;
- }
- str = ( str.length > 0 ) ? str.substring( 0, str.length - 1 ) : '';
- this.$field.val( str + '...' );
- }
- }
- }
- },
- enable: function() {
- this.$element.removeClass( 'disabled' );
- this.$field.removeAttr( 'disabled' );
- },
- externalClickListener: function( e, force ) {
- if ( force === true || this.isExternalClick( e ) ) {
- this.complete( this.options.externalClickAction );
- }
- },
- getValue: function() {
- if ( this.actualValue !== null ) {
- return this.actualValue;
- } else {
- return this.$field.val();
- }
- },
- hide: function() {
- if ( !this.$element.hasClass( 'showing' ) ) {
- return;
- }
- this.$element.removeClass( 'showing' );
- this.ellipsis();
- $( document ).off( 'click.fu.placard.externalClick.' + this.clickStamp );
- this.$element.trigger( 'hidden.fu.placard' );
- },
- isExternalClick: function( e ) {
- var el = this.$element.get( 0 );
- var exceptions = this.options.externalClickExceptions || [];
- var $originEl = $( e.target );
- var i, l;
- if ( e.target === el || $originEl.parents( '.placard:first' ).get( 0 ) === el ) {
- return false;
- } else {
- for ( i = 0, l = exceptions.length; i < l; i++ ) {
- if ( $originEl.is( exceptions[ i ] ) || $originEl.parents( exceptions[ i ] ).length > 0 ) {
- return false;
- }
- }
- }
- return true;
- },
- setValue: function( val ) {
- this.$field.val( val );
- if ( !this.$element.hasClass( 'showing' ) ) {
- this.ellipsis();
- }
- },
- show: function() {
- var other;
- if ( this.$element.hasClass( 'showing' ) ) {
- return;
- }
- other = $( document ).find( '.placard.showing' );
- if ( other.length > 0 ) {
- if ( other.data( 'fu.placard' ) && other.data( 'fu.placard' ).options.explicit ) {
- return;
- }
- other.placard( 'externalClickListener', {}, true );
- }
- this.previousValue = this.$field.val();
- this.$element.addClass( 'showing' );
- if ( this.actualValue !== null ) {
- this.$field.val( this.actualValue );
- this.actualValue = null;
- }
- if ( this.$header.length > 0 ) {
- this.$popup.css( 'top', '-' + this.$header.outerHeight( true ) + 'px' );
- }
- if ( this.$footer.length > 0 ) {
- this.$popup.css( 'bottom', '-' + this.$footer.outerHeight( true ) + 'px' );
- }
- this.$element.trigger( 'shown.fu.placard' );
- this.clickStamp = new Date().getTime() + ( Math.floor( Math.random() * 100 ) + 1 );
- if ( !this.options.explicit ) {
- $( document ).on( 'click.fu.placard.externalClick.' + this.clickStamp, $.proxy( this.externalClickListener, this ) );
- }
- }
- };
- // PLACARD PLUGIN DEFINITION
- $.fn.placard = function( option ) {
- var args = Array.prototype.slice.call( arguments, 1 );
- var methodReturn;
- var $set = this.each( function() {
- var $this = $( this );
- var data = $this.data( 'fu.placard' );
- var options = typeof option === 'object' && option;
- if ( !data ) $this.data( 'fu.placard', ( data = new Placard( this, options ) ) );
- if ( typeof option === 'string' ) methodReturn = data[ option ].apply( data, args );
- } );
- return ( methodReturn === undefined ) ? $set : methodReturn;
- };
- $.fn.placard.defaults = {
- onAccept: undefined,
- onCancel: undefined,
- externalClickAction: 'cancel',
- externalClickExceptions: [],
- explicit: false,
- revertOnCancel: -1 //negative 1 will check for an '.placard-accept' button. Also can be set to true or false
- };
- $.fn.placard.Constructor = Placard;
- $.fn.placard.noConflict = function() {
- $.fn.placard = old;
- return this;
- };
- // DATA-API
- $( document ).on( 'focus.fu.placard.data-api', '[data-initialize=placard]', function( e ) {
- var $control = $( e.target ).closest( '.placard' );
- if ( !$control.data( 'fu.placard' ) ) {
- $control.placard( $control.data() );
- }
- } );
- // Must be domReady for AMD compatibility
- $( function() {
- $( '[data-initialize=placard]' ).each( function() {
- var $this = $( this );
- if ( $this.data( 'fu.placard' ) ) return;
- $this.placard( $this.data() );
- } );
- } );
- } )( jQuery );
- ( function( $ ) {
- /*
- * Fuel UX Radio
- * https://github.com/ExactTarget/fuelux