Bug 22888: Use DataTables for Koha news table filtering
authorOwen Leonard <oleonard@myacpl.org>
Thu, 9 May 2019 16:55:00 +0000 (16:55 +0000)
committerMartin Renvoize <martin.renvoize@ptfs-europe.com>
Mon, 24 Jun 2019 13:58:02 +0000 (14:58 +0100)
This patch modifies the Koha news page so that filtering the table of
news is done using DataTables' built-in search functionality. This
allows for the table to be filtered without requiring a reload of the
page.

The patch also moves the table filter into a sidebar form and adds a
keyword field. A minor change has been made to the global CSS to improve
the display of the form in the sidebar.

To test, apply the patch and rebuild the staff client CSS.

 - Go to Tools -> News.
 - Test the various table filter options: keyword, display location, and
   library. Confirm that all work as expected.
   - Changes to the keyword search text should be reflected in the
     search field at the top of the table, and vice versa.
 - Changes to the sidebar filter should trigger the correct state of the
   "Clear filter" button at the top of the news table (enabled or
   disabled).

Signed-off-by: Maryse Simard <maryse.simard@inlibro.com>
Signed-off-by: Katrin Fischer <katrin.fischer.83@web.de>
Signed-off-by: Martin Renvoize <martin.renvoize@ptfs-europe.com>

koha-tmpl/intranet-tmpl/prog/css/src/staff-global.scss
koha-tmpl/intranet-tmpl/prog/en/modules/tools/koha-news.tt
tools/koha-news.pl

