• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (C) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16export class PageNation {
17  element: any;
18  pageInfo: any;
19  first: any;
20  prev: any;
21  next: any;
22  last: any;
23  inputBox: any;
24  btn: any;
25  list: any;
26  origin: HTMLElement | undefined;
27  static BtnBackColor = '#6C9BFA';
28  static BtnColor = '#fff';
29  constructor(selector: any, options = {}) {
30    selector!.innerHTML = '';
31    //最大容器
32    this.element = selector;
33    // 默认值
34    this.pageInfo = {
35      current: 1,
36      total: 100,
37      pageSize: 15,
38    };
39    //等待创建的元素
40    this.first = null;
41    this.prev = null;
42    this.next = null;
43    this.last = null;
44    // 输入框
45    this.inputBox = null;
46    // 跳转按钮
47    this.btn = null;
48    // 中间的按钮组
49    this.list = null;
50    this.setPageOptions(options);
51    this.setItemStyles();
52    this.createPageElement();
53    this.bindPageHtml();
54    this.bindPageEvent();
55  }
56
57  setPageOptions(options: any) {
58    // 当前页
59    this.pageInfo.current = options.current || 1;
60    // 一页显示多少条
61    this.pageInfo.pageSize = options.pageSize || 15;
62    if (options.totalpage) {
63      //用户传递了多少页
64      this.pageInfo.totalpage = options.totalpage;
65    } else {
66      //没有传递多少页
67      if (options.total) {
68        // 如果传递了总条数
69        this.pageInfo.totalpage = Math.ceil(options.total / this.pageInfo.pageSize);
70      } else {
71        // 如果没有传递总条数
72        this.pageInfo.totalpage = 9;
73      }
74    }
75    this.pageInfo.first = options.first || '<<';
76    this.pageInfo.change = options.change || function () {};
77  }
78
79  setElementStyles(ele: any, styles: any) {
80    for (let key in styles) {
81      ele.style[key] = styles[key];
82    }
83  }
84
85  setItemStyles() {
86    this.setElementStyles(this.element, {
87      margin: '18px auto',
88      display: 'flex',
89      alignItems: 'center',
90      justifyContent: 'center',
91    });
92  }
93
94  createElement(jumpDiv:HTMLElement):void{
95    // Create input field
96    this.inputBox = document.createElement('input');
97    this.inputBox.value = this.pageInfo.current;
98    this.setElementStyles(this.inputBox, {
99      width: '35px',
100      height: '30px',
101      textAlign: 'center',
102      outline: 'none',
103      padding: '0',
104      border: '0',
105      'border-radius': '5px',
106    });
107    jumpDiv.appendChild(this.inputBox);
108    let span = document.createElement('span');
109    span.style.width = '1px';
110    span.style.height = '24px';
111    span.style.alignSelf = 'center';
112    span.style.backgroundColor = '#999999';
113    jumpDiv.appendChild(span);
114    // Create button
115    this.btn = document.createElement('button');
116    this.btn.innerText = '';
117    this.btn.name = 'goto';
118    this.setElementStyles(this.btn, {
119      height: '32px',
120      width: '30px',
121      cursor: 'pointer',
122      backgroundColor: '#FFF',
123      border: '0',
124      'border-radius': '5px',
125    });
126    this.btn.style.background = `url('img/arrowright.png') no-repeat 98% center var(--dark-background3,#FFFFFF)`;
127    this.btn.style.backgroundPosition = 'center';
128    jumpDiv.appendChild(this.btn);
129    this.element.appendChild(jumpDiv);
130  }
131
132  // 创建元素 首页 上一页 按钮组  下一页 尾页 输入框 按钮
133  createPageElement() {
134    //首页
135    this.origin = document.createElement('p');
136    this.setElementStyles(this.origin, {
137      'border-radius': '4px',
138      padding: '5px',
139      border: '1px solid rgba(0,0,0,0.6)',
140      cursor: 'pointer',
141      margin: '0 5px',
142    });
143    this.first = this.origin.cloneNode(true);
144    this.first.innerText = this.pageInfo.first;
145    this.first.name = 'first';
146    this.element.appendChild(this.first);
147    this.prev = this.origin.cloneNode(true);
148    this.prev.innerText = '<';
149    this.prev.name = 'prev';
150    this.prev.style.padding = '5px 10px';
151    this.element.appendChild(this.prev);
152    // 创建ul
153    this.list = document.createElement('ul');
154    this.setElementStyles(this.list, {
155      display: 'flex',
156      padding: '0',
157    });
158    this.element.appendChild(this.list);
159    this.next = this.origin.cloneNode(true);
160    this.next.innerText = '>';
161    this.next.name = 'next';
162    this.next.style.padding = '5px 10px';
163    this.next.style.margin = '0px 5px';
164    this.element.appendChild(this.next);
165    this.last = this.origin.cloneNode(true);
166    this.last.innerText = '>>';
167    this.last.name = 'last';
168    this.last.style.padding = '5px';
169    this.last.style.margin = '0px 5px';
170    this.element.appendChild(this.last);
171    let jumpDiv = document.createElement('div');
172    jumpDiv.style.display = 'flex';
173    jumpDiv.style.border = '1px solid rgba(0,0,0,0.6)';
174    jumpDiv.style.borderRadius = '4px';
175    jumpDiv.style.width = '70px';
176    jumpDiv.style.height = '32px';
177    jumpDiv.style.marginLeft = '10px';
178
179    this.createElement(jumpDiv);
180  }
181
182  // 判断首页 上一页 下一页 尾页 是否可以点击
183  bindPageHtml() {
184    const { current, totalpage } = this.pageInfo;
185    const disable = { color: '#999999', cursor: 'not-allowed' };
186    const enable = {
187      color: '#000',
188      cursor: 'pointer',
189    };
190    // 判断当前页是否是第一页  如果是第一页  那么首页和上一页就不能点击
191    if (current <= 1) {
192      this.setElementStyles(this.first, disable);
193      this.setElementStyles(this.prev, disable);
194    } else {
195      this.setElementStyles(this.first, enable);
196      this.setElementStyles(this.prev, enable);
197    }
198    // 判断当前页是否是最后一页  如果是最后一页  那么下一页和尾页就不能点击
199    if (current >= totalpage) {
200      this.setElementStyles(this.next, disable);
201      this.setElementStyles(this.last, disable);
202    } else {
203      this.setElementStyles(this.next, enable);
204      this.setElementStyles(this.last, enable);
205    }
206    this.inputBox.value = current;
207    //渲染的时候判断ul列表的显示情况
208    this.bindPageList();
209    this.pageInfo.change(this.pageInfo.current);
210  }
211
212  bindPageList() {
213    this.list.innerHTML = '';// clear ul its contents
214    const { pageSize, current, totalpage } = this.pageInfo;//Clean the ul before each load
215    const origin = document.createElement('li');
216    origin.dataset.name = 'item';
217    this.setElementStyles(origin, {
218      listStyle: 'none',
219      'border-radius': '4px',
220      border: '1px solid rgba(0,0,0,0.6)',
221      padding: '5px 10px',
222      margin: '0 5px',
223      cursor: 'pointer',
224    });
225    if (totalpage <= 9) {
226      for (let i = 0; i < totalpage; i++) {
227        this.buildLi(origin, i, current);
228      }
229      return;
230    }
231    // Five on the left... Two on the right
232    if (this.bindLeftList(current, totalpage, origin)) {
233      return;
234    }
235    // The current page is larger than 5 pages and smaller than the last 5 pages
236    for (let index = 0; index < 2; index++) {
237      this.buildLi(origin, index, current);
238    }
239    let span = document.createElement('span');
240    span.innerText = '...';
241    this.list.appendChild(span);
242    for (let i = current - 3; i < current + 2; i++) {
243      this.buildLi(origin, i, current);
244    }
245    span = document.createElement('span');
246    span.innerText = '...';
247    this.list.appendChild(span);
248    for (let i = totalpage - 2; i < totalpage; i++) {
249      this.buildLi(origin, i, current);
250    }
251  }
252
253  private buildLi(origin: HTMLElement, i: number, current: number) {
254    const li = origin.cloneNode(true);
255    // @ts-ignore
256    li.innerText = i + 1;
257    if (i + 1 === current) {
258      this.setElementStyles(li, {
259        backgroundColor: PageNation.BtnBackColor,
260        color: PageNation.BtnColor,
261      });
262    }
263    this.list.appendChild(li);
264  }
265
266  bindLeftList(current: number, totalpage: number, origin: HTMLElement): boolean {
267    let span;
268    if (current < 5) {
269      // 左边5个 中间 ... 右边2个
270      for (let index = 0; index < 5; index++) {
271        this.buildLi(origin, index, current);
272      }
273      span = document.createElement('span');
274      span.innerText = '...';
275      this.list.appendChild(span);
276      for (let index = totalpage - 2; index < totalpage; index++) {
277        this.buildLi(origin, index, current);
278      }
279      return true;
280    }
281    if (current == 5) {
282      // 左边5个 中间 ... 右边2个
283      for (let i = 0; i < 7; i++) {
284        this.buildLi(origin, i, current);
285      }
286      span = document.createElement('span');
287      span.innerText = '...';
288      this.list.appendChild(span);
289
290      for (let index = totalpage - 2; index < totalpage; index++) {
291        this.buildLi(origin, index, current);
292      }
293      return true;
294    }
295    // 当前页面 大于倒数第5页
296    if (current > totalpage - 4) {
297      // 左边5个 中间 ... 右边2个
298      for (let index = 0; index < 2; index++) {
299        this.buildLi(origin, index, current);
300      }
301      span = document.createElement('span');
302      span.innerText = '...';
303      this.list.appendChild(span);
304      for (let i = totalpage - 5; i < totalpage; i++) {
305        this.buildLi(origin, i, current);
306      }
307      return true;
308    }
309    if (current == totalpage - 4) {
310      // 左边5个 中间 ... 右边2个
311      this.nodeAppendChild(origin,current,span,totalpage);
312      return true;
313    }
314    return false;
315  }
316
317  nodeAppendChild(origin: HTMLElement,current: number,span: any,totalpage: number):void{
318    for (let i = 0; i < 2; i++) {
319      this.buildLi(origin, i, current);
320    }
321    span = document.createElement('span');
322    span.innerText = '...';
323    this.list.appendChild(span);
324    for (let i = totalpage - 7; i < totalpage; i++) {
325      this.buildLi(origin, i, current);
326    }
327  }
328
329  bindPageEvent() {
330    this.element.addEventListener(
331      'click',
332      (event: {
333        target: {
334          name: string;
335          dataset: { name: string };
336          innerText: number;
337        };
338      }) => {
339        this.targetName(event);
340        if (event.target.name === 'goto') {
341          // 拿到你文本的内容
342          let page = this.inputBox.value - 0;
343          if (isNaN(page)) {
344            page = 1;
345          }
346          if (page <= 1) {
347            page = 1;
348          }
349          if (page >= this.pageInfo.totalpage) {
350            page = this.pageInfo.totalpage;
351          }
352          this.pageInfo.current = page;
353          this.bindPageHtml();
354        }
355        if (event.target.dataset.name === 'item') {
356          this.pageInfo.current = event.target.innerText - 0;
357          this.bindPageHtml();
358        }
359      }
360    );
361  }
362
363  targetName(event:{
364    target: {
365      name: string;
366      dataset: { name: string };
367      innerText: number;
368    };
369  }):void{
370    if (event.target.name === 'first') {
371      if (this.pageInfo.current === 1) return;
372      this.pageInfo.current = 1;
373      this.bindPageHtml();
374    }
375    if (event.target.name === 'prev') {
376      if (this.pageInfo.current === 1) return;
377      this.pageInfo.current--;
378      this.bindPageHtml();
379    }
380    if (event.target.name === 'next') {
381      if (this.pageInfo.current === this.pageInfo.totalpage) return;
382      this.pageInfo.current++;
383      this.bindPageHtml();
384    }
385    if (event.target.name === 'last') {
386      if (this.pageInfo.current === this.pageInfo.totalpage) return;
387      this.pageInfo.current = this.pageInfo.totalpage;
388      this.bindPageHtml();
389    }
390  }
391}
392