PageSourceSearch

https://www.epogen.com/-/media/Base-Themes/Components-Theme/Scripts/component-accordions.js

js epogen.com collected 2026-09-25 00:31:21 UTC 11,286 bytes, 326 lines download raw bytes

1/* global _:true */
2/**
3 * Component Accordion
4 * @module Accordion
5 * @param  {jQuery} $ Instance of jQuery
6 * @return {Object} List of accordion methods
7 */
8XA.component.accordions = (function($) {
9    /**
10     * This object stores all public api methods
11     * @type {Object.<Methods>}
12     * @memberOf module:Accordion
13     * */
14    var api = {};
15    /**
16     * toogleEvents list of toggle events
17     * @memberOf module:Accordion
18     * @private
19     */
20    var toogleEvents = {
21        focus: function() {
22            $(this).addClass("show");
23        },
24        blur: function() {
25            $(this).removeClass("show");
26        }
27    };
28    /**
29     * headerBackground method set up background image for toggle-header
30     * @memberOf module:Accordion
31     * @param {DomElement} header toggle-header DOM element of accordion component
32     * @alias module:Accordion.headerBackground
33     * @private
34     */
35    function headerBackground(header) {
36        var backgroundIcon = $(header),
37            background = $(header).find("img"),
38            backgroundSrc = background.attr("src");
39
40        if (backgroundSrc) {
41            backgroundIcon.parents(".accordion").addClass("accordion-image");
42
43            backgroundIcon.css({
44                background: "url(" + backgroundSrc + ")",
45                "background-repeat": "no-repeat",
46                "background-size": "cover",
47                "background-position": "50% 100%"
48            });
49
50            background.hide();
51        }
52    }
53    /**
54     * calcSlideSize method calculate and set up width of accordion items
55     * @memberOf module:Accordion
56     * @param {DomElement} acc Root Dom element of accordion component
57     * @alias module:Accordion.calcSlideSize
58     * @private
59     */
60    function calcSlideSize(acc) {
61        var accordionWidth = $(acc).width(),
62            accordionItems = $(acc).find(".item"),
63            maxHeight = 0;
64
65        _.each(accordionItems, function(item) {
66            var itemContent = $(item).find(".toggle-content"),
67                itemHeader = $(item).find(".toggle-header"),
68                slideWidth =
69                    accordionWidth -
70                    accordionItems.length * itemHeader.outerWidth();
71
72            if ($(item).hasClass("active")) {
73                $(item).css({
74                    width: slideWidth
75                });
76            }
77
78            //width
79            itemContent.css({
80                width: $(acc).hasClass("accordion-image")
81                    ? slideWidth + itemHeader.outerWidth()
82                    : slideWidth -
83                      itemHeader.outerWidth() -
84                      parseInt(itemHeader.css("padding"))
85            });
86
87            //height
88            if (
89                $(item)
90                    .find(".toggle-content")
91                    .height() > maxHeight
92            ) {
93                maxHeight = $(item)
94                    .find(".toggle-content")
95                    .height();
96            }
97        });
98    }
99
100    /**
101     * animateHorizontal method set up animation for horizontally oriented
102     * accordion component
103     * @memberOf module:Accordion
104     * @param {Object} properties list of properties for accordion component
105     * @alias module:Accordion.animateHorizontal
106     */
107    api.animateHorizontal = function(properties) {
108        var accordion = $(this).parents(".accordion"),
109            panel = $(this).closest(".item"),
110            header = panel.find(".toggle-header"),
111            content = panel.find(".toggle-content"),
112            items = accordion.find(".item"),
113            siblings = panel.siblings(),
114            siblingsContent = siblings.find(".toggle-content");
115
116        panel.toggleClass("active");
117        siblings.removeClass("active");
118        siblings.stop(true).animate(
119            {
120                width: 0
121            },
122            properties.speed,
123            properties.easing,
124            function() {
125                siblingsContent.css({
126                    display: "none"
127                });
128            }
129        );
130
131        if (panel.hasClass("active")) {
132            var slideWidth = accordion.hasClass("accordion-image")
133                    ? content.outerWidth()
134                    : accordion.width() -
135                      ((items.length - 1) * panel.outerWidth() + 2),
136                contentWidth = accordion.hasClass("accordion-image")
137                    ? slideWidth
138                    : slideWidth - header.outerWidth();
139
140            panel.stop(true).animate(
141                {
142                    width: slideWidth
143                },
144                properties.speed,
145                properties.easing,
146                function() {}
147            );
148
149            content.css({
150                width: contentWidth,
151                display: "block"
152            });
153        } else {
154            panel.stop(true).animate(
155                {
156                    width: 0
157                },
158                properties.speed,
159                properties.easing,
160                function() {
161                    content.css({
162                        display: "none"
163                    });
164                }
165            );
166        }
167    };
168    /**
169     * getQueryParamKey get an Id of accordion component
170     * @memberOf module:Accordion
171     * @param {jQuery} accordions  Root Dom element of accordion component
172     * @private
173     * @return {null|string} return id of accordion component
174     */
175    function getQueryParamKey(accordions) {
176        var firstAccordionId = accordions[0].id;
177        if (accordions.length > 0 && firstAccordionId != "") {
178            return firstAccordionId.toLocaleLowerCase();
179        }
180        return null;
181    }
182    /**
183     * accordion method that sets up watchers that animate accordion slide
184     * @memberOf module:Accordion
185     * @method
186     * @private
187     * @param {jQuery} acc Root DOM element of archive component wrapped by jQuery
188     * @param {Object} prop list of properties for accordion component
189     * @alias module:Accordion.accordion
190     */
191    function accordion(acc, properties) {
192        var ev = "click",
193            toggleHeader = acc.find(".toggle-header").filter(function (index, element) {
194                return $(element).closest('.accordion').is(acc);
195            });
196
197        if (properties.expandOnHover) {
198            ev += " mouseenter";
199        }
200
201        toggleHeader.on("mouseover", toogleEvents.focus);
202        toggleHeader.on("mouseleave", toogleEvents.blur);
203        toggleHeader.on("focus", toogleEvents.focus);
204        toggleHeader.on("blur", toogleEvents.blur);
205        toggleHeader.on("keyup", function(e) {
206            if (e.keyCode == 13 || e.keyCode == 32) {
207                $(this).click();
208            }
209        });
210
211        if (acc.hasClass("accordion-horizontal")) {
212            //calc slide width
213            $(document).ready(function() {
214                calcSlideSize(acc);
215            });
216
217            _.each(toggleHeader, function(header) {
218                headerBackground(header);
219            });
220        }
221
222        toggleHeader.on(ev, function() {
223            var $this = $(this),
224                panel = $this.closest(".item"),
225                accordion = $this.parents(".accordion"),
226                content = panel.find(".toggle-content:first"),
227                siblings = panel.siblings(),
228                siblingsContent = siblings.find(".toggle-content");
229
230            // Horizontal animation
231            if (accordion.hasClass("accordion-horizontal")) {
232                api.animateHorizontal.call(this, properties);
233                // Vertical animation
234            } else {
235                // Closes all other items if open
236                // multiple option disabled
237                if (!properties.canOpenMultiple) {
238                    siblings.removeClass("active");
239                    siblingsContent.stop().slideUp({
240                        duration: properties.speed,
241                        easing: properties.easing
242                    });
243                }
244
245                panel.toggleClass("active");
246                // Toggle state of selected item
247                // If toggle state is enabled
248                if (properties.canToggle) {
249                    content.slideToggle({
250                        duration: properties.speed,
251                        easing: properties.easing
252                    });
253                } else {
254                    content.slideDown({
255                        duration: properties.speed,
256                        easing: properties.easing
257                    });
258                }
259            }
260        });
261    }
262    /**
263     * initInstance method prepare Dom elements according accordion setup
264     * and call ["accordion"]{@link module:Accordion.accordion} method
265     * @memberOf module:Acordion
266     * @method
267     * @param {jQuery} component Root DOM element of archive component wrapped by jQuery
268     * @param {Object} prop list of properties for accordion component
269     * @alias module:Accordion.initInstance
270     */
271    api.initInstance = function(component, prop) {
272        // Set tabindex=0 for first header
273        component
274            .find(".toggle-header")
275            .eq(0)
276            .attr("tabindex", "0");
277        //
278        if (component.hasClass("toggle")) {
279            $.extend(prop, {
280                canToggle: true
281            });
282        }
283        component.find(".toggle-content").hide();
284        var current = XA.queryString.getQueryParam(getQueryParamKey(component));
285        if (current != null) {
286            var arr = current.split(",");
287            var items = component.find("ul").first().children();
288            for (var index = 0; index < items.length; index++) {
289                var element = items[index];
290                if (arr.indexOf(index + "") > -1) {
291                    $(element).addClass("active");
292                    $(element)
293                        .find(".toggle-content")
294                        .show();
295                }
296            }
297        } else if (prop.expandedByDefault) {
298            component.find("li:first-child").addClass("active");
299            component
300                .find("li:first-child")
301                .find(".toggle-content")
302                .show();
303        }
304        accordion(component, prop);
305    };
306    /**
307     * init method calls in a loop for each
308     * accordions component on a page and run Accordions
309     * [".initInstance"]{@link module:Accordion.initInstance} method.
310     * @memberOf module:Accordion
311     * @alias module:Accordion.init
312     */
313    api.init = function() {
314        var accordions = $(".accordion:not(.initialized)");
315        accordions.each(function() {
316            var properties = $(this).data("properties"),
317                acc = $(this);
318            api.initInstance(acc, properties);
319            acc.addClass("initialized");
320        });
321    };
322
323    return api;
324})(jQuery);
325
326XA.register("accordions", XA.component.accordions);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.