index 333f9fd..1f9ccf6 100644 (file)
@@ -155,7 +155,7 @@ aside {
 
     fieldset {
         &.brief {
-            margin: 0;
+            margin: 0 0 1em 0;
             padding: .4em .7em;
 
             fieldset {
index 3d590e2..fe88908 100644 (file)
@@ -100,24 +100,6 @@ Edit news item[% ELSE %]Add news item[% END %][% ELSE %]News[% END %]</div>
                 <fieldset class="action"><input class="button" type="submit" value="Submit" /> <a class="cancel" href="/cgi-bin/koha/tools/koha-news.pl">Cancel</a></fieldset>
         </form>
     [% ELSE %]
-        <div style="margin-bottom:5px;">
-        <form name="add_form" method="post" action="/cgi-bin/koha/tools/koha-news.pl" >
-            <label for="lang">Display location:</label>
-            <select name="lang" id="lang">
-                [% PROCESS lang_locations language => lang %]
-            </select>
-            <label for="branch">Library: </label>
-            <select id="branch" name="branch">
-                [% IF ( branchcode == "" ) %]
-                <option value="" selected="selected">All libraries</option>
-                [% ELSE %]
-                <option value=""         >All libraries</option>
-                [% END %]
-                [% PROCESS options_for_libraries libraries => Branches.all( selected => branchcode, unfiltered => 1, ) %]
-            </select>
-            <input type="submit" class="button" value="Filter" />
-        </form>
-        </div>
         [% IF ( opac_news_count ) %]
         <form id="del_form" method="post" action="/cgi-bin/koha/tools/koha-news.pl">
                 <table id="newst">
@@ -186,6 +168,35 @@ Edit news item[% ELSE %]Add news item[% END %][% ELSE %]News[% END %]</div>
 
                 <div class="col-sm-2 col-sm-pull-10">
                     <aside>
+
+                        <div id="news-filter">
+                            <form action="/cgi-bin/koha/tools/koha-news.pl" method="get">
+                                <h4>Filter</h4>
+                                <fieldset class="brief">
+                                    <ol>
+                                        <li>
+                                            <label for="news_keyword">Keyword:</label>
+                                            <input type="text" name="news_keyword" id="news_keyword" />
+                                        </li>
+                                        <li>
+                                            <label for="news_display_location">Display location:</label>
+                                            <select name="news_display_location" id="news_display_location">
+                                                [% PROCESS lang_locations %]
+                                            </select>
+                                        </li>
+                                        <li>
+                                            <label for="news_library">Library: </label>
+                                            <select id="news_library" name="news_library">
+                                                <option value=""></option>
+                                                <option value="">All libraries</option>
+                                                [% PROCESS options_for_libraries libraries => Branches.all( selected => branchcode, unfiltered => 1, ) %]
+                                            </select>
+                                        </li>
+                                    </ol>
+                                </fieldset>
+                            </form>
+                        </div>
+
                         [% INCLUDE 'tools-menu.inc' %]
                     </aside>
                 </div> <!-- /.col-sm-2.col-sm-pull-10 -->
@@ -198,8 +209,37 @@ Edit news item[% ELSE %]Add news item[% END %][% ELSE %]News[% END %]</div>
     [% IF ( opac_news_count ) %]
         [% INCLUDE 'datatables.inc' %]
         <script>
+            function Checkbox(){
+                var form = document.getElementById('del_form');
+                var inputs = form.getElementsByTagName('input');
+                var checked = false;
+                for (var i=0; i<inputs.length; i++) {
+                    if (inputs[i].type == 'checkbox' && inputs[i].name == 'ids') {
+                        checked = inputs[i].checked;
+                        if (checked) return true;
+                    }
+                }
+            }
+
+            function filterDataTable( table, column, term ){
+                if( column ){
+                    table.column( column ).search( term ).draw();
+                } else {
+                    table.search( term ).draw();
+                }
+                clearFilter( term );
+            }
+
+            function clearFilter( term ){
+                if( term == "" ){
+                    $(".dt_button_clear_filter").addClass("disabled");
+                } else {
+                    $(".dt_button_clear_filter").removeClass("disabled");
+                }
+            }
+
             $(document).ready(function() {
-                $("#newst").dataTable($.extend(true, {}, dataTablesDefaults, {
+                var newst = $("#newst").DataTable($.extend(true, {}, dataTablesDefaults, {
                     "aoColumnDefs": [
                         { "aTargets": [ 0,-1,-2 ], "bSortable": false },
                         { "aTargets": [ 0, -1 ], "bSearchable": false },
@@ -207,22 +247,11 @@ Edit news item[% ELSE %]Add news item[% END %][% ELSE %]News[% END %]</div>
                     ],
                     "sPaginationType": "full_numbers"
                 }));
+
                 $(".delete_news").on("click", function(){
                     return confirmDelete( _("Are you sure you want to delete this news item? This cannot be undone.") );
                 });
 
-                function Checkbox(){
-                    var form = document.getElementById('del_form');
-                    var inputs = form.getElementsByTagName('input');
-                    var checked = false;
-                    for (var i=0; i<inputs.length; i++) {
-                        if (inputs[i].type == 'checkbox' && inputs[i].name == 'ids') {
-                            checked = inputs[i].checked;
-                            if (checked) return true;
-                        }
-                    }
-                }
-
                 $("#del_form").on("submit",function(){
                     if ( Checkbox() ) {
                         return confirmDelete( _("Are you sure you want to delete the selected news?") );
@@ -231,6 +260,34 @@ Edit news item[% ELSE %]Add news item[% END %][% ELSE %]News[% END %]</div>
                         return false;
                     }
                 });
+
+                newst.on( 'search.dt', function () {
+                    var term = newst.search();
+                    $("#news_keyword").val( term );
+                });
+
+                $("#news_keyword").on("keyup", function(){
+                    var term = $(this).val();
+                    filterDataTable( newst, null, term );
+                });
+
+                $("#news_display_location").on("change", function(){
+                    var term = $(this).val();
+                    filterDataTable( newst, 1, term );
+                });
+
+                $("#news_library").on("change", function(){
+                    // Table must be filtered by the <option>'s text, not its value
+                    var opt = $(this).find("option:selected").text();
+                    filterDataTable( newst, 2, opt );
+                });
+
+                $(".dt_button_clear_filter").on("click", function(){
+                    newst.search('').columns().search('').draw();
+                    $("#news-filter select").each(function(){
+                        $(this).val("");
+                    });
+                });
             });
         </script>
     [% END %]
@@ -262,7 +319,7 @@ Edit news item[% ELSE %]Add news item[% END %][% ELSE %]News[% END %]</div>
 
 [% BLOCK lang_locations %]
     [% IF ( language == "" ) %]
-        <option value="" selected="selected">All</option>
+        <option value="" selected="selected"></option>
     [% ELSE %]
         <option value="">All</option>
     [% END %]
index 7c20b5d..b90a8c4 100755 (executable)
@@ -144,7 +144,7 @@ elsif ( $op eq 'del' ) {
 
 else {
 
-    my ( $opac_news_count, $opac_news ) = &get_opac_news( undef, $lang, $branchcode );
+    my ( $opac_news_count, $opac_news ) = &get_opac_news( undef, undef, undef );
     
     foreach my $new ( @$opac_news ) {
         next unless $new->{'expirationdate'};