]> BookStack Code Mirror - bookstack/blob - resources/js/components/shelf-sort.js
Finished updating remainder of JS components to new system
[bookstack] / resources / js / components / shelf-sort.js
1 import Sortable from "sortablejs";
2 import {Component} from "./component";
3
4 export class ShelfSort extends Component {
5
6     setup() {
7         this.elem = this.$el;
8         this.input = this.$refs.input;
9         this.shelfBookList = this.$refs.shelfBookList;
10         this.allBookList = this.$refs.allBookList;
11         this.bookSearchInput = this.$refs.bookSearch;
12
13         this.initSortable();
14         this.setupListeners();
15     }
16
17     initSortable() {
18         const scrollBoxes = this.elem.querySelectorAll('.scroll-box');
19         for (const scrollBox of scrollBoxes) {
20             new Sortable(scrollBox, {
21                 group: 'shelf-books',
22                 ghostClass: 'primary-background-light',
23                 handle: '.handle',
24                 animation: 150,
25                 onSort: this.onChange.bind(this),
26             });
27         }
28     }
29
30     setupListeners() {
31         this.elem.addEventListener('click', event => {
32             const sortItem = event.target.closest('.scroll-box-item');
33             if (sortItem) {
34                 event.preventDefault();
35                 this.sortItemClick(sortItem);
36             }
37         });
38
39         this.bookSearchInput.addEventListener('input', event => {
40             this.filterBooksByName(this.bookSearchInput.value);
41         });
42     }
43
44     /**
45      * @param {String} filterVal
46      */
47     filterBooksByName(filterVal) {
48
49         // Set height on first search, if not already set, to prevent the distraction
50         // of the list height jumping around
51         if (!this.allBookList.style.height) {
52             this.allBookList.style.height = this.allBookList.getBoundingClientRect().height + 'px';
53         }
54
55         const books = this.allBookList.children;
56         const lowerFilter = filterVal.trim().toLowerCase();
57
58         for (const bookEl of books) {
59             const show = !filterVal || bookEl.textContent.toLowerCase().includes(lowerFilter);
60             bookEl.style.display = show ? null : 'none';
61         }
62     }
63
64     /**
65      * Called when a sort item is clicked.
66      * @param {Element} sortItem
67      */
68     sortItemClick(sortItem) {
69         const lists = this.elem.querySelectorAll('.scroll-box');
70         const newList = Array.from(lists).filter(list => sortItem.parentElement !== list);
71         if (newList.length > 0) {
72             newList[0].appendChild(sortItem);
73         }
74         this.onChange();
75     }
76
77     onChange() {
78         const shelfBookElems = Array.from(this.shelfBookList.querySelectorAll('[data-id]'));
79         this.input.value = shelfBookElems.map(elem => elem.getAttribute('data-id')).join(',');
80     }
81
82 }