fix race in filters
[wolnelektury.git] / src / catalogue / static / 2022 / book / filter.js
1 (function($) {
2
3     let unpagedSearch = null;
4     if (!$(".quick-filter").val() && !$('.l-pagination li').length) {
5         unpagedSearch = '';
6     }
7     
8     function get_page(page, search, ordering, callback) {
9         get_page_by_url('.?page=' + page + '&order=' + ordering + '&search=' + search, callback);
10     }
11
12     let lastFulfilledPage = 0;
13
14     function get_page_by_url(url, callback) {
15         let requestTime = + new Date();
16         $.get(
17             url,
18             function(data) {
19                 if (lastFulfilledPage > requestTime) return;
20                 lastFulfilledPage = requestTime;
21
22                 html = $(data);
23                 objectList = $('#object-list', html);
24                 paginate = $('#paginate', html);
25
26                 ids = new Set(); 
27                 $(".icon-like", objectList).each(
28                     (i, e)=>{
29                         ids.add($(e).attr('data-book'));
30                     }
31                 );
32                 ids = [...ids].join(',');
33                 $.refreshLikes(ids);
34
35                 $('#book-list').html(objectList.children());
36                 $('#paginator').html(paginate.children());
37                 history.replaceState({}, '', url);
38                 callback && callback();
39             }
40         )
41     }
42
43     $("#paginator").on('click', 'a', function() {
44         get_page_by_url(url=$(this).attr('href'));
45         return false;
46     });
47
48     $(".quick-filter").each(function() {
49         let bookList = $('#' + $(this).data('for'));
50         let filterList = $('.' + $(this).data('filters'));
51
52         $(this).on('focus', function() {
53             filterList.addClass('filters-enabled');
54         });
55         $(this).on('blur', function() {
56             filterList.removeClass('filters-enabled');
57         });
58
59         $(this).on('input propertychange', function() {
60             let search = $(this).val().toLowerCase();
61
62             if (!search.startsWith(unpagedSearch)) {
63                 get_page(1, search, 'title', function() {
64                     if ($('.l-pagination li').length) {
65                         unpagedSearch = null;
66                     }
67                 })
68             } else {
69                 bookList.children().each(function() {
70                     found = !search ||
71                         $(".s", this).text().toLowerCase().search(search) != -1
72                     ;
73                     if (found) 
74                         $(this).fadeIn();
75                     else
76                         $(this).fadeOut();
77                 });
78             }
79
80             $('.filter-container', filterList).children().each(function() {
81                 found = !search ||
82                     $(this).text().toLowerCase().search(search) != -1
83                     ;
84                 if (found) 
85                     $(this).fadeIn();
86                 else
87                     $(this).fadeOut();
88             });
89         });
90
91     });
92
93     $(".l-books__sorting button").on('click', function() {
94         if ($(this).hasClass('is-active')) return;
95         $(".is-active", $(this).parent()).removeClass("is-active");
96         $(this).addClass("is-active");
97         let prop = $(this).attr('data-order');
98
99
100         // do we NOW have pages (possibly after filtering)?
101         // if we don't have pages, we can just sort here.
102         let havePages = $('.l-pagination li').length > 0;
103
104         $(".l-books__item").css('opacity', '0');
105         setTimeout(function() {
106             if (havePages) {
107                 get_page(1, '', prop);
108             } else {
109                 if (prop) {
110                     $(".l-books__item").each(function() {
111                         $(this).css('order', $(this).attr('data-' + prop));
112                     });
113                 } else {
114                     $(".l-books__item").css('order', '');
115                 }
116                 setTimeout(function() {
117                     $(".l-books__item").css('opacity', '100%');
118                 }, 200);
119             }
120         }, 200);
121     });
122     
123 })(jQuery);