3149: Fix user-controlled filters overwriting page-controlled filters.
[arvados.git] / apps / workbench / app / assets / javascripts / filterable.js
1 $(document).
2     on('paste keyup input', 'input[type=text].filterable-control', function() {
3         var $target = $($(this).attr('data-filterable-target'));
4         var currentquery = $target.data('filterable-query');
5         if (currentquery === undefined) currentquery = '';
6         if ($target.is('[data-infinite-scroller]')) {
7             // We already know how to load content dynamically, so we
8             // can do all filtering on the server side.
9
10             if ($target.data('infinite-cooloff-timer') > 0) {
11                 // Clear a stale refresh-after-delay timer.
12                 clearTimeout($target.data('infinite-cooloff-timer'));
13             }
14             // Stash the new query string in the filterable container.
15             $target.data('filterable-query-new', $(this).val());
16             if (currentquery == $(this).val()) {
17                 // Don't mess with existing results or queries in
18                 // progress.
19                 return;
20             }
21             $target.data('infinite-cooloff-timer', setTimeout(function() {
22                 // If the user doesn't do any query-changing actions
23                 // in the next 1/4 second (like type or erase
24                 // characters in the search box), hide the stale
25                 // content and ask the server for new results.
26                 var newquery = $target.data('filterable-query-new');
27                 var params = $target.data('infiniteContentParamsFilterable') || {};
28                 params.filters = [['any', 'ilike', '%' + newquery + '%']];
29                 $target.data('infiniteContentParamsFilterable', params);
30                 $target.data('filterable-query', newquery);
31                 $target.trigger('refresh-content');
32             }, 250));
33         } else {
34             // Target does not have infinite-scroll capability. Just
35             // filter the rows in the browser using a RegExp.
36             $target.
37                 addClass('filterable-container').
38                 data('q', new RegExp($(this).val(), 'i')).
39                 trigger('refresh');
40         }
41     }).on('refresh', '.filterable-container', function() {
42         var $container = $(this);
43         var q = $(this).data('q');
44         var filters = $(this).data('filters');
45         $('.filterable', this).hide().filter(function() {
46             var $row = $(this);
47             var pass = true;
48             if (q && !$row.text().match(q))
49                 return false;
50             if (filters) {
51                 $.each(filters, function(filterby, val) {
52                     if (!val) return;
53                     if (!pass) return;
54                     pass = false;
55                     $.each(val.split(" "), function(i, e) {
56                         if ($row.attr(filterby) == e)
57                             pass = true;
58                     });
59                 });
60             }
61             return pass;
62         }).show();
63
64         // Show/hide each section heading depending on whether any
65         // content rows are visible in that section.
66         $('.row[data-section-heading]', this).each(function(){
67             $(this).toggle($('.row.filterable[data-section-name="' +
68                              $(this).attr('data-section-name') +
69                              '"]:visible').length > 0);
70         });
71
72         // Load more content if the last result is showing.
73         $('.infinite-scroller').add(window).trigger('scroll');
74     }).on('change', 'select.filterable-control', function() {
75         var val = $(this).val();
76         var filterby = $(this).attr('data-filterable-attribute');
77         var $target = $($(this).attr('data-filterable-target')).
78             addClass('filterable-container');
79         var filters = $target.data('filters') || {};
80         filters[filterby] = val;
81         $target.
82             data('filters', filters).
83             trigger('refresh');
84     }).on('ajax:complete', function() {
85         $('.filterable-control').trigger('input');
86     });