All Downloads are FREE. Search and download functionalities are using the official Maven repository.

META-INF.resources.butterfaces-dist-bundle-js.butterfaces-js-bundle.js Maven / Gradle / Ivy

The newest version!
/* Simple JavaScript Inheritance
 * By John Resig http://ejohn.org/
 * MIT Licensed.
 */
// Inspired by base2 and Prototype
(function(){
    var initializing = false, fnTest = /xyz/.test(function(){xyz;}) ? /\b_super\b/ : /.*/;

    // The base Class implementation (does nothing)
    this.Class = function(){};

    // Create a new Class that inherits from this class
    Class.extend = function(prop) {
        var _super = this.prototype;

        // Instantiate a base class (but only create the instance,
        // don't run the init constructor)
        initializing = true;
        var prototype = new this();
        initializing = false;

        // Copy the properties over onto the new prototype
        for (var name in prop) {
            // Check if we're overwriting an existing function
            prototype[name] = typeof prop[name] == "function" &&
            typeof _super[name] == "function" && fnTest.test(prop[name]) ?
                    (function(name, fn){
                        return function() {
                            var tmp = this._super;

                            // Add a new ._super() method that is the same method
                            // but on the super-class
                            this._super = _super[name];

                            // The method only need to be bound temporarily, so we
                            // remove it when we're done executing
                            var ret = fn.apply(this, arguments);
                            this._super = tmp;

                            return ret;
                        };
                    })(name, prop[name]) :
                    prop[name];
        }

        // The dummy class constructor
        function Class() {
            // All construction is actually done in the init method
            if ( !initializing && this.init )
                this.init.apply(this, arguments);
        }

        // Populate our constructed prototype object
        Class.prototype = prototype;

        // Enforce the constructor to be what we expect
        Class.prototype.constructor = Class;

        // And make this class extendable
        Class.extend = arguments.callee;

        return Class;
    };
})();
/**
 * jQuery-Plugin "butterHandleAutoComplete" for text autocomplete tag. Initializes auto complete functionality to
 * text component.
 *
 * How to use:
 * jQuery("#selector")._butterAutoCompleteInit();
 */
