UNPKG

fuelux

Version:

Base Fuel UX styles and controls

921 lines (784 loc) 28.5 kB
/* global jQuery:true */ /* * Fuel UX Repeater * https://github.com/ExactTarget/fuelux * * Copyright (c) 2014 ExactTarget * Licensed under the BSD New license. */ // -- BEGIN UMD WRAPPER PREFACE -- // For more information on UMD visit: // https://github.com/umdjs/umd/blob/master/jqueryPlugin.js (function umdFactory (factory) { if (typeof define === 'function' && define.amd) { // if AMD loader is available, register as an anonymous module. define(['jquery', 'fuelux/combobox', 'fuelux/infinite-scroll', 'fuelux/search', 'fuelux/selectlist'], factory); } else if (typeof exports === 'object') { // Node/CommonJS module.exports = factory(require('jquery'), require('./combobox'), require('./infinite-scroll'), require('./search'), require('./selectlist')); } else { // OR use browser globals if AMD is not present factory(jQuery); } }(function RepeaterWrapper ($) { // -- END UMD WRAPPER PREFACE -- // -- BEGIN MODULE CODE HERE -- var old = $.fn.repeater; // REPEATER CONSTRUCTOR AND PROTOTYPE var Repeater = function Repeater (element, options) { var self = this; var $btn; var currentView; this.$element = $(element); this.$canvas = this.$element.find('.repeater-canvas'); this.$count = this.$element.find('.repeater-count'); this.$end = this.$element.find('.repeater-end'); this.$filters = this.$element.find('.repeater-filters'); this.$loader = this.$element.find('.repeater-loader'); this.$pageSize = this.$element.find('.repeater-itemization .selectlist'); this.$nextBtn = this.$element.find('.repeater-next'); this.$pages = this.$element.find('.repeater-pages'); this.$prevBtn = this.$element.find('.repeater-prev'); this.$primaryPaging = this.$element.find('.repeater-primaryPaging'); this.$search = this.$element.find('.repeater-search').find('.search'); this.$secondaryPaging = this.$element.find('.repeater-secondaryPaging'); this.$start = this.$element.find('.repeater-start'); this.$viewport = this.$element.find('.repeater-viewport'); this.$views = this.$element.find('.repeater-views'); this.currentPage = 0; this.currentView = null; this.isDisabled = false; this.infiniteScrollingCallback = function noop () {}; this.infiniteScrollingCont = null; this.infiniteScrollingEnabled = false; this.infiniteScrollingEnd = null; this.infiniteScrollingOptions = {}; this.lastPageInput = 0; this.options = $.extend({}, $.fn.repeater.defaults, options); this.pageIncrement = 0;// store direction navigated this.resizeTimeout = {}; this.stamp = new Date().getTime() + (Math.floor(Math.random() * 100) + 1); this.storedDataSourceOpts = null; this.syncingViewButtonState = false; this.viewOptions = {}; this.viewType = null; this.$filters.selectlist(); this.$pageSize.selectlist(); this.$primaryPaging.find('.combobox').combobox(); this.$search.search({ searchOnKeyPress: this.options.searchOnKeyPress, allowCancel: this.options.allowCancel }); this.$filters.on('changed.fu.selectlist', function onFiltersChanged (e, value) { self.$element.trigger('filtered.fu.repeater', value); self.render({ clearInfinite: true, pageIncrement: null }); }); this.$nextBtn.on('click.fu.repeater', $.proxy(this.next, this)); this.$pageSize.on('changed.fu.selectlist', function onPageSizeChanged (e, value) { self.$element.trigger('pageSizeChanged.fu.repeater', value); self.render({ pageIncrement: null }); }); this.$prevBtn.on('click.fu.repeater', $.proxy(this.previous, this)); this.$primaryPaging.find('.combobox').on('changed.fu.combobox', function onPrimaryPagingChanged (evt, data) { self.pageInputChange(data.text, data); }); this.$search.on('searched.fu.search cleared.fu.search', function onSearched (e, value) { self.$element.trigger('searchChanged.fu.repeater', value); self.render({ clearInfinite: true, pageIncrement: null }); }); this.$search.on('canceled.fu.search', function onSearchCanceled (e, value) { self.$element.trigger('canceled.fu.repeater', value); self.render({ clearInfinite: true, pageIncrement: null }); }); this.$secondaryPaging.on('blur.fu.repeater', function onSecondaryPagingBlur () { self.pageInputChange(self.$secondaryPaging.val()); }); this.$secondaryPaging.on('keyup', function onSecondaryPagingKeyup (e) { if (e.keyCode === 13) { self.pageInputChange(self.$secondaryPaging.val()); } }); this.$views.find('input').on('change.fu.repeater', $.proxy(this.viewChanged, this)); $(window).on('resize.fu.repeater.' + this.stamp, function onResizeRepeater () { clearTimeout(self.resizeTimeout); self.resizeTimeout = setTimeout(function resizeTimeout () { self.resize(); self.$element.trigger('resized.fu.repeater'); }, 75); }); this.$loader.loader(); this.$loader.loader('pause'); if (this.options.defaultView !== -1) { currentView = this.options.defaultView; } else { $btn = this.$views.find('label.active input'); currentView = ($btn.length > 0) ? $btn.val() : 'list'; } this.setViewOptions(currentView); this.initViewTypes(function initViewTypes () { self.resize(); self.$element.trigger('resized.fu.repeater'); self.render({ changeView: currentView }); }); }; var logWarn = function logWarn (msg) { if (window.console && window.console.warn) { window.console.warn(msg); } }; var scan = function scan (cont) { var keep = []; cont.children().each(function eachContainerChild () { var item = $(this); var pres = item.attr('data-preserve'); if (pres === 'deep') { item.detach(); keep.push(item); } else if (pres === 'shallow') { scan(item); item.detach(); keep.push(item); } }); cont.empty(); cont.append(keep); }; var addItem = function addItem ($parent, response) { var action; if (response) { action = (response.action) ? response.action : 'append'; if (action !== 'none' && response.item !== undefined) { var $container = (response.container !== undefined) ? $(response.container) : $parent; $container[action](response.item); } } }; var callNextInit = function callNextInit (currentViewType, viewTypes, callback) { var nextViewType = currentViewType + 1; if (nextViewType < viewTypes.length) { initViewType.call(this, nextViewType, viewTypes, callback); } else { callback(); } }; var initViewType = function initViewType (currentViewtype, viewTypes, callback) { if (viewTypes[currentViewtype].initialize) { viewTypes[currentViewtype].initialize.call(this, {}, function afterInitialize () { callNextInit.call(this, currentViewtype, viewTypes, callback); }); } else { callNextInit.call(this, currentViewtype, viewTypes, callback); } }; // Does all of our cleanup post-render var afterRender = function afterRender (state) { var data = state.data || {}; if (this.infiniteScrollingEnabled) { if (state.viewChanged || state.options.clearInfinite) { this.initInfiniteScrolling(); } this.infiniteScrollPaging(data, state.options); } this.$loader.hide().loader('pause'); this.enable(); this.$search.trigger('rendered.fu.repeater', { data: data, options: state.dataOptions, renderOptions: state.options }); this.$element.trigger('rendered.fu.repeater', { data: data, options: state.dataOptions, renderOptions: state.options }); // for maintaining support of 'loaded' event this.$element.trigger('loaded.fu.repeater', state.dataOptions); }; // This does the actual rendering of the repeater var doRender = function doRender (state) { var data = state.data || {}; if (this.infiniteScrollingEnabled) { // pass empty object because data handled in infiniteScrollPaging method this.infiniteScrollingCallback({}); } else { this.itemization(data); this.pagination(data); } var self = this; this.renderItems( state.viewTypeObj, data, function callAfterRender (d) { state.data = d; afterRender.call(self, state); } ); }; Repeater.prototype = { constructor: Repeater, clear: function clear (opts) { var options = opts || {}; if (!options.preserve) { // Just trash everything because preserve is false this.$canvas.empty(); } else if (!this.infiniteScrollingEnabled || options.clearInfinite) { // Preserve clear only if infiniteScrolling is disabled or if specifically told to do so scan(this.$canvas); } // Otherwise don't clear because infiniteScrolling is enabled // If viewChanged and current viewTypeObj has a cleared function, call it var viewChanged = (options.viewChanged !== undefined) ? options.viewChanged : false; var viewTypeObj = $.fn.repeater.viewTypes[this.viewType] || {}; if (!viewChanged && viewTypeObj.cleared) { viewTypeObj.cleared.call(this, { options: options }); } }, clearPreservedDataSourceOptions: function clearPreservedDataSourceOptions () { this.storedDataSourceOpts = null; }, destroy: function destroy () { var markup; // set input value attrbute in markup this.$element.find('input').each(function eachInput () { $(this).attr('value', $(this).val()); }); // empty elements to return to original markup this.$canvas.empty(); markup = this.$element[0].outerHTML; // destroy components and remove leftover this.$element.find('.combobox').combobox('destroy'); this.$element.find('.selectlist').selectlist('destroy'); this.$element.find('.search').search('destroy'); if (this.infiniteScrollingEnabled) { $(this.infiniteScrollingCont).infinitescroll('destroy'); } this.$element.remove(); // any external events $(window).off('resize.fu.repeater.' + this.stamp); return markup; }, disable: function disable () { var viewTypeObj = $.fn.repeater.viewTypes[this.viewType] || {}; this.$search.search('disable'); this.$filters.selectlist('disable'); this.$views.find('label, input').addClass('disabled').attr('disabled', 'disabled'); this.$pageSize.selectlist('disable'); this.$primaryPaging.find('.combobox').combobox('disable'); this.$secondaryPaging.attr('disabled', 'disabled'); this.$prevBtn.attr('disabled', 'disabled'); this.$nextBtn.attr('disabled', 'disabled'); if (viewTypeObj.enabled) { viewTypeObj.enabled.call(this, { status: false }); } this.isDisabled = true; this.$element.addClass('disabled'); this.$element.trigger('disabled.fu.repeater'); }, enable: function enable () { var viewTypeObj = $.fn.repeater.viewTypes[this.viewType] || {}; this.$search.search('enable'); this.$filters.selectlist('enable'); this.$views.find('label, input').removeClass('disabled').removeAttr('disabled'); this.$pageSize.selectlist('enable'); this.$primaryPaging.find('.combobox').combobox('enable'); this.$secondaryPaging.removeAttr('disabled'); if (!this.$prevBtn.hasClass('page-end')) { this.$prevBtn.removeAttr('disabled'); } if (!this.$nextBtn.hasClass('page-end')) { this.$nextBtn.removeAttr('disabled'); } // is 0 or 1 pages, if using $primaryPaging (combobox) // if using selectlist allow user to use selectlist to select 0 or 1 if (this.$prevBtn.hasClass('page-end') && this.$nextBtn.hasClass('page-end')) { this.$primaryPaging.combobox('disable'); } // if there are no items if (parseInt(this.$count.html(), 10) !== 0) { this.$pageSize.selectlist('enable'); } else { this.$pageSize.selectlist('disable'); } if (viewTypeObj.enabled) { viewTypeObj.enabled.call(this, { status: true }); } this.isDisabled = false; this.$element.removeClass('disabled'); this.$element.trigger('enabled.fu.repeater'); }, getDataOptions: function getDataOptions (opts) { var options = opts || {}; if (options.pageIncrement !== undefined) { if (options.pageIncrement === null) { this.currentPage = 0; } else { this.currentPage += options.pageIncrement; } } var dataSourceOptions = {}; if (options.dataSourceOptions) { dataSourceOptions = options.dataSourceOptions; if (options.preserveDataSourceOptions) { if (this.storedDataSourceOpts) { this.storedDataSourceOpts = $.extend(this.storedDataSourceOpts, dataSourceOptions); } else { this.storedDataSourceOpts = dataSourceOptions; } } } if (this.storedDataSourceOpts) { dataSourceOptions = $.extend(this.storedDataSourceOpts, dataSourceOptions); } var returnOptions = { view: this.currentView, pageIndex: this.currentPage, filter: { text: 'All', value: 'all' } }; if (this.$filters.length > 0) { returnOptions.filter = this.$filters.selectlist('selectedItem'); } if (!this.infiniteScrollingEnabled) { returnOptions.pageSize = 25; if (this.$pageSize.length > 0) { returnOptions.pageSize = parseInt(this.$pageSize.selectlist('selectedItem').value, 10); } } var searchValue = this.$search && this.$search.find('input') && this.$search.find('input').val(); if (searchValue !== '') { returnOptions.search = searchValue; } var viewType = $.fn.repeater.viewTypes[this.viewType] || {}; var addViewTypeData = viewType.dataOptions; if (addViewTypeData) { returnOptions = addViewTypeData.call(this, returnOptions); } returnOptions = $.extend(returnOptions, dataSourceOptions); return returnOptions; }, infiniteScrolling: function infiniteScrolling (enable, opts) { var footer = this.$element.find('.repeater-footer'); var viewport = this.$element.find('.repeater-viewport'); var options = opts || {}; if (enable) { this.infiniteScrollingEnabled = true; this.infiniteScrollingEnd = options.end; delete options.dataSource; delete options.end; this.infiniteScrollingOptions = options; viewport.css({ height: viewport.height() + (footer.outerHeight() || 0) }); footer.hide(); } else { var cont = this.infiniteScrollingCont; var data = cont.data(); delete data.infinitescroll; cont.off('scroll'); cont.removeClass('infinitescroll'); this.infiniteScrollingCont = null; this.infiniteScrollingEnabled = false; this.infiniteScrollingEnd = null; this.infiniteScrollingOptions = {}; viewport.css({ height: viewport.height() - (footer.outerHeight() || 0) }); footer.show(); } }, infiniteScrollPaging: function infiniteScrollPaging (data) { var end = (this.infiniteScrollingEnd !== true) ? this.infiniteScrollingEnd : undefined; var page = data.page; var pages = data.pages; this.currentPage = (page !== undefined) ? page : NaN; if (this.infiniteScrollingCont) { if (data.end === true || (this.currentPage + 1) >= pages) { this.infiniteScrollingCont.infinitescroll('end', end); } else { this.infiniteScrollingCont.infinitescroll('onScroll'); } } }, initInfiniteScrolling: function initInfiniteScrolling () { var cont = this.$canvas.find('[data-infinite="true"]:first'); cont = (cont.length < 1) ? this.$canvas : cont; if (cont.data('fu.infinitescroll')) { cont.infinitescroll('enable'); } else { var self = this; var opts = $.extend({}, this.infiniteScrollingOptions); opts.dataSource = function dataSource (helpers, callback) { self.infiniteScrollingCallback = callback; self.render({ pageIncrement: 1 }); }; cont.infinitescroll(opts); this.infiniteScrollingCont = cont; } }, initViewTypes: function initViewTypes (callback) { var viewTypes = []; for (var key in $.fn.repeater.viewTypes) { if ({}.hasOwnProperty.call($.fn.repeater.viewTypes, key)) { viewTypes.push($.fn.repeater.viewTypes[key]); } } if (viewTypes.length > 0) { initViewType.call(this, 0, viewTypes, callback); } else { callback(); } }, itemization: function itemization (data) { this.$count.html((data.count !== undefined) ? data.count : '?'); this.$end.html((data.end !== undefined) ? data.end : '?'); this.$start.html((data.start !== undefined) ? data.start : '?'); }, next: function next () { this.$nextBtn.attr('disabled', 'disabled'); this.$prevBtn.attr('disabled', 'disabled'); this.pageIncrement = 1; this.$element.trigger('nextClicked.fu.repeater'); this.render({ pageIncrement: this.pageIncrement }); }, pageInputChange: function pageInputChange (val, dataFromCombobox) { // dataFromCombobox is a proxy for data from combobox's changed event, // if no combobox is present data will be undefined var pageInc; if (val !== this.lastPageInput) { this.lastPageInput = val; var value = parseInt(val, 10) - 1; pageInc = value - this.currentPage; this.$element.trigger('pageChanged.fu.repeater', [value, dataFromCombobox]); this.render({ pageIncrement: pageInc }); } }, pagination: function pagination (data) { this.$primaryPaging.removeClass('active'); this.$secondaryPaging.removeClass('active'); var totalPages = data.pages; this.currentPage = (data.page !== undefined) ? data.page : NaN; // set paging to 0 if total pages is 0, otherwise use one-based index var currenPageOutput = totalPages === 0 ? 0 : this.currentPage + 1; if (totalPages <= this.viewOptions.dropPagingCap) { this.$primaryPaging.addClass('active'); var dropMenu = this.$primaryPaging.find('.dropdown-menu'); dropMenu.empty(); for (var i = 0; i < totalPages; i++) { var l = i + 1; dropMenu.append('<li data-value="' + l + '"><a href="#">' + l + '</a></li>'); } this.$primaryPaging.find('input.form-control').val(currenPageOutput); } else { this.$secondaryPaging.addClass('active'); this.$secondaryPaging.val(currenPageOutput); } this.lastPageInput = this.currentPage + 1 + ''; this.$pages.html('' + totalPages); // this is not the last page if ((this.currentPage + 1) < totalPages) { this.$nextBtn.removeAttr('disabled'); this.$nextBtn.removeClass('page-end'); } else { this.$nextBtn.attr('disabled', 'disabled'); this.$nextBtn.addClass('page-end'); } // this is not the first page if ((this.currentPage - 1) >= 0) { this.$prevBtn.removeAttr('disabled'); this.$prevBtn.removeClass('page-end'); } else { this.$prevBtn.attr('disabled', 'disabled'); this.$prevBtn.addClass('page-end'); } // return focus to next/previous buttons after navigating if (this.pageIncrement !== 0) { if (this.pageIncrement > 0) { if (this.$nextBtn.is(':disabled')) { // if you can't focus, go the other way this.$prevBtn.focus(); } else { this.$nextBtn.focus(); } } else if (this.$prevBtn.is(':disabled')) { // if you can't focus, go the other way this.$nextBtn.focus(); } else { this.$prevBtn.focus(); } } }, previous: function previous () { this.$nextBtn.attr('disabled', 'disabled'); this.$prevBtn.attr('disabled', 'disabled'); this.pageIncrement = -1; this.$element.trigger('previousClicked.fu.repeater'); this.render({ pageIncrement: this.pageIncrement }); }, // This functions more as a "pre-render" than a true "render" render: function render (opts) { this.disable(); var viewChanged = false; var viewTypeObj = $.fn.repeater.viewTypes[this.viewType] || {}; var options = opts || {}; if (options.changeView && (this.currentView !== options.changeView)) { var prevView = this.currentView; this.currentView = options.changeView; this.viewType = this.currentView.split('.')[0]; this.setViewOptions(this.currentView); this.$element.attr('data-currentview', this.currentView); this.$element.attr('data-viewtype', this.viewType); viewChanged = true; options.viewChanged = viewChanged; this.$element.trigger('viewChanged.fu.repeater', this.currentView); if (this.infiniteScrollingEnabled) { this.infiniteScrolling(false); } viewTypeObj = $.fn.repeater.viewTypes[this.viewType] || {}; if (viewTypeObj.selected) { viewTypeObj.selected.call(this, { prevView: prevView }); } } this.syncViewButtonState(); options.preserve = (options.preserve !== undefined) ? options.preserve : !viewChanged; this.clear(options); if (!this.infiniteScrollingEnabled || (this.infiniteScrollingEnabled && viewChanged)) { this.$loader.show().loader('play'); } var dataOptions = this.getDataOptions(options); var beforeRender = this.viewOptions.dataSource; var repeaterPrototypeContext = this; beforeRender( dataOptions, // this serves as a bridge function to pass all required data through to the actual function // that does the rendering for us. function callDoRender (dataSourceReturnedData) { doRender.call( repeaterPrototypeContext, { data: dataSourceReturnedData, dataOptions: dataOptions, options: options, viewChanged: viewChanged, viewTypeObj: viewTypeObj } ); } ); }, resize: function resize () { var staticHeight = (this.viewOptions.staticHeight === -1) ? this.$element.attr('data-staticheight') : this.viewOptions.staticHeight; var viewTypeObj = {}; var height; var viewportMargins; var scrubbedElements = []; var previousProperties = []; var $hiddenElements = this.$element.parentsUntil(':visible').addBack(); var currentHiddenElement; var currentElementIndex = 0; // Set parents to 'display:block' until repeater is visible again while (currentElementIndex < $hiddenElements.length && this.$element.is(':hidden')) { currentHiddenElement = $hiddenElements[currentElementIndex]; // Only set display property on elements that are explicitly hidden (i.e. do not inherit it from their parent) if ($(currentHiddenElement).is(':hidden')) { previousProperties.push(currentHiddenElement.style['display']); currentHiddenElement.style['display'] = 'block'; scrubbedElements.push(currentHiddenElement); } currentElementIndex++; } if (this.viewType) { viewTypeObj = $.fn.repeater.viewTypes[this.viewType] || {}; } if (staticHeight !== undefined && staticHeight !== false && staticHeight !== 'false') { this.$canvas.addClass('scrolling'); viewportMargins = { bottom: this.$viewport.css('margin-bottom'), top: this.$viewport.css('margin-top') }; var staticHeightValue = (staticHeight === 'true' || staticHeight === true) ? this.$element.height() : parseInt(staticHeight, 10); var headerHeight = this.$element.find('.repeater-header').outerHeight() || 0; var footerHeight = this.$element.find('.repeater-footer').outerHeight() || 0; var bottomMargin = (viewportMargins.bottom === 'auto') ? 0 : parseInt(viewportMargins.bottom, 10); var topMargin = (viewportMargins.top === 'auto') ? 0 : parseInt(viewportMargins.top, 10); height = staticHeightValue - headerHeight - footerHeight - bottomMargin - topMargin; this.$viewport.outerHeight(height); } else { this.$canvas.removeClass('scrolling'); } if (viewTypeObj.resize) { viewTypeObj.resize.call(this, { height: this.$element.outerHeight() || 0, width: this.$element.outerWidth() || 0 }); } scrubbedElements.forEach(function (element, i) { element.style['display'] = previousProperties[i]; }); }, // e.g. "Rows" or "Thumbnails" renderItems: function renderItems (viewTypeObj, data, callback) { if (!viewTypeObj.render) { if (viewTypeObj.before) { var addBefore = viewTypeObj.before.call(this, { container: this.$canvas, data: data }); addItem(this.$canvas, addBefore); } var $dataContainer = this.$canvas.find('[data-container="true"]:last'); var $container = ($dataContainer.length > 0) ? $dataContainer : this.$canvas; // It appears that the following code would theoretically allow you to pass a deeply // nested value to "repeat on" to be added to the repeater. // eg. `data.foo.bar.items` if (viewTypeObj.renderItem) { var subset; var objectAndPropsToRepeatOnString = viewTypeObj.repeat || 'data.items'; var objectAndPropsToRepeatOn = objectAndPropsToRepeatOnString.split('.'); var objectToRepeatOn = objectAndPropsToRepeatOn[0]; if (objectToRepeatOn === 'data' || objectToRepeatOn === 'this') { subset = (objectToRepeatOn === 'this') ? this : data; // Extracts subset from object chain (get `items` out of `foo.bar.items`). I think.... var propsToRepeatOn = objectAndPropsToRepeatOn.slice(1); for (var prop = 0; prop < propsToRepeatOn.length; prop++) { if (subset[propsToRepeatOn[prop]] !== undefined) { subset = subset[propsToRepeatOn[prop]]; } else { subset = []; logWarn('WARNING: Repeater unable to find property to iterate renderItem on.'); break; } } for (var subItemIndex = 0; subItemIndex < subset.length; subItemIndex++) { var addSubItem = viewTypeObj.renderItem.call(this, { container: $container, data: data, index: subItemIndex, subset: subset }); addItem($container, addSubItem); } } else { logWarn('WARNING: Repeater plugin "repeat" value must start with either "data" or "this"'); } } if (viewTypeObj.after) { var addAfter = viewTypeObj.after.call(this, { container: this.$canvas, data: data }); addItem(this.$canvas, addAfter); } callback(data); } else { viewTypeObj.render.call(this, { container: this.$canvas, data: data }, callback); } }, setViewOptions: function setViewOptions (curView) { var opts = {}; var viewName = curView.split('.')[1]; if (this.options.views) { opts = this.options.views[viewName] || this.options.views[curView] || {}; } else { opts = {}; } this.viewOptions = $.extend({}, this.options, opts); }, viewChanged: function viewChanged (e) { var $selected = $(e.target); var val = $selected.val(); if (!this.syncingViewButtonState) { if (this.isDisabled || $selected.parents('label:first').hasClass('disabled')) { this.syncViewButtonState(); } else { this.render({ changeView: val, pageIncrement: null }); } } }, syncViewButtonState: function syncViewButtonState () { var $itemToCheck = this.$views.find('input[value="' + this.currentView + '"]'); this.syncingViewButtonState = true; this.$views.find('input').prop('checked', false); this.$views.find('label.active').removeClass('active'); if ($itemToCheck.length > 0) { $itemToCheck.prop('checked', true); $itemToCheck.parents('label:first').addClass('active'); } this.syncingViewButtonState = false; } }; // For backwards compatibility. Repeater.prototype.runRenderer = Repeater.prototype.renderItems; // REPEATER PLUGIN DEFINITION $.fn.repeater = function fnrepeater (option) { var args = Array.prototype.slice.call(arguments, 1); var methodReturn; var $set = this.each(function eachThis () { var $this = $(this); var data = $this.data('fu.repeater'); var options = typeof option === 'object' && option; if (!data) { $this.data('fu.repeater', (data = new Repeater(this, options))); } if (typeof option === 'string') { methodReturn = data[option].apply(data, args); } }); return (methodReturn === undefined) ? $set : methodReturn; }; $.fn.repeater.defaults = { dataSource: function dataSource (options, callback) { callback({ count: 0, end: 0, items: [], page: 0, pages: 1, start: 0 }); }, defaultView: -1, // should be a string value. -1 means it will grab the active view from the view controls dropPagingCap: 10, staticHeight: -1, // normally true or false. -1 means it will look for data-staticheight on the element views: null, // can be set to an object to configure multiple views of the same type, searchOnKeyPress: false, allowCancel: true }; $.fn.repeater.viewTypes = {}; $.fn.repeater.Constructor = Repeater; $.fn.repeater.noConflict = function noConflict () { $.fn.repeater = old; return this; }; // -- BEGIN UMD WRAPPER AFTERWORD -- })); // -- END UMD WRAPPER AFTERWORD --