PageSourceSearch

https://doorcountycoffeewholesale.com/skin/frontend/base/default/js/utilities/action-list.js?v=8.0.0-0

js doorcountycoffeewholesale.com collected 2026-10-08 16:47:55 UTC 10,213 bytes, 276 lines download raw bytes

1/*
2    # How to use ZoeyActionList.
3
4    ## Classes Used
5    #### JavaScript Classes
6    * .zoey-action-list__js__element         - Used to scope the action list.
7    * .zoey-action-list__js__element-trigger - Used to attach click events to trigger hide/show.
8    * .zoey-action-list__js__element-list    - Used to add styles to hide/show.
9
10    #### CSS Classes
11    * .zoey-actions-list-element            - No Styles applied.
12    * .zoey-actions-list-element-trigger    - Used to style the correct pointer.
13    * .zoey-actions-list-element-list       - Used to style the list.
14    
15    #### Dyamic CSS Classes
16    * .zoey-action-list-element-trigger-active - Added by the model when list is active.
17    
18    ## Examples
19    ```js
20        var element = document.getElementById('#whatever-your-id-is');
21
22        // `model` will be direct access to the ZoeyActionList model.
23        var model = ZoeyActionList(element);
24
25        // access to the API. API will remain on element even after destroy. This allows for re-init;
26        jQuery(element).data('ZoeyActionList')
27    ```
28
29    ```html
30        <div class="zoey-action-list__js__element"> <!-- Container Element -->
31            <div class="zoey-action-list__js__element-trigger">This is the trigger</div> <!-- Trigger Element -->
32            <ul class="zoey-action-list__js__element-list"> <!-- List Element -->
33                <li>Item 1</li>
34                <li>Item 2</li>
35            </ul>
36        </div>
37    ```
38*/
39window.Zoey.require(['jQuery', 'pix.globalEvents'], function($, globalEvents) {
40    "use strict";
41
42    window.pix = window.pix || {};
43    window.pix.modules = window.pix.modules || {};
44
45    var idCounter = 0;
46    var $body = null;
47
48    /**
49     * Used to create an actions list.
50     * @param {HTMLElement} element
51     */
52    function ZoeyActionList(element) {
53        this._$element  = $(element);
54        this._$list     = this._$element.find('.'+this.ACTION_ELEMENT_LIST_CLASS).first();
55        this._$trigger  = this._$element.find('.'+this.ACTION_ELEMENT_TRIGGER_CLASS).first();
56        this._$element.data('ZoeyActionList', this.getApi());
57        this._$list.data('ZoeyActionList', this.getApi());
58        this._$trigger.data('ZoeyActionList', this.getApi());
59        this.init();
60    }
61
62    ZoeyActionList.prototype = {
63        ACTION_ELEMENT_CLASS:           'zoey-action-list__js__element',
64        ACTION_ELEMENT_TRIGGER_CLASS:   'zoey-action-list__js__element-trigger',
65        ACTION_ELEMENT_LIST_CLASS:      'zoey-action-list__js__element-list',
66        ACTION_ELEMENT_ID:              'zoey-action-list-element-id',
67        ACTION_ELEMENT_TRIGGER_ACTIVE_CLASS: 'zoey-action-list-element-trigger-active',
68
69        /**
70         * Used to build the elements and set events.
71         * @return {ZoeyActionList}
72         */
73        init: function() {
74            if(this._isInit) return this;
75            this._isInit = true;
76            var elementId = this._$element.attr('id');
77            if(!elementId) {
78                elementId = this.ACTION_ELEMENT_ID + '__' + Date.now() + idCounter;
79                idCounter++;
80                this._$element.attr('id', elementId);
81            }
82
83            this._$list.attr(this.ACTION_ELEMENT_ID, elementId);
84            this._$trigger.attr(this.ACTION_ELEMENT_ID, elementId);
85
86            this._componentId = this._$list.parents('.pix-design-component').first().attr('id');
87            this._$list.css('display', 'none');
88            if(this._componentId){
89                this._$listContainer = jQuery('<div style="width: 0; padding: 0; margin: 0; height: 0; border: 0; outline: 0;">');
90                this._$listContainer.addClass(this._componentId);
91                this._$listContainer.append(this._$list);
92                $body.append(this._$listContainer);
93            } else {
94                // remove the list `ul` from the container and place it in the bottom of the body.
95                $body.append(this._$list);
96            }
97
98            // set click event.
99            this._boundTriggerCallback = this.toggle.bind(this);
100            this._$trigger.on('click', this._boundTriggerCallback);
101
102            // set body click event.
103            this._bodyClickBoundCallback = function(evt) {
104                var element = this._$element.get(0);
105                var listElement = this._$list.get(0);
106                if(!element || !listElement){
107                    this.destroy();
108                } else if( this.isShown() && !$.contains(element, evt.target) && !$.contains(listElement, evt.target) ){
109                    this.hide();
110                }
111            }.bind(this);
112            globalEvents.add('bodyClick', this._bodyClickBoundCallback);
113            this._boundHide = this.hide.bind(this);
114            globalEvents.add('smartresize', this._boundHide);
115        },
116
117        /**
118         * Is the list currently showing.
119         * @return {Boolean}
120         */
121        isShown: function() {
122            return this._$list.css('display') !== 'none';
123        },
124
125        /**
126         * Used to show the list.
127         * @return {ZoeyActionList}
128         */
129        show: function() {
130            // get position of trigger
131            var listStyles = this._$trigger.offset();
132            this._$list.css('display', 'inline-block');
133            listStyles.width = this._$list.outerWidth();
134            listStyles.height = this._$list.outerHeight();
135            this._$list.css('display', 'block');
136
137            if(listStyles.left < (window.outerWidth / 2)) {
138                // open to the right of the trigger.
139                listStyles.left += (this._$trigger.outerWidth() - (this._$trigger.outerWidth() / 2));
140            } else {
141                // open to the left of the trigger.
142                // listStyles.left -= this._$trigger.outerWidth();
143                listStyles.left -= (listStyles.width - (this._$trigger.outerWidth() / 2));
144            }
145
146            var scrollTop = $(document).scrollTop();
147            var scrollBottom = (scrollTop + window.outerHeight);
148
149            if(listStyles.top > (scrollBottom - scrollTop) / 2) {
150                // open to the top of the trigger.
151                listStyles.top -= listStyles.height;
152            } else {
153                // open to the bottom of the trigger.
154                listStyles.top += this._$trigger.outerHeight();
155            }
156
157            listStyles.position = 'absolute';
158            // same zindex as the drawer
159            listStyles.zIndex   = '9999999999';
160            this._$list.css(listStyles);
161            // NOTE zindex should be higher than the FE drawer's z-index (adding another 9 to make it higher doesn't work)
162            // instead append the list again to the parent so that it's the last item
163            this._$list.parent().append(this._$list);
164            this._$trigger.addClass(this.ACTION_ELEMENT_TRIGGER_ACTIVE_CLASS);
165
166            return this;
167        },
168
169        /**
170         * Used to hide the list.
171         * @return {ZoeyActionList}
172         */
173        hide: function() {
174            this._$list.css({
175                position: '',
176                top: '',
177                left: '',
178                display: 'none',
179            });
180            this._$trigger.removeClass(this.ACTION_ELEMENT_TRIGGER_ACTIVE_CLASS);
181
182            return this;
183        },
184
185        /**
186         * Used to toggle the list.
187         * @return {ZoeyActionList}
188         */
189        toggle: function() {
190            if(this.isShown()) {
191                this.hide();
192            } else {
193                this.show();
194            }
195        },
196
197        /**
198         * Used to destroy the model and remove events.
199         * @return {ZoeyActionList}
200         */
201        destroy: function() {
202            // remove all events.
203            if(this._bodyClickBoundCallback) globalEvents.remove('bodyClick', this._bodyClickBoundCallback);
204            if(this._boundTriggerCallback) this._$trigger.off('click', this._boundTriggerCallback);
205            if(this._boundHide) globalEvents.remove('smartresize', this._boundHide);
206
207            // put everything back the way it was.
208            this.hide();
209            this._$list.css('display', '');
210            this._$element.append(this._$list);
211            if(this._$listContainer){
212                this._$listContainer.remove();
213                this._$listContainer = null;
214            }
215
216            var elementId = this._$element.attr('id');
217            if(elementId.indexOf(this.ACTION_ELEMENT_ID) > -1) {
218                this._$element.removeAttr('id');
219            }
220            this._$list.removeAttr(this.ACTION_ELEMENT_ID);
221            this._$trigger.removeAttr(this.ACTION_ELEMENT_ID);
222
223            this._isInit = false;
224            return this;
225        },
226
227        /**
228         * Used to return an API.
229         * @return {Object}
230         */
231        getApi: function() {
232            var self = this;
233            return {
234                show: function() {
235                    self.show();
236                    return this;
237                },
238                hide: function() {
239                    self.hide();
240                    return this;
241                },
242                toggle: function() {
243                    self.toggle();
244                    return this;
245                },
246                isActive: this.isShown.bind(this),
247                destroy: function() {
248                    self.destroy();
249                    return this;
250                },
251                init: function() {
252                    self.init();
253                    return this;
254                },
255            };
256        },
257    };
258
259    // Adding it as a module.
260    window.pix.modules.ZoeyActionList = ZoeyActionList;
261
262    function initModule(elements){
263        var elementsToInit = elements instanceof Array ? $(elements) : $(document.body);
264        $body = $(document.body);
265
266        // init all action-lists
267        elementsToInit.find('.'+ZoeyActionList.prototype.ACTION_ELEMENT_CLASS).each(function(index, element) {
268            new ZoeyActionList(element);
269        });
270    }
271
272    globalEvents.add('layoutUpdate', initModule);
273    globalEvents.add('documentLoaded', initModule);
274
275    window.Zoey.export('pix.modules.ZoeyActionList');
276});

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.