(function ($) {
    // extend jQuery --------------------------------------------------------------------

    $.fn._butterAutoCompleteInit = function () {
        return this.each(function () {
            new AutocompleteList(this);
        });
    };

    // define objects --------------------------------------------------------------------

    var AutocompleteList = Class.extend({
        init: function (rootElement) {
            this.SEARCH_REQUEST_DELAY = 300;// in ms

            var $autocompleteTmp = $(rootElement);
            this.$input = $autocompleteTmp.prev();
            this.$input.parent().css({position: "relative"});
            this.autocompleteId = $autocompleteTmp.attr("id");
            this.$selectedOption = null;
            this.ignoreKeyupEvent = false;
            this.requestDelayTimerId = null;
            this.isRequestRunning = false;
            this.areChangesMadeWhileRequestWasRunning = false;

            this._keyCodes = {
                //backspace: 8,
                tab: 9,
                enter: 13,
                shift: 16,
                ctrl: 17,
                alt: 18,
                pause: 19,
                caps_lock: 20,
                escape: 27,
                page_up: 33,
                page_down: 34,
                end: 35,
                home: 36,
                arrow_left: 37,
                arrow_up: 38,
                arrow_right: 39,
                arrow_down: 40,
                insert: 45,
                // 'delete' is a reserved key word
                delete_key: 46,
                left_window_key: 91,
                right_window_key: 92,
                select_key: 93,
                num_lock: 144,
                scroll_lock: 145
            };

            var self = this;
            self.$input
                    .on("keydown", function (event) {
                        if (event.which === self._keyCodes.enter) {
                            self._handleEnterKeyDown(event);
                        } else if (event.which === self._keyCodes.arrow_up
                                || event.which === self._keyCodes.arrow_down) {
                            self._handleArrowUpAndDownKeyDown(event);
                        } else if (event.which === self._keyCodes.escape) {
                            self._handleEscapeKeyDown(event);
                        }
                    })
                    .on("keyup", function (event) {
                        // don't handle other keys than character keys
                        for (keyName in self._keyCodes) {
                            if (self._keyCodes[keyName] === event.which) {
                                self._stopEvent(event);
                                return;
                            }
                        }

                        if (self.ignoreKeyupEvent) {
                            self._stopEvent(event);
                            self.ignoreKeyupEvent = false;
                            return;
                        }

                        if (self.$input.val().length === 0) {
                            self._stopEvent(event);
                            self._hideAutocompleteResultList();
                            return;
                        }

                        self._trySendJsfAjaxRequest();
                    })
                    .on("blur", function (event) {
                        window.setTimeout(function () {
                            self._hideAutocompleteResultList();
                        }, 100);
                    });
        },

        _handleEnterKeyDown: function (event) {
            if (this.$selectedOption !== null) {
                this._stopEvent(event);
                this._setSelectedValue();
            }
        },

        _handleArrowUpAndDownKeyDown: function (event) {
            this._stopEvent(event);
            var $autocomplete = this._getAutocompleteElement();
            if (!$autocomplete.is(":visible") && this.$input.val().length > 0) {
                this._trySendJsfAjaxRequest();
            } else if ($autocomplete.is(":visible") && $autocomplete.find("li").length > 0) {
                if (this.$selectedOption === null) {
                    this._selectResultOptionElement($autocomplete.find("li")[0]);
                } else {
                    this._moveResultOptionElementSelectionCursor(
                            $autocomplete, event.which === this._keyCodes.arrow_up ? -1 : 1);
                }
            }
        },

        _handleEscapeKeyDown: function (event) {
            this._stopEvent(event);
            this._hideAutocompleteResultList();
        },

        _trySendJsfAjaxRequest: function () {
            var self = this;

            if (self.isRequestRunning) {
                // console.log("request is active, so remember that changes has been made while request was running");
                self.areChangesMadeWhileRequestWasRunning = true;
            }

            if (self.requestDelayTimerId !== null) {
                window.clearTimeout(self.requestDelayTimerId)
            }

            self.requestDelayTimerId = window.setTimeout(function () {
                self.requestDelayTimerId = null;
                self._sendJsfAjaxRequest();
            }, self.SEARCH_REQUEST_DELAY);
        },

        _sendJsfAjaxRequest: function () {
            var self = this;

            if (self.isRequestRunning) {
                // console.log("request is running, abort");
                return;
            }
            self.isRequestRunning = true;

            self.areChangesMadeWhileRequestWasRunning = false;
            self._showLoadingSpinner();

            // console.log("starting request");

            var id = self.$input.parent().parent().attr('id');

            jsf.ajax.request(id, "autocomplete", {
                "javax.faces.behavior.event": "autocomplete",
                render: self.autocompleteId,
                params: self.$input.val(),
                onevent: function (data) {
                    if (data.status === "success") {
                        // console.log("request finished");

                        // only show result if input field still has focus
                        if (self.$input.is(":focus")) {
                            self._handleAutocompleteResultListVisibility();
                        }
                        self._hideLoadingSpinner();
                        self.isRequestRunning = false;

                        if (self.areChangesMadeWhileRequestWasRunning) {
                            // console.log("changes made while request was running, start new request automatically");
                            self._sendJsfAjaxRequest();
                        }
                    }
                }
            });
        },

        _handleAutocompleteResultListVisibility: function () {
            var self = this;
            var $autocomplete = self._getAutocompleteElement();

            if ($autocomplete.find("li").length > 0) {
                self._initAndShowAutocompleteResultList();
            } else {
                self._hideAutocompleteResultList();
            }
        },

        _showLoadingSpinner: function () {
            $('
') .appendTo(this.$input.parent()); }, _hideLoadingSpinner: function () { this.$input.parent().find(".butter-dropdownlist-spinner").remove(); }, _initAndShowAutocompleteResultList: function () { var self = this; var $autocomplete = self._getAutocompleteElement(); $autocomplete .show() .css({ width: self.$input.innerWidth() }) .highlight(self.$input.val()); $autocomplete.find("ul") .on("mouseleave", function () { self._clearResultOptionSelection(); }); $autocomplete.find("li") .on("mousedown", function () { self._setSelectedValue(); }) .on("mouseenter", function () { self._selectResultOptionElement(this); }); }, _selectResultOptionElement: function (optionElement) { this._clearResultOptionSelection(); var $selectedOptionElement = $(optionElement); $selectedOptionElement.addClass("butter-dropdownlist-resultItem-selected"); this.$selectedOption = $selectedOptionElement; }, _clearResultOptionSelection: function () { this.$selectedOption = null; this._getAutocompleteElement() .find(".butter-dropdownlist-resultItem-selected") .removeClass("butter-dropdownlist-resultItem-selected"); }, _moveResultOptionElementSelectionCursor: function ($autocomplete, direction) { if (direction > 0) { var $next = this.$selectedOption.next(); if ($next.length > 0) { this._selectResultOptionElement($next[0]); } else { //there is no next this._selectResultOptionElement($autocomplete.find("li")[0]); } } else { var $prev = this.$selectedOption.prev(); if ($prev.length > 0) { this._selectResultOptionElement($prev[0]); } else { //there is no previous var resultListOptions = $autocomplete.find("li"); this._selectResultOptionElement(resultListOptions[resultListOptions.length - 1]); } } }, _setSelectedValue: function () { if (this.$selectedOption !== null) { this.ignoreKeyupEvent = true; this.$input .val(this.$selectedOption.attr("data-select-value")) .change() .focus() .keyup(); this._hideAutocompleteResultList(); } }, _hideAutocompleteResultList: function () { if (this.requestDelayTimerId !== null) { window.clearTimeout(this.requestDelayTimerId) } this.$selectedOption = null; this._getAutocompleteElement().hide(); }, _getAutocompleteElement: function () { return $(document.getElementById(this.autocompleteId)); }, _stopEvent: function (event) { event.stopPropagation(); event.preventDefault(); } }); }(jQuery)); /** * jQuery-Plugin to handle bootstrap fixes. * Works with at least jQuery 1.3.2. * * How to use: * jQuery("#someTreeSelector").fixBootstrapDropDown(); */ (function ($) { $.fn.fixBootstrapDropDown = function () { return this.each(function () { $('.dropdown-menu').on('click', function(e) { if($(this).hasClass('dropdown-menu-form')) { e.stopPropagation(); } }); }); }; }(jQuery)); /** * butterItemFilterField is a jQuery plugin that filters html element with the css class filterable-item. * It is applied to the search field.
* If no filter text is entered, then all filterable-items are displayed. Else the search field value is matched against all text contained by a filterable-item. * * How to use: * jQuery("#someInputSelector").butterItemFilterField(); * * Author: Yann Massard */ (function ($) { var delay = (function () { var timer = 0; return function (callback, ms) { clearTimeout(timer); timer = setTimeout(callback, ms); }; })(); // extend jQuery -------------------------------------------------------------------- $.fn.butterItemFilterField = function (filterableItemContainerSelector) { return this.each(function () { var $this = $(this); $this.keyup(function () { delay(function () { var filterValue = $this.val(); // find container again every time, because it could have been rerendered. var $filterableItemContainer; if (filterableItemContainerSelector) { $filterableItemContainer = $(filterableItemContainerSelector); } else { var containerSelector = $this.attr('data-filterable-item-container'); $filterableItemContainer = $(containerSelector); } $filterableItemContainer.find('.filterable-item').each(function () { var $filterableItem = $(this); if ($filterableItem.is(':containsIgnoreCase(' + filterValue + ')')) { $filterableItem.removeClass("hidden"); $filterableItem.highlight(filterValue); } else { $filterableItem.addClass("hidden"); } }); }, 300); }); }); }; }(jQuery)); (function ($) { $.expr[":"].containsIgnoreCase = $.expr.createPseudo(function (arg) { return function (elem) { return !arg || $(elem).text().toUpperCase().indexOf(arg.toUpperCase()) >= 0; }; }); }(jQuery)); /** * jQuery-Plugin "Animate dots" for tree animation. Animates a waiting dot line (4 dots) in an interval of 200 millis * as html string in given component. Note: existing html code will be cleared. * Works with at least jQuery 1.3.2. * * How to use: * jQuery("#selector").startDots(); * jQuery("#selector").stopDots(); */ (function ($) { // extend jQuery -------------------------------------------------------------------- var intervalTrigger = null; $.fn.startDots = function () { return this.each(function () { var $originalElement = $(this); $originalElement.html(''); intervalTrigger = setInterval(function () { $originalElement.append('.'); if ($originalElement.html().length > 5) { $originalElement.html(''); } }, 200); }); }; $.fn.stopDots = function () { return this.each(function () { var $originalElement = $(this); $originalElement.html(''); window.clearInterval(intervalTrigger); }); }; }(jQuery)); /** * jQuery-Plugin "Expanded TextAreas" for expandable text areas. It is used for the JSF-Component "b:textarea". * Works with at least jQuery 1.7. * * How to use: * jQuery("#someTextAreaSelector").butterExpandable(); */ (function ($) { // extend jQuery -------------------------------------------------------------------- $.fn.butterExpandable = function () { return this.each(function () { if ($(this).find("textarea").length > 0) { new TextareaExpandable(this); } else { new DivExpandable(this); } }); }; // define objects -------------------------------------------------------------------- var _AbstractExpandable = Class.extend({ init: function (rootElement) { this.EXPAND_HEIGHT = 250; //in px this.EXPAND_WIDTH = 500; //in px this.ANIMATION_DURATION = 200; //in ms this.REPOSITION_INTERVAL = 500; //in ms this.EASING = "swing"; this.KEYCODE_ESCAPE = 27; this.$rootElement = $(rootElement); this.$ghostElement = null; this.$originalElement; this.initialHeight; this.initialWidth; this.initialOffset; this.positionTriggerInterval; this.initialize(); }, initialize: function () { // should intentionally be overridden }, isExpansionEventIgnored: function (event) { // should intentionally be overridden return false; }, onGhostElementCreated: function () { // should intentionally be overridden }, onGhostElementCollapsed: function (isCancelled) { // should intentionally be overridden }, transferValueToGhostElement: function () { // should intentionally be overridden }, expandElement: function (event) { if (this.isExpansionEventIgnored(event)) { return; } // console.log("expanding element"); this.initialHeight = this.$originalElement.outerHeight(); this.initialWidth = this.$originalElement.outerWidth(); this.initialOffset = this.$originalElement.offset(); //create a ghost element that be animated on gets the focus var self = this; this.$ghostElement = this.createGhostElement(); this.transferValueToGhostElement(); this.$ghostElement.css("width", this.initialWidth) .css("height", this.initialHeight) .css("position", "absolute") .css("top", this.initialOffset.top) .css("left", this.initialOffset.left) .css("z-index", 2000) .css("box-shadow", "5px 5px 5px 0 #999") .addClass("butter-component-expandable-ghost") .appendTo($("body")) .animate({ height: self.EXPAND_HEIGHT, width: self.initialWidth > self.EXPAND_WIDTH ? self.initialWidth : self.EXPAND_WIDTH }, self.ANIMATION_DURATION, self.EASING, function () { $(document) .on("click.expandable", function (event) { self._handleMouseClick(event); }) .on("keydown.expandable", function (event) { self._handleEscapeKey(event); }); $(window).on("resize.expandable", function (event) { self._repositionGhostElement(event); }); //keep track of the orginal element's position self.positionTriggerInterval = window.setInterval(self._repositionGhostElement, self.REPOSITION_INTERVAL); }); //make original invisible this.$originalElement .css("visibility", "hidden") .siblings() .css("visibility", "hidden"); this.onGhostElementCreated(); }, /** * @returns {*|HTMLElement} */ createGhostElement: function () { // should intentionally be overridden return null; }, /** * Collapses the ghost element and sets the value if not isCancelled * @param isCancelled */ collapseElement: function (cancelled) { // console.log("collapsing element"); // 'cancelled' can be an event object var isCancelled = typeof cancelled === "boolean" && cancelled; $(document) .off("click.expandable") .off("keydown.expandable"); //make original visible again this.$originalElement .css("visibility", "visible") .siblings() .css("visibility", "visible"); var self = this; this.$ghostElement.animate({ height: self.initialHeight, width: self.initialWidth }, self.ANIMATION_DURATION, self.EASING, function () { //on animation complete self.onGhostElementCollapsed(isCancelled); //delete the ghost element self.$ghostElement.remove(); self.$ghostElement = null; //delete position trigger timeout and resize listener window.clearInterval(self.positionTriggerInterval); $(window).off("resize.expandable"); }); }, _handleMouseClick: function (event) { // collapse ghost element if user clicks beside it if (!$(event.target).is(".butter-component-expandable-ghost")) { this.collapseElement(false); } }, _handleEscapeKey: function (event) { if (event.which === this.KEYCODE_ESCAPE) { this.collapseElement(true); } }, _repositionGhostElement: function () { //keep track of window resizing and reposition the ghost element if (this.$ghostElement !== undefined && this.$ghostElement != null) { this.initialOffset = this.$originalElement.offset(); this.$ghostElement .css("top", this.initialOffset.top) .css("left", this.initialOffset.left); } } }); var DivExpandable = _AbstractExpandable.extend({ initialize: function () { this.$originalElement = this.$rootElement.find(".butter-component-value-readonly"); this._rearrangeOriginalElementStructure(); }, _rearrangeOriginalElementStructure: function () { var self = this; var _label = this.$rootElement.find(".butter-component-label"); this.$originalElement .addClass("butter-component-expandable-original") .click(function (event) { self.expandElement(event); }) .detach(); var _container = $("
") .addClass("butter-component-expandable-readonly-container") .insertAfter(_label); var _icon = $("").addClass("glyphicon glyphicon-resize-full"); this.$originalElement.appendTo(_container); $("
") .addClass("butter-component-expandable-readonly-icon") .append(_icon) .appendTo(_container); }, createGhostElement: function () { return $("
"); }, transferValueToGhostElement: function () { $("
") .html(this.$originalElement.html()) .addClass("butter-component-expandable-ghost-readonlyContent") .appendTo(this.$ghostElement); } }); var TextareaExpandable = _AbstractExpandable.extend({ initialize: function () { this.blockFocusEventOnOriginal = false; this.blockBlurEventOnOriginal = false; this.$originalElement = this.$rootElement.find("textarea"); this.$originalElement.addClass("butter-component-expandable-original"); var self = this; this.$originalElement.focus(function (event) { self.expandElement(event); }); this.$originalElement.blur(function (event) { self._handleBlurEvent(event); }); this._addInputGroupAddon(); }, _addInputGroupAddon: function () { this.$originalElement .addClass("form-control") .parent() .addClass("input-group"); $("") .insertAfter(this.$originalElement); }, _handleBlurEvent: function (event) { if (this.blockBlurEventOnOriginal) { // prevent blur event bubbling, so it will not be triggered in jsf event.preventDefault(); } }, createGhostElement: function () { return $("