1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 | import settings from '../../globals/js/settings';
|
9 | import mixin from '../../globals/js/misc/mixin';
|
10 | import createComponent from '../../globals/js/mixins/create-component';
|
11 | import initComponentBySearch from '../../globals/js/mixins/init-component-by-search';
|
12 | import handles from '../../globals/js/mixins/handles';
|
13 | import on from '../../globals/js/misc/on';
|
14 |
|
15 | class PaginationNav extends mixin(
|
16 | createComponent,
|
17 | initComponentBySearch,
|
18 | handles
|
19 | ) {
|
20 | |
21 |
|
22 |
|
23 |
|
24 |
|
25 |
|
26 |
|
27 | constructor(element, options) {
|
28 | super(element, options);
|
29 | this.manage(on(this.element, 'click', (evt) => this.handleClick(evt)));
|
30 | this.manage(
|
31 | on(this.element, 'change', (evt) => {
|
32 | if (evt.target.matches(this.options.selectorPageSelect)) {
|
33 | this.handleSelectChange(evt);
|
34 | }
|
35 | })
|
36 | );
|
37 | }
|
38 |
|
39 | |
40 |
|
41 |
|
42 | getActivePageNumber = () => {
|
43 | let pageNum;
|
44 | const activePageElement = this.element.querySelector(
|
45 | this.options.selectorPageActive
|
46 | );
|
47 | if (activePageElement) {
|
48 | pageNum = Number(activePageElement.getAttribute(this.options.attribPage));
|
49 | }
|
50 | return pageNum;
|
51 | };
|
52 |
|
53 | |
54 |
|
55 |
|
56 | clearActivePage = (evt) => {
|
57 | const pageButtonNodeList = this.element.querySelectorAll(
|
58 | this.options.selectorPageButton
|
59 | );
|
60 | const pageSelectElement = this.element.querySelector(
|
61 | this.options.selectorPageSelect
|
62 | );
|
63 | Array.prototype.forEach.call(pageButtonNodeList, (el) => {
|
64 | el.classList.remove(this.options.classActive, this.options.classDisabled);
|
65 | el.removeAttribute(this.options.attribActive);
|
66 | el.removeAttribute('aria-disabled');
|
67 | el.removeAttribute('aria-current');
|
68 | });
|
69 | if (pageSelectElement) {
|
70 | pageSelectElement.removeAttribute('aria-current');
|
71 | const pageSelectElementOptions = pageSelectElement.options;
|
72 | Array.prototype.forEach.call(pageSelectElementOptions, (el) => {
|
73 | el.removeAttribute(this.options.attribActive);
|
74 | });
|
75 | if (!evt.target.matches(this.options.selectorPageSelect)) {
|
76 | pageSelectElement.classList.remove(this.options.classActive);
|
77 | pageSelectElement.value = '';
|
78 | }
|
79 | }
|
80 | };
|
81 |
|
82 | |
83 |
|
84 |
|
85 | handleClick = (evt) => {
|
86 | if (!evt.target.getAttribute('aria-disabled') === true) {
|
87 | let nextActivePageNumber = this.getActivePageNumber();
|
88 | const pageElementNodeList = this.element.querySelectorAll(
|
89 | this.options.selectorPageElement
|
90 | );
|
91 | const pageSelectElement = this.element.querySelector(
|
92 | this.options.selectorPageSelect
|
93 | );
|
94 | this.clearActivePage(evt);
|
95 | if (evt.target.matches(this.options.selectorPageButton)) {
|
96 | nextActivePageNumber = Number(
|
97 | evt.target.getAttribute(this.options.attribPage)
|
98 | );
|
99 | }
|
100 | if (evt.target.matches(this.options.selectorPagePrevious)) {
|
101 | nextActivePageNumber -= 1;
|
102 | }
|
103 | if (evt.target.matches(this.options.selectorPageNext)) {
|
104 | nextActivePageNumber += 1;
|
105 | }
|
106 | const pageTargetElement = pageElementNodeList[nextActivePageNumber - 1];
|
107 | pageTargetElement.setAttribute(this.options.attribActive, true);
|
108 | if (pageTargetElement.tagName === 'OPTION') {
|
109 | pageSelectElement.value = this.getActivePageNumber();
|
110 | pageSelectElement.classList.add(this.options.classActive);
|
111 | pageSelectElement.setAttribute('aria-current', 'page');
|
112 | } else {
|
113 | pageTargetElement.classList.add(
|
114 | this.options.classActive,
|
115 | this.options.classDisabled
|
116 | );
|
117 | pageTargetElement.setAttribute('aria-disabled', true);
|
118 | pageTargetElement.setAttribute('aria-current', 'page');
|
119 | }
|
120 | this.setPrevNextStates();
|
121 | }
|
122 | };
|
123 |
|
124 | |
125 |
|
126 |
|
127 | handleSelectChange = (evt) => {
|
128 | this.clearActivePage(evt);
|
129 | const pageSelectElement = this.element.querySelector(
|
130 | this.options.selectorPageSelect
|
131 | );
|
132 | const pageSelectElementOptions = pageSelectElement.options;
|
133 | pageSelectElementOptions[
|
134 | pageSelectElementOptions.selectedIndex
|
135 | ].setAttribute(this.options.attribActive, true);
|
136 | evt.target.setAttribute('aria-current', 'page');
|
137 | evt.target.classList.add(this.options.classActive);
|
138 | this.setPrevNextStates();
|
139 | };
|
140 |
|
141 | |
142 |
|
143 |
|
144 | setPrevNextStates = () => {
|
145 | const pageElementNodeList = this.element.querySelectorAll(
|
146 | this.options.selectorPageElement
|
147 | );
|
148 | const totalPages = pageElementNodeList.length;
|
149 | const pageDirectionElementPrevious = this.element.querySelector(
|
150 | this.options.selectorPagePrevious
|
151 | );
|
152 | const pageDirectionElementNext = this.element.querySelector(
|
153 | this.options.selectorPageNext
|
154 | );
|
155 | if (pageDirectionElementPrevious) {
|
156 | if (this.getActivePageNumber() <= 1) {
|
157 | pageDirectionElementPrevious.setAttribute('aria-disabled', true);
|
158 | pageDirectionElementPrevious.classList.add(this.options.classDisabled);
|
159 | } else {
|
160 | pageDirectionElementPrevious.removeAttribute('aria-disabled');
|
161 | pageDirectionElementPrevious.classList.remove(
|
162 | this.options.classDisabled
|
163 | );
|
164 | }
|
165 | }
|
166 | if (pageDirectionElementNext) {
|
167 | if (this.getActivePageNumber() >= totalPages) {
|
168 | pageDirectionElementNext.setAttribute('aria-disabled', true);
|
169 | pageDirectionElementNext.classList.add(this.options.classDisabled);
|
170 | } else {
|
171 | pageDirectionElementNext.removeAttribute('aria-disabled');
|
172 | pageDirectionElementNext.classList.remove(this.options.classDisabled);
|
173 | }
|
174 | }
|
175 | };
|
176 |
|
177 | |
178 |
|
179 |
|
180 |
|
181 |
|
182 | static components = new WeakMap();
|
183 |
|
184 | |
185 |
|
186 |
|
187 |
|
188 |
|
189 |
|
190 |
|
191 |
|
192 |
|
193 |
|
194 |
|
195 |
|
196 |
|
197 |
|
198 |
|
199 |
|
200 | static get options() {
|
201 | const { prefix } = settings;
|
202 | return {
|
203 | selectorInit: '[data-pagination-nav]',
|
204 | selectorPageElement: '[data-page]',
|
205 | selectorPageButton: '[data-page-button]',
|
206 | selectorPagePrevious: '[data-page-previous]',
|
207 | selectorPageNext: '[data-page-next]',
|
208 | selectorPageSelect: '[data-page-select]',
|
209 | selectorPageActive: '[data-page-active="true"]',
|
210 | attribPage: 'data-page',
|
211 | attribActive: 'data-page-active',
|
212 | classActive: `${prefix}--pagination-nav__page--active`,
|
213 | classDisabled: `${prefix}--pagination-nav__page--disabled`,
|
214 | };
|
215 | }
|
216 | }
|
217 |
|
218 | export default PaginationNav;
|