PageSourceSearch

https://industrycity.com/wp-content/themes/ci-uikit/js/pages/availabilities.js?ver=1.15bl

js industrycity.com collected 2026-10-02 04:55:54 UTC 10,105 bytes, 316 lines download raw bytes

1class ReorderItems {
2    constructor(sel) {
3        this.component = document.querySelector(sel);
4        if (!this.component) return;
5        this.bttns = this.component.querySelectorAll('.title-wrapper button');
6        this.itemsSelector = '.item'
7
8
9        this._init();
10    }
11    _init() {
12        if (!this.bttns) return;
13        this.bttns.forEach(bttn => {
14            bttn.addEventListener('click', () => {
15
16                this.bttns.forEach(bttn => bttn.dataset.order = "neutral")
17                bttn.dataset.order = this._getNextOrder(bttn.dataset.order);
18                this.reorderItems(bttn.dataset.name, bttn.dataset.order)
19            })
20        })
21    }
22    reorderItems = (category, order) => {
23        if (order == 'neutral') return console.warn(`${category} order is neutral, no reorder were made`);
24        tinysort(this.itemsSelector, { data: category, order: order, natural: true });
25    };
26    _getNextOrder = (order) => {
27        switch (order) {
28            case 'neutral':
29                return 'asc';
30            case 'asc':
31                return 'desc';
32            case 'desc':
33                return 'asc';
34            default:
35                return 'asc'
36        }
37    }
38}
39
40class CategorizeItems {
41
42    constructor() {
43        // CATEGORIES PROPERTIES
44        this.component = document.querySelector('.categorize-items');
45        if (!this.component) return;
46        this.filter = this.component.querySelector('.categorizer, .filter');
47        this.items = this.component.querySelectorAll('.item');
48        this.defaultCategory = this.filter.querySelector('[data-default]')?.dataset.category
49            ? this.filter.querySelector('[data-default]')?.dataset.category
50            : this.filter.querySelector('[data-category]')?.dataset.category
51        this.activeCategory = false;
52        // CATEGORIES PROPERTIES
53
54        this.transitionTime = 500;
55
56
57        this.events = {
58            preFilter: (item) => true,
59            changed: () => { },
60            ready: () => { },
61        }
62        this.state = {
63            empty: () => this.setState('empty'),
64            ready: () => this.setState('ready'),
65        }
66    }
67
68
69    async init() {
70        if (this.filter) this._initFilter();
71        await this.setState('loading');
72        const status = this.setCategory();
73        this.state[status]();
74        this.events.ready();
75    }
76
77
78    async setState(state) {
79        this.component.dataset.state = state;
80        await this._sleep(this.transitionTime)
81    }
82
83
84    on(event, cb) {
85        this.events[event] = cb;
86    }
87
88    setCategoryFromUrl(value) {
89        const url = new URL(window.location); // Crear un objeto URL basado en el URL actual
90        url.searchParams.set('category', value); // Añadir o actualizar el parámetro
91        window.history.replaceState(null, '', url); // Actualizar la URL sin recargar la página
92    }
93
94    getCategoryFromUrl = () => new URLSearchParams(window.location.search).get('category')
95
96    updateState = async () => {
97        await this.setState('loading');
98        const status = this.setCategory(this.component.dataset.category);
99        await this._sleep(100)
100        this.state[status]();
101    }
102
103    setCategory = (cat) => {
104        this.activeCategory = cat ?? this.getCategoryFromUrl() ?? this.defaultCategory;
105
106        debugger
107
108        this.setCategoryFromUrl(this.activeCategory);
109
110        this.component.dataset.category = this.activeCategory;
111
112        const state = this.updateItemsState();
113
114        if (this.filter) this._updateFilterState();
115
116        this.events.changed();
117        return state;
118    }
119
120
121    // CATEGORIES METHODS
122    _initFilter() {
123
124        this.filter.addEventListener('click', async (e) => {
125
126            const isMobile = this.WW < 960;
127
128            const isSelector =
129                (isMobile && this.filter.classList.contains('selector-mobile'))
130                || (!isMobile && this.filter.classList.contains('selector-desktop'))
131                || this.filter.classList.contains('selector');
132
133            if (isSelector) this.filter.classList.toggle('open');
134
135            if (!e.target.matches('.category')) return;
136
137            await this.setState('loading');
138            const status = this.setCategory(e.target.dataset.category);
139            await this._sleep(100)
140            this.state[status]();
141
142
143
144        })
145    }
146
147
148    updateItemsState() {
149        let state = 'empty';
150
151        this.items.forEach(item => {
152            const passedOthersFilters = this.events.preFilter(item);
153            const isActive = item.dataset.category === this.activeCategory || this.activeCategory === 'all';
154            item.classList.toggle('active', passedOthersFilters && isActive);
155
156            if (!passedOthersFilters || !isActive) return;
157            state = 'ready';
158
159        });
160        return state;
161    }
162
163
164    _updateFilterState() {
165        const filters = this.filter.querySelectorAll('li');
166        filters.forEach(item => {
167            const isActive = item.dataset.category === this.activeCategory;
168            item.classList.toggle('active', isActive);
169
170            if (!isActive) return;
171            const catName = item.querySelector('span');
172            const mobileTitle = this.filter.querySelector('header span');
173            if (mobileTitle) mobileTitle.innerHTML = catName.innerHTML;
174
175        });
176    }
177
178    get WW() { return window.innerWidth }
179    _sleep = async (ms) => new Promise(resolve => setTimeout(resolve, ms));
180
181}
182
183class RangeItems {
184    constructor(sel) {
185        // CATEGORIES PROPERTIES
186        this.component = document.querySelector(sel);
187        if (!this.component) return;
188        this.filter = this.component.querySelector('.ranger');
189        this.items = this.component.querySelectorAll('.item');
190        this.defaultCategory = this.filter.querySelector('[data-default]')?.dataset.category
191            ? this.filter.querySelector('[data-default]')?.dataset.category
192            : this.filter.querySelector('[data-min][data-max]')?.dataset.category
193        this.activeCategory = false;
194        this.events = {
195            changed: () => { },
196        }
197
198        this._init();
199    }
200
201    async _init() {
202        this.setDefaultMinMax();
203        if (this.filter) this._initFilter();
204    }
205
206    on(event, cb) {
207        this.events[event] = cb;
208    }
209    isInRange = (number) => {
210        const x = Number(number);
211        const min = Number(this.component.dataset.min)
212        const max = Number(this.component.dataset.max)
213        if (!max) return console.warn("Missing max range:", max);
214        return x >= min && x <= max;
215    }
216    _initFilter() {
217
218        this.filter.addEventListener('click', async (e) => {
219
220            const isMobile = this.WW < 960;
221
222            const isSelector =
223                (isMobile && this.filter.classList.contains('selector-mobile'))
224                || (!isMobile && this.filter.classList.contains('selector-desktop'))
225                || this.filter.classList.contains('selector');
226
227            if (isSelector) this.filter.classList.toggle('open');
228
229            if (!e.target.matches('.category')) return;
230
231            this.filter.querySelectorAll('li').forEach(filter => {
232                filter.classList.toggle('active', false)
233            })
234
235            e.target.classList.toggle('active', true);
236
237            this.component.dataset.min = e.target.dataset.min;
238            this.component.dataset.max = e.target.dataset.max;
239            this.events.changed();
240        })
241    }
242
243    updateFilterState = () => {
244        const filters = this.filter.querySelectorAll('li');
245        console.log(filters)
246        filters.forEach(item => {
247            const isActive = item.classList.contains('active');
248            item.classList.toggle('active', isActive);
249
250            if (!isActive) return;
251            const catName = item.querySelector('span');
252            const mobileTitle = this.filter.querySelector('header span');
253            if (mobileTitle) mobileTitle.innerHTML = catName.innerHTML;
254
255        });
256    }
257    setDefaultMinMax = () => {
258        const params = new URLSearchParams(window.location.search);
259        this.component.dataset.min = Number(params.get('min')) ?? 0;
260        this.component.dataset.max = Number(params.get('max')) == 0 ? Infinity : Number(params.get('max'));
261    }
262}
263
264class Availabilities {
265
266    constructor(sel) {
267        // view
268        this.page = document.querySelector(sel);
269        if (!this.page) return;
270        this.swiperSel = '.featured-swiper';
271        this.categorizeItems = new CategorizeItems();
272        this.reorderItems = new ReorderItems('.unit-list');
273        this.rangeItems = new RangeItems('.unit-list');
274        if (!this.page) return;
275
276        if (this.page) {
277            this.init();
278        }
279    }
280
281    init() {
282        if (this.page.querySelector(this.swiperSel)) this._initSwiper();
283        if (this.page.querySelector('.unit-list')) {
284            this.categorizeItems.on('preFilter', (item) => {
285                return this.rangeItems.isInRange(item.dataset.size);
286            })
287            this.rangeItems.on('changed', async () => {
288                this.categorizeItems.updateState();
289                this.rangeItems.updateFilterState();
290            })
291            this.categorizeItems.init();
292        };
293
294    }
295    _initSwiper = () => {
296        const swiper = new Swiper(this.swiperSel, {
297            slidesPerView: 1.2,
298            navigation: {
299                nextEl: '.swiper-button-next',
300                prevEl: '.swiper-button-prev',
301            },
302            breakpoints: {
303                960: {
304                    slidesPerView: 4,
305                },
306            }
307        });
308    }
309    _initFilters = () => {
310
311    }
312
313}
314document.addEventListener('DOMContentLoaded', () => {
315    new Availabilities('.availabilities');
316})

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.