From 01f050ce684c2107119544ecb38cd9f6321be86e Mon Sep 17 00:00:00 2001 From: Julian Maurice Date: Thu, 9 Feb 2017 16:19:42 +0100 Subject: [PATCH] Bug 15235: Add column filters to checkouts table This adds a switch that allow to enable/disable column filters on checkouts table (disabled by default) Depends on bug 15219 --- C4/Utils/DataTables.pm | 44 ++++++++----- .../plugins/jquery.dataTables.columnFilter.js | 2 +- .../intranet-tmpl/prog/css/datatables.css | 10 +++ .../prog/en/includes/checkouts-table.inc | 19 ++++++ .../prog/en/includes/strings.inc | 1 + .../prog/en/modules/circ/circulation.tt | 1 + .../prog/en/modules/members/moremember.tt | 1 + koha-tmpl/intranet-tmpl/prog/js/checkouts.js | 62 +++++++++++++++++++ svc/checkouts | 6 ++ 9 files changed, 130 insertions(+), 16 deletions(-) diff --git a/C4/Utils/DataTables.pm b/C4/Utils/DataTables.pm index e6fc1ccbcf..62629c32f2 100644 --- a/C4/Utils/DataTables.pm +++ b/C4/Utils/DataTables.pm @@ -20,6 +20,8 @@ package C4::Utils::DataTables; use Modern::Perl; require Exporter; +use Koha::DateUtils; + use vars qw(@ISA @EXPORT); BEGIN { @@ -138,14 +140,10 @@ sub dt_build_having { my $mDataProp = $param->{'mDataProp_'.$i}; my @filter_fields = $param->{$mDataProp.'_filteron'} ? split(' ', $param->{$mDataProp.'_filteron'}) - : (); - if(@filter_fields > 0) { - foreach my $field (@filter_fields) { - push @gFilters, " $field LIKE ? "; - push @gParams, "%$sSearch%"; - } - } else { - push @gFilters, " $mDataProp LIKE ? "; + : ($mDataProp); + + foreach my $field (@filter_fields) { + push @gFilters, " $field LIKE ? "; push @gParams, "%$sSearch%"; } } @@ -163,17 +161,33 @@ sub dt_build_having { my $mDataProp = $param->{'mDataProp_'.$i}; my @filter_fields = $param->{$mDataProp.'_filteron'} ? split(' ', $param->{$mDataProp.'_filteron'}) - : (); - if(@filter_fields > 0) { - my @localfilters; - foreach my $field (@filter_fields) { + : ($mDataProp); + + my @localfilters; + foreach my $field (@filter_fields) { + if ($sSearch =~ /^(.*)\~(.*)$/) { + my ($from, $to) = ($1, $2); + my @datefilters; + if ($from) { + my $date = dt_from_string($from); + push @datefilters, " $field >= ? "; + push @params, $date->ymd; + } + if ($to) { + my $date = dt_from_string($to); + push @datefilters, " $field <= ? "; + push @params, $date->ymd; + } + if (@datefilters) { + push @localfilters, ' (' . join(' AND ', @datefilters) . ') '; + } + } else { push @localfilters, " $field LIKE ? "; push @params, "%$sSearch%"; } + } + if (@localfilters) { push @filters, " ( ". join(" OR ", @localfilters) ." ) "; - } else { - push @filters, " $mDataProp LIKE ? "; - push @params, "%$sSearch%"; } } $i++; diff --git a/koha-tmpl/intranet-tmpl/lib/jquery/plugins/jquery.dataTables.columnFilter.js b/koha-tmpl/intranet-tmpl/lib/jquery/plugins/jquery.dataTables.columnFilter.js index 89343f576f..342ecd0235 100644 --- a/koha-tmpl/intranet-tmpl/lib/jquery/plugins/jquery.dataTables.columnFilter.js +++ b/koha-tmpl/intranet-tmpl/lib/jquery/plugins/jquery.dataTables.columnFilter.js @@ -250,7 +250,6 @@ //th.html(_fnRangeLabelPart(0)); var sFromId = oTable.attr("id") + '_range_from_' + i; var from = $(''); - from.datepicker(); //th.append(from); //th.append(_fnRangeLabelPart(1)); var sToId = oTable.attr("id") + '_range_to_' + i; @@ -275,6 +274,7 @@ th.wrapInner(''); + from.datepicker(); to.datepicker(); var index = i; aiCustomSearch_Indexes.push(i); diff --git a/koha-tmpl/intranet-tmpl/prog/css/datatables.css b/koha-tmpl/intranet-tmpl/prog/css/datatables.css index 71fdb6b2ec..05f28e31d9 100644 --- a/koha-tmpl/intranet-tmpl/prog/css/datatables.css +++ b/koha-tmpl/intranet-tmpl/prog/css/datatables.css @@ -257,6 +257,16 @@ span.filter_column > input[type="text"] { box-sizing: border-box; } +span.filter_column.filter_date_range { + white-space: nowrap; +} + +span.filter_column > input.date_range_filter { + font-size: 80%; + width: 6em; + padding: 0; +} + /* Row grouping */ td.group, table.group td.group { diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/checkouts-table.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/checkouts-table.inc index cbd12467f8..b367e90f8e 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/includes/checkouts-table.inc +++ b/koha-tmpl/intranet-tmpl/prog/en/includes/checkouts-table.inc @@ -9,6 +9,25 @@
+ + + + + + + + + + + + + + + + + + + diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/strings.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/strings.inc index 2f03dbbe5e..8b4651d663 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/includes/strings.inc +++ b/koha-tmpl/intranet-tmpl/prog/en/includes/strings.inc @@ -47,5 +47,6 @@ var MSG_NO_ITEMTYPE = _("No itemtype"); var MSG_CHECKOUTS_BY_ITEMTYPE = _("Number of checkouts by item type"); var GROUP_TODAYS_CHECKOUTS = _("Group today's checkouts"); + var SHOW_COLUMN_FILTERS = _("Show column filters"); //]]> diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt index 4fba41c019..afea929896 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt @@ -981,6 +981,7 @@ No patron matched [% message | html %] [% Asset.js("lib/jquery/plugins/jquery-ui-timepicker-addon.min.js") | $raw %] [% INCLUDE 'timepicker.inc' %] [% Asset.js("lib/jquery/plugins/jquery.dataTables.rowGrouping.js") | $raw %] + [% Asset.js("lib/jquery/plugins/jquery.dataTables.columnFilter.js") | $raw %] [% Asset.js("js/pages/circulation.js") | $raw %] [% INCLUDE 'checkouts.js.inc' %] [% Asset.js("js/holds.js") | $raw %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember.tt index 458af27760..1ece7a491b 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember.tt @@ -799,6 +799,7 @@ [% Asset.js("lib/jquery/plugins/jquery-ui-timepicker-addon.min.js") | $raw %] [% INCLUDE 'timepicker.inc' %] [% Asset.js("lib/jquery/plugins/jquery.dataTables.rowGrouping.js") | $raw %] + [% Asset.js("lib/jquery/plugins/jquery.dataTables.columnFilter.js") | $raw %] [% Asset.js("js/pages/circulation.js") | $raw %] [% INCLUDE 'checkouts.js.inc' %] [% Asset.js("js/holds.js") | $raw %] diff --git a/koha-tmpl/intranet-tmpl/prog/js/checkouts.js b/koha-tmpl/intranet-tmpl/prog/js/checkouts.js index 9c6ef36d5a..8dacbb4d92 100644 --- a/koha-tmpl/intranet-tmpl/prog/js/checkouts.js +++ b/koha-tmpl/intranet-tmpl/prog/js/checkouts.js @@ -22,6 +22,49 @@ function disableGrouping(datatable) { } } +function enableFiltering(datatable) { + var oSettings = datatable.fnSettings(); + var filters_row = $(oSettings.nTable).find('thead tr.filters_row'); + if (!filters_row.hasClass('columnFilter')) { + datatable.columnFilter({ + sPlaceHolder: "head:after", + bUseColVis: true, + sRangeFormat: "From {from}
to {to}", + aoColumns: [ + null, + null, + { type: "date-range" }, + { type: "text" }, + { type: "text" }, + { type: "text" }, + { type: "text" }, + { type: "date-range" }, + { type: "text" }, + { type: "text" }, + null, + null, + null, + null, + null, + null, + null + ] + }); + filters_row.addClass('columnFilter'); + } + filters_row.show(); +} + +function disableFiltering(datatable) { + var oSettings = datatable.fnSettings(); + var filters_row = $(oSettings.nTable).find('thead tr.filters_row'); + filters_row.find('input[type="text"]') + .val('') // Empty filter text boxes + .trigger('keyup') // Filter (display all rows) + .trigger('blur'); // Reset value to the column name + filters_row.hide(); +} + var renderers = { groupOrder: function (data, type, row) { if ( row.issued_today ) { @@ -644,6 +687,25 @@ $(document).ready(function() { .append('') .appendTo('#issues-table_wrapper .top.pager'); + var filteringSwitch = $('') + .attr('id', 'issues-table-filtering-switch') + .css('vertical-align', 'middle') + .change(function() { + if ($(this).is(':checked')) { + enableFiltering(issuesTable); + } else { + disableFiltering(issuesTable); + } + }); + $('
') + .css('float', 'left') + .css('padding', '0.3em 0.5em') + .css('line-height', '1.9em') + .append(filteringSwitch) + .append(' ') + .append('') + .appendTo('#issues-table_wrapper .top.pager'); + if ( $("#issues-table").length ) { $("#issues-table_processing").position({ of: $( "#issues-table" ), diff --git a/svc/checkouts b/svc/checkouts index e97fc4afc3..ee23887783 100755 --- a/svc/checkouts +++ b/svc/checkouts @@ -52,6 +52,7 @@ my $count = $input->param('iDisplayLength'); my %params = dt_get_params($input); my $orderby = dt_build_orderby(\%params); +my ($having, $having_params) = dt_build_having(\%params); my $todaysIssuesDefaultSortOrder = C4::Context->preference('todaysIssuesDefaultSortOrder'); @@ -130,6 +131,11 @@ if ( @borrowernumber == 1 ) { $sql .= $borrowernumber_sql; push( @parameters, @borrowernumber ); +if (@$having) { + $sql .= ' HAVING ' . join (' AND ', @$having); + push @parameters, @$having_params; +} + $sql .= " $orderby"; if ($count && $count > 0) { -- 2.17.1