Bugzilla – Attachment 114998 Details for
Bug 25775
Add DataTables controls to user's checkouts table in OPAC
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 25775: Add DataTables controls to user's checkouts table in OPAC
Bug-25775-Add-DataTables-controls-to-users-checkou.patch (text/plain), 37.77 KB, created by
Katrin Fischer
on 2021-01-10 22:20:59 UTC
(
hide
)
Description:
Bug 25775: Add DataTables controls to user's checkouts table in OPAC
Filename:
MIME Type:
Creator:
Katrin Fischer
Created:
2021-01-10 22:20:59 UTC
Size:
37.77 KB
patch
obsolete
>From e307faad85816563f8c82c053b5c5a5a0acdd626 Mon Sep 17 00:00:00 2001 >From: Owen Leonard <oleonard@myacpl.org> >Date: Wed, 9 Sep 2020 18:23:38 +0000 >Subject: [PATCH] Bug 25775: Add DataTables controls to user's checkouts table > in OPAC > >This patch updates the "your summary" page in the OPAC so that tables on >the logged-in user's page have DataTables controls. The patch also >tweaks the DataTable configuration of some other pages to make them all >more consistent. > >To test, apply the patch and rebuild the OPAC CSS >(https://wiki.koha-community.org/wiki/Working_with_SCSS_in_the_OPAC_and_staff_client). > >- Log in to the OPAC as a user who has checkouts, overdues, and holds. >- On the "your summary" page, confirm that the checkouts table has > controls at the top: A search form and link-style buttons: Clear > filter, Copy, CSV, Print, iCal, Renew selected, and Renew all. >- Confirm that each work correctly. >- At the bottom of the page, the style of the "Renew selected" and > "Renew all" buttons should now be side by side. >- Confirm that both buttons work correctly. >- If necessary, enable the UseCourseReserves system preference. >- Go to the OPAC course reserves page. >- Confirm that there is a working "Search courses" field at the top of > the table. >- View the contents of a course reserve. >- There should be a "Search course reserves" field at the top of the > table. > >Signed-off-by: Lucas Gass <lucas@bywatersolutions.com> >--- > koha-tmpl/opac-tmpl/bootstrap/css/datatables.css | 22 ++ > koha-tmpl/opac-tmpl/bootstrap/css/src/_common.scss | 289 +++++++++++++++ > koha-tmpl/opac-tmpl/bootstrap/css/src/opac.scss | 31 +- > .../bootstrap/en/modules/opac-course-details.tt | 6 +- > .../bootstrap/en/modules/opac-course-reserves.tt | 2 +- > .../opac-tmpl/bootstrap/en/modules/opac-user.tt | 48 ++- > koha-tmpl/opac-tmpl/bootstrap/js/datatables.js | 407 ++------------------- > 7 files changed, 380 insertions(+), 425 deletions(-) > >diff --git a/koha-tmpl/opac-tmpl/bootstrap/css/datatables.css b/koha-tmpl/opac-tmpl/bootstrap/css/datatables.css >index 5546a58eb1..b9361b7acd 100644 >--- a/koha-tmpl/opac-tmpl/bootstrap/css/datatables.css >+++ b/koha-tmpl/opac-tmpl/bootstrap/css/datatables.css >@@ -19,6 +19,10 @@ div.dataTables_filter { > margin : 0; > } > >+.dt-buttons { >+ padding: .3em 0 0 0; >+} >+ > .dataTables_filter input { > background-color: #fff; > border-radius: 0.2rem; >@@ -26,6 +30,7 @@ div.dataTables_filter { > color: #495057; > height: calc(1.5em + 0.5rem + 2px); > line-height: 1.5; >+ margin-left: 3px; > padding: 0.25rem 0.5rem; > transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out, -webkit-box-shadow 0.15s ease-in-out; > } >@@ -34,3 +39,20 @@ div.dataTables_filter { > border-color: #85ca11; > box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(194, 228, 136, 0.6); > } >+ >+div.dt-button-collection { >+ background-color: white; >+ border-radius: 5px; >+ border: 1px solid #ccc; >+ border: 1px solid rgba(0, 0, 0, 0.4); >+ box-shadow: 3px 3px 5px rgba(0, 0, 0, 0.3); >+ column-gap: 8px; >+ left: 0; >+ margin-top: 3px; >+ overflow: hidden; >+ padding: 8px 8px 4px 8px; >+ position: absolute; >+ top: 0; >+ width: 150px; >+ z-index: 2002; >+} >diff --git a/koha-tmpl/opac-tmpl/bootstrap/css/src/_common.scss b/koha-tmpl/opac-tmpl/bootstrap/css/src/_common.scss >index f0a0fd2be3..93a0c66712 100644 >--- a/koha-tmpl/opac-tmpl/bootstrap/css/src/_common.scss >+++ b/koha-tmpl/opac-tmpl/bootstrap/css/src/_common.scss >@@ -34,6 +34,10 @@ $sci-heading-color: #727272; > border-radius: $radius; > } > >+@mixin input-focus { >+ border-color: #85CA11; >+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(194, 228, 136, .6); >+} > > /* Bootstrap imports */ > @import "../../../../../node_modules/bootstrap/scss/functions"; >@@ -295,6 +299,291 @@ textarea, > } > } > >+.dt-button { >+ background-color: transparent; >+ border: 0; >+ color: #0088cc; >+ display: inline-block; >+ line-height: 20px; >+ padding: 4px 12px; >+ text-align: center; >+ text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75); >+ vertical-align: middle; >+ >+ &:hover { >+ color: #005580; >+ >+ &::before { >+ color: #44AE89; >+ } >+ } >+ >+ &::before { >+ color: #4466AE; >+ font-family: FontAwesome; >+ display: inline-block; >+ padding-right: .5em; >+ } >+ >+ &.disabled { >+ color: #333; >+ opacity: .65; >+ pointer-events: none; >+ >+ &:hover { >+ color: #333; >+ filter: alpha(opacity=65); >+ opacity: 0.65; >+ } >+ >+ i { >+ >+ &.fa, >+ &.fa:hover { >+ color: #333; >+ filter: alpha(opacity=65); >+ opacity: 0.65; >+ } >+ } >+ } >+} >+ >+div.dt-button-collection button.dt-button, >+div.dt-button-collection div.dt-button, >+div.dt-button-collection a.dt-button { >+ position: relative; >+ left: 0; >+ right: 0; >+ width: 100%; >+ display: block; >+ float: none; >+ margin-bottom: 4px; >+ margin-right: 0; >+} >+ >+div.dt-button-collection { >+ width: auto >+} >+ >+div.dt-button-collection button.dt-button { >+ border-radius: 2px; >+ text-align: left >+} >+ >+div.dt-button-collection button.dt-button.buttons-collection { >+ border: 0 >+} >+ >+div.dt-button-collection button.dt-button.buttons-columnVisibility { >+ background: #fff none; >+ border: 1px solid #eee; >+ box-shadow: none; >+ font-size: 1em; >+ margin: 0 0 4px; >+ padding: .3em .7em; >+ text-shadow: none >+} >+ >+div.dt-button-collection button.dt-button.buttons-columnVisibility:before { >+ color: #c00; >+ content: "\f00d"; >+ display: inline-block; >+ font-family: FontAwesome; >+ margin-right: .5em; >+ width: 1em >+} >+ >+div.dt-button-collection button.dt-button.buttons-columnVisibility:hover { >+ background: #ffc none; >+ border: 1px solid #999; >+ box-shadow: none >+} >+ >+div.dt-button-collection button.dt-button.buttons-columnVisibility:hover:before { >+ color: #538200; >+ content: "\f00c"; >+ display: inline-block; >+ font-family: FontAwesome; >+ margin-right: .5em; >+ width: 1em >+} >+ >+div.dt-button-collection button.dt-button.buttons-columnVisibility:active:not(.disabled):hover:not(.disabled) { >+ background: transparent none; >+ box-shadow: none >+} >+ >+div.dt-button-collection button.dt-button.buttons-columnVisibility.active { >+ background: #e6f0f2 none; >+ border-color: #999; >+ box-shadow: none >+} >+ >+div.dt-button-collection button.dt-button.buttons-columnVisibility.active:hover { >+ background: #ffc none >+} >+ >+div.dt-button-collection button.dt-button.buttons-columnVisibility.active:hover:before { >+ color: #c00; >+ content: "\f00d"; >+ display: inline-block; >+ font-family: FontAwesome; >+ margin-right: .5em; >+ width: 1em >+} >+ >+div.dt-button-collection button.dt-button.buttons-columnVisibility.active:not(.disabled):hover:not(.disabled) { >+ background: transparent none; >+ box-shadow: none >+} >+ >+div.dt-button-collection button.dt-button.buttons-columnVisibility.active:before { >+ color: #538200; >+ content: "\f00c"; >+ display: inline-block; >+ font-family: FontAwesome; >+ margin-right: .5em; >+ width: 1em; >+} >+ >+div.dt-button-collection button.dt-button.buttons-html5, >+div.dt-button-collection button.dt-button.buttons-print { >+ background: #fff none; >+ border: 1px solid #eee; >+ box-shadow: none; >+ font-size: 1.2em; >+ margin: 0 0 4px; >+ padding: .3em .7em; >+ text-shadow: none >+} >+ >+div.dt-button-collection button.dt-button.buttons-html5:hover, >+div.dt-button-collection button.dt-button.buttons-print:hover { >+ background: #ffc none >+} >+ >+div.dt-button-collection button.dt-button.buttons-html5:not(.disabled):before { >+ color: #222bac; >+ display: inline-block; >+ font-family: FontAwesome; >+ margin-right: .5em; >+ width: 1em >+} >+ >+div.dt-button-collection button.dt-button.buttons-excel:not(.disabled):before { >+ content: "\f1c3" >+} >+ >+div.dt-button-collection button.dt-button.buttons-csv:not(.disabled):before { >+ content: "\f0ce" >+} >+ >+div.dt-button-collection button.dt-button.buttons-copy:not(.disabled):before { >+ content: "\f0c5" >+} >+ >+div.dt-button-collection button.dt-button.buttons-print:not(.disabled):before { >+ color: #222bac; >+ content: "\f02f"; >+ display: inline-block; >+ font-family: FontAwesome; >+ margin-right: .5em; >+ width: 1em >+} >+ >+.dt-button-info { >+ position: fixed; >+ top: 50%; >+ left: 50%; >+ width: 400px; >+ margin-top: -100px; >+ margin-left: -200px; >+ background-color: #FFF; >+ border: 2px solid #005580; >+ box-shadow: 3px 3px 8px rgba(0, 0, 0, 0.3); >+ border-radius: 3px; >+ text-align: center; >+ z-index: 21; >+ >+ h2 { >+ padding: 0.5em; >+ margin: 0; >+ font-weight: normal; >+ border-bottom: 1px solid #ddd; >+ background-color: #f3f3f3; >+ } >+ >+ &>div { >+ padding: 1em; >+ } >+} >+ >+.buttons-print { >+ &::before { >+ content: "\f02f"; >+ } >+} >+ >+.buttons-csv { >+ &::before { >+ content: "\f0ce"; >+ } >+} >+ >+.buttons-copy { >+ &::before { >+ content: "\f0c5"; >+ } >+} >+ >+.buttons-ical { >+ &::before { >+ content: "\f073"; >+ } >+ >+ &:hover { >+ text-decoration: none; >+ } >+} >+ >+.buttons-renew, >+.buttons-renewall { >+ &:hover { >+ i.fa { >+ color: #44AE89; >+ } >+ } >+} >+ >+.buttons-colvis { >+ &::before { >+ content: "\f013"; >+ } >+} >+ >+.table_controls { >+ display: flex; >+ >+ .dataTables_filter { >+ label { >+ input { >+ margin-left: 5px; >+ } >+ } >+ >+ input { >+ @extend .form-control; >+ @extend .form-control-sm; >+ display: inline-block; >+ width: auto; >+ >+ &:focus { >+ @include input-focus; >+ } >+ } >+ } >+} >+ > [class^="icon-"] { > vertical-align: 0; > } >diff --git a/koha-tmpl/opac-tmpl/bootstrap/css/src/opac.scss b/koha-tmpl/opac-tmpl/bootstrap/css/src/opac.scss >index f8159086fd..a33ba13211 100644 >--- a/koha-tmpl/opac-tmpl/bootstrap/css/src/opac.scss >+++ b/koha-tmpl/opac-tmpl/bootstrap/css/src/opac.scss >@@ -10,7 +10,8 @@ > padding: 0; > } > >- .selections-toolbar { >+ .selections-toolbar, >+ #renewall_js { > display: none; > } > >@@ -542,7 +543,6 @@ th { > } > } > >- > .breadcrumb { > background-color: #F0F3F3; > font-size: 85%; >@@ -552,33 +552,6 @@ th { > border-radius: 0px; > } > >-.buttons-print { >- background-color: transparent; >- border: 0; >- color: #0088cc; >- display: inline-block; >- line-height: 20px; >- padding: 4px 12px; >- text-align: center; >- text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75); >- vertical-align: middle; >- >- &:hover { >- color: #005580; >- &::before { >- color: #44AE89; >- } >- } >- >- &::before { >- color: #4466AE; >- content: "\f02f"; >- font-family: FontAwesome; >- display: inline-block; >- padding-right: .5em; >- } >-} >- > #opac-main-search { > background: #f0f3f3; > margin: 7px 0; >diff --git a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-course-details.tt b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-course-details.tt >index ffd3367aa1..d90c1fa2e8 100644 >--- a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-course-details.tt >+++ b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-course-details.tt >@@ -122,9 +122,13 @@ > $(document).ready(function() { > columns_settings = [% TablesSettings.GetColumns( 'opac', 'biblio-detail', 'course-items-table', 'json' ) | $raw %]; > KohaTable("#course-items-table", { >- "dom": '<"top"f>rt<"clear">', >+ "dom": '<"top"<"table_controls"f>>t', > "sorting": [[ 1, "asc" ]], > "autoWidth": false, >+ "language": { >+ "search": "_INPUT_", >+ "searchPlaceholder": _("Search course reserves") >+ } > }, columns_settings ); > }); > </script> >diff --git a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-course-reserves.tt b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-course-reserves.tt >index bc6a9814e8..6856d1e3bd 100644 >--- a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-course-reserves.tt >+++ b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-course-reserves.tt >@@ -84,7 +84,7 @@ > ], > "language": { > "search": "_INPUT_", >- "searchPlaceholder": "Search courses" >+ "searchPlaceholder": _("Search courses") > } > }, columns_settings ); > }); >diff --git a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-user.tt b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-user.tt >index bb2cc72410..0f5e696cf7 100644 >--- a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-user.tt >+++ b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-user.tt >@@ -452,22 +452,22 @@ > </table> > [% IF ( canrenew && !userdebarred && OpacRenewalAllowed && !( logged_in_user.is_expired && logged_in_user.category.effective_BlockExpiredPatronOpacActions ) ) %] > <input type="submit" class="btn btn-primary" value="Renew selected" /> >+ <button type="button" id="renewall_js" class="btn btn-primary">Renew all</button> > [% END %] > </form> > > [% IF ( canrenew && !userdebarred && OpacRenewalAllowed && !( logged_in_user.is_expired && logged_in_user.category.effective_BlockExpiredPatronOpacActions ) ) %] >- <form id="renewall" action="/cgi-bin/koha/opac-renew.pl" method="post"> >- <input type="hidden" name="from" value="opac_user" /> >- <input type="hidden" name="borrowernumber" value="[% borrowernumber | html %]" /> >- [% FOREACH ISSUE IN ISSUES %] >- [% IF ISSUE.status %] >- <input type="hidden" name="item" value="[% ISSUE.itemnumber | html %]" /> >+ <form id="renewall" class="js-hide" action="/cgi-bin/koha/opac-renew.pl" method="post"> >+ <input type="hidden" name="from" value="opac_user" /> >+ <input type="hidden" name="borrowernumber" value="[% borrowernumber | html %]" /> >+ [% FOREACH ISSUE IN ISSUES %] >+ [% IF ISSUE.status %] >+ <input type="hidden" name="item" value="[% ISSUE.itemnumber | html %]" /> >+ [% END %] > [% END %] >- [% END %] >- <input type="submit" class="btn btn-primary" value="Renew all" /> >- </form> >+ <input type="submit" class="btn btn-primary" value="Renew all" /> >+ </form> > [% END %] >- <p><a href="opac-ics.pl">Download as iCal/.ics file</a></p> > [% ELSE %] > <table class="table table-bordered table-striped"> > <tr><td>You have nothing checked out</td></tr> >@@ -834,7 +834,14 @@ > [% INCLUDE 'calendar.inc' %] > [% INCLUDE 'datatables.inc' %] > <script> >- >+ function tableInit( tableId ){ >+ if( tableId == "checkoutst" ){ >+ $(".dt-buttons").append("<a class=\"dt-button buttons-ical\" href=\"opac-ics.pl\">iCal</a> "); >+ [% IF ( OpacRenewalAllowed && canrenew && !userdebarred ) %] >+ $(".dt-buttons").append("<button id=\"renewselected_link\" class=\"dt-button buttons-renew\"><i class=\"fa fa-check\" aria-hidden=\"true\"></i> "+_("Renew selected")+"</button> <button id=\"renewall_link\" class=\"dt-button buttons-renewall\"><span class=\"fa-stack\"><i class=\"fa fa-check fa-stack-1x\" aria-hidden=\"true\"></i><i class=\"fa fa-check fa-stack-1x\" aria-hidden=\"true\"></i></span> "+_("Renew all")+"</button>"); >+ [% END %] >+ } >+ } > $(document).ready(function(){ > $('#opac-user-views').tabs(); > $(".modal-nojs").addClass("modal").addClass("hide").removeClass("modal-nojs"); >@@ -891,13 +898,21 @@ > var dTables = $("#checkoutst,#holdst,#overduest,#opac-user-relative-issues-table"); > dTables.each(function(){ > var thIndex = $(this).find("th.psort").index(); >- $(this).dataTable($.extend(true, {}, dataTablesDefaults, { >+ $(this).on("init.dt", function() { >+ tableInit( $(this).attr("id") ); >+ }) >+ .dataTable($.extend(true, {}, dataTablesDefaults, { > "sorting" : [[ thIndex, 'asc' ]], >+ "dom": '<"top"<"table_entries"><"table_controls"fB>>t', > "columnDefs": [ > { "targets": [ "nosort" ],"sortable": false,"searchable": false }, > { "type": "anti-the", "targets" : [ "anti-the" ] }, > { "type": "title-string", "targets" : [ "title-string" ] } >- ] >+ ], >+ "language": { >+ "search": "_INPUT_", >+ "searchPlaceholder": _("Search") >+ } > })); > }); > >@@ -919,14 +934,11 @@ > e.preventDefault(); > $("#renewselected").submit(); > }); >- $("body").on("click","#renewall_link",function(e){ >+ $("body").on("click","#renewall_link, #renewall_js",function(e){ > e.preventDefault(); > $("#renewall").submit(); > }); >- [% IF ( canrenew && !userdebarred && OpacRenewalAllowed && !( logged_in_user.is_expired && logged_in_user.category.effective_BlockExpiredPatronOpacActions ) ) %] >- $("#checkoutst caption").append("<div id=\"renewcontrols\"><a id=\"renewselected_link\" class=\"btn btn-link\" href=\"#\"><i class=\"fa fa-check\" aria-hidden=\"true\"></i> "+_("Renew selected")+"</a> <a id=\"renewall_link\" class=\"btn btn-link\" href=\"#\"><span class=\"fa-stack\"><i class=\"fa fa-check fa-stack-1x\" aria-hidden=\"true\"></i><i class=\"fa fa-check fa-stack-1x\" aria-hidden=\"true\"></i></span> "+_("Renew all")+"</a></div>"); >- [% END %] >- [% END %] >+ [% END # /IF ( OpacRenewalAllowed && canrenew && !userdebarred ) %] > > [% IF ( Koha.Preference('AllowCheckoutNotes') ) %] > >diff --git a/koha-tmpl/opac-tmpl/bootstrap/js/datatables.js b/koha-tmpl/opac-tmpl/bootstrap/js/datatables.js >index 231ef74219..f8b1633de8 100644 >--- a/koha-tmpl/opac-tmpl/bootstrap/js/datatables.js >+++ b/koha-tmpl/opac-tmpl/bootstrap/js/datatables.js >@@ -1,3 +1,4 @@ >+/* global __ */ > // These default options are for translation but can be used > // for any other datatables settings > // To use it, write: >@@ -32,24 +33,10 @@ var dataTablesDefaults = { > } > }, > "dom": 't', >+ "buttons": [ >+ 'clearFilter', 'copy', 'csv', 'print' >+ ], > "paginate": false, >- "buttons": [{ >- fade: 100, >- className: "dt_button_clear_filter", >- titleAttr: window.MSG_CLEAR_FILTER, >- enabled: false, >- text: '<i class="fa fa-lg fa-remove"></i> <span class="dt-button-text">' + window.MSG_CLEAR_FILTER + '</span>', >- available: function ( dt ) { >- // The "clear filter" button is made available if this test returns true >- if( dt.settings()[0].aanFeatures.f ){ // aanFeatures.f is null if there is no search form >- return true; >- } >- }, >- action: function ( e, dt, node ) { >- dt.search( "" ).draw("page"); >- node.addClass("disabled"); >- } >- }], > initComplete: function( settings) { > var tableId = settings.nTable.id > // When the DataTables search function is triggered, >@@ -65,225 +52,23 @@ var dataTablesDefaults = { > } > }; > >- >-// Return an array of string containing the values of a particular column >-$.fn.dataTableExt.oApi.fnGetColumnData = function ( oSettings, iColumn, bUnique, bFiltered, bIgnoreEmpty ) { >- // check that we have a column id >- if ( typeof iColumn == "undefined" ) return new Array(); >- // by default we only wany unique data >- if ( typeof bUnique == "undefined" ) bUnique = true; >- // by default we do want to only look at filtered data >- if ( typeof bFiltered == "undefined" ) bFiltered = true; >- // by default we do not wany to include empty values >- if ( typeof bIgnoreEmpty == "undefined" ) bIgnoreEmpty = true; >- // list of rows which we're going to loop through >- var aiRows; >- // use only filtered rows >- if (bFiltered == true) aiRows = oSettings.aiDisplay; >- // use all rows >- else aiRows = oSettings.aiDisplayMaster; // all row numbers >- >- // set up data array >- var asResultData = new Array(); >- for (var i=0,c=aiRows.length; i<c; i++) { >- iRow = aiRows[i]; >- var aData = this.fnGetData(iRow); >- var sValue = aData[iColumn]; >- // ignore empty values? >- if (bIgnoreEmpty == true && sValue.length == 0) continue; >- // ignore unique values? >- else if (bUnique == true && jQuery.inArray(sValue, asResultData) > -1) continue; >- // else push the value onto the result data array >- else asResultData.push(sValue); >- } >- return asResultData; >-} >- >-// List of unbind keys (Ctrl, Alt, Direction keys, etc.) >-// These keys must not launch filtering >-var blacklist_keys = new Array(0, 16, 17, 18, 37, 38, 39, 40); >- >-// Set a filtering delay for global search field >-jQuery.fn.dataTableExt.oApi.fnSetFilteringDelay = function ( oSettings, iDelay ) { >- /* >- * Inputs: object:oSettings - dataTables settings object - automatically given >- * integer:iDelay - delay in milliseconds >- * Usage: $('#example').dataTable().fnSetFilteringDelay(250); >- * Author: Zygimantas Berziunas (www.zygimantas.com) and Allan Jardine >- * License: GPL v2 or BSD 3 point style >- * Contact: zygimantas.berziunas /AT\ hotmail.com >- */ >- var >- _that = this, >- iDelay = (typeof iDelay == 'undefined') ? 250 : iDelay; >- >- this.each( function ( i ) { >- $.fn.dataTableExt.iApiIndex = i; >- var >- $this = this, >- oTimerId = null, >- sPreviousSearch = null, >- anControl = $( 'input', _that.fnSettings().aanFeatures.f ); >- >- anControl.unbind( 'keyup.DT' ).bind( 'keyup.DT', function(event) { >- var $$this = $this; >- if (blacklist_keys.indexOf(event.keyCode) != -1) { >- return this; >- }else if ( event.keyCode == '13' ) { >- $.fn.dataTableExt.iApiIndex = i; >- _that.fnFilter( $(this).val() ); >- } else { >- if (sPreviousSearch === null || sPreviousSearch != anControl.val()) { >- window.clearTimeout(oTimerId); >- sPreviousSearch = anControl.val(); >- oTimerId = window.setTimeout(function() { >- $.fn.dataTableExt.iApiIndex = i; >- _that.fnFilter( anControl.val() ); >- }, iDelay); >- } >- } >- }); >- >- return this; >- } ); >- return this; >-} >- >-// Add a filtering delay on general search and on all input (with a class 'filter') >-jQuery.fn.dataTableExt.oApi.fnAddFilters = function ( oSettings, sClass, iDelay ) { >- var table = this; >- this.fnSetFilteringDelay(iDelay); >- var filterTimerId = null; >- $(table).find("input."+sClass).keyup(function(event) { >- if (blacklist_keys.indexOf(event.keyCode) != -1) { >- return this; >- }else if ( event.keyCode == '13' ) { >- table.fnFilter( $(this).val(), $(this).attr('data-column_num') ); >- } else { >- window.clearTimeout(filterTimerId); >- var input = this; >- filterTimerId = window.setTimeout(function() { >- table.fnFilter($(input).val(), $(input).attr('data-column_num')); >- }, iDelay); >- } >- }); >- $(table).find("select."+sClass).on('change', function() { >- table.fnFilter($(this).val(), $(this).attr('data-column_num')); >- }); >-} >- >-// Sorting on html contains >-// <a href="foo.pl">bar</a> sort on 'bar' >-function dt_overwrite_html_sorting_localeCompare() { >- jQuery.fn.dataTableExt.oSort['html-asc'] = function(a,b) { >- a = a.replace(/<.*?>/g, "").replace(/\s+/g, " "); >- b = b.replace(/<.*?>/g, "").replace(/\s+/g, " "); >- if (typeof(a.localeCompare == "function")) { >- return a.localeCompare(b); >- } else { >- return (a > b) ? 1 : ((a < b) ? -1 : 0); >+$.fn.dataTable.ext.buttons.clearFilter = { >+ fade: 100, >+ className: "dt_button_clear_filter", >+ titleAttr: window.MSG_CLEAR_FILTER, >+ enabled: false, >+ text: '<i class="fa fa-lg fa-remove"></i> <span class="dt-button-text">' + window.MSG_CLEAR_FILTER + '</span>', >+ available: function ( dt ) { >+ // The "clear filter" button is made available if this test returns true >+ if( dt.settings()[0].aanFeatures.f ){ // aanFeatures.f is null if there is no search form >+ return true; > } >- }; >- >- jQuery.fn.dataTableExt.oSort['html-desc'] = function(a,b) { >- a = a.replace(/<.*?>/g, "").replace(/\s+/g, " "); >- b = b.replace(/<.*?>/g, "").replace(/\s+/g, " "); >- if(typeof(b.localeCompare == "function")) { >- return b.localeCompare(a); >- } else { >- return (b > a) ? 1 : ((b < a) ? -1 : 0); >- } >- }; >- >- jQuery.fn.dataTableExt.oSort['num-html-asc'] = function(a,b) { >- var x = a.replace( /<.*?>/g, "" ); >- var y = b.replace( /<.*?>/g, "" ); >- x = parseFloat( x ); >- y = parseFloat( y ); >- return ((x < y) ? -1 : ((x > y) ? 1 : 0)); >- }; >- >- jQuery.fn.dataTableExt.oSort['num-html-desc'] = function(a,b) { >- var x = a.replace( /<.*?>/g, "" ); >- var y = b.replace( /<.*?>/g, "" ); >- x = parseFloat( x ); >- y = parseFloat( y ); >- return ((x < y) ? 1 : ((x > y) ? -1 : 0)); >- }; >-} >- >-$.fn.dataTableExt.oSort['num-html-asc'] = function(a,b) { >- var x = a.replace( /<.*?>/g, "" ); >- var y = b.replace( /<.*?>/g, "" ); >- x = parseFloat( x ); >- y = parseFloat( y ); >- return ((x < y) ? -1 : ((x > y) ? 1 : 0)); >-}; >- >-$.fn.dataTableExt.oSort['num-html-desc'] = function(a,b) { >- var x = a.replace( /<.*?>/g, "" ); >- var y = b.replace( /<.*?>/g, "" ); >- x = parseFloat( x ); >- y = parseFloat( y ); >- return ((x < y) ? 1 : ((x > y) ? -1 : 0)); >-}; >- >-(function() { >- >-/* >- * Natural Sort algorithm for Javascript - Version 0.7 - Released under MIT license >- * Author: Jim Palmer (based on chunking idea from Dave Koelle) >- * Contributors: Mike Grier (mgrier.com), Clint Priest, Kyle Adams, guillermo >- * See: http://js-naturalsort.googlecode.com/svn/trunk/naturalSort.js >- */ >-function naturalSort (a, b) { >- var re = /(^-?[0-9]+(\.?[0-9]*)[df]?e?[0-9]?$|^0x[0-9a-f]+$|[0-9]+)/gi, >- sre = /(^[ ]*|[ ]*$)/g, >- dre = /(^([\w ]+,?[\w ]+)?[\w ]+,?[\w ]+\d+:\d+(:\d+)?[\w ]?|^\d{1,4}[\/\-]\d{1,4}[\/\-]\d{1,4}|^\w+, \w+ \d+, \d{4})/, >- hre = /^0x[0-9a-f]+$/i, >- ore = /^0/, >- // convert all to strings and trim() >- x = a.toString().replace(sre, '') || '', >- y = b.toString().replace(sre, '') || '', >- // chunk/tokenize >- xN = x.replace(re, '\0$1\0').replace(/\0$/,'').replace(/^\0/,'').split('\0'), >- yN = y.replace(re, '\0$1\0').replace(/\0$/,'').replace(/^\0/,'').split('\0'), >- // numeric, hex or date detection >- xD = parseInt(x.match(hre), 10) || (xN.length != 1 && x.match(dre) && Date.parse(x)), >- yD = parseInt(y.match(hre), 10) || xD && y.match(dre) && Date.parse(y) || null; >- // first try and sort Hex codes or Dates >- if (yD) >- if ( xD < yD ) return -1; >- else if ( xD > yD ) return 1; >- // natural sorting through split numeric strings and default strings >- for(var cLoc=0, numS=Math.max(xN.length, yN.length); cLoc < numS; cLoc++) { >- // find floats not starting with '0', string or 0 if not defined (Clint Priest) >- var oFxNcL = !(xN[cLoc] || '').match(ore) && parseFloat(xN[cLoc]) || xN[cLoc] || 0; >- var oFyNcL = !(yN[cLoc] || '').match(ore) && parseFloat(yN[cLoc]) || yN[cLoc] || 0; >- // handle numeric vs string comparison - number < string - (Kyle Adams) >- if (isNaN(oFxNcL) !== isNaN(oFyNcL)) return (isNaN(oFxNcL)) ? 1 : -1; >- // rely on string comparison if different types - i.e. '02' < 2 != '02' < '2' >- else if (typeof oFxNcL !== typeof oFyNcL) { >- oFxNcL += ''; >- oFyNcL += ''; >- } >- if (oFxNcL < oFyNcL) return -1; >- if (oFxNcL > oFyNcL) return 1; >- } >- return 0; >-} >- >-jQuery.extend( jQuery.fn.dataTableExt.oSort, { >- "natural-asc": function ( a, b ) { >- return naturalSort(a,b); > }, >- >- "natural-desc": function ( a, b ) { >- return naturalSort(a,b) * -1; >+ action: function ( e, dt, node ) { >+ dt.search( "" ).draw("page"); >+ node.addClass("disabled"); > } >-} ); >- >-}()); >+}; > > /* Plugin to allow sorting on data stored in a span's title attribute > * >@@ -359,7 +144,7 @@ jQuery.extend( jQuery.fn.dataTableExt.oSort, { > if (config_exclude_articles_from_sort){ > var articles = config_exclude_articles_from_sort.split(" "); > var rpattern = ""; >- for(i=0;i<articles.length;i++){ >+ for( var i=0; i<articles.length; i++){ > rpattern += "^" + articles[i] + " "; > if(i < articles.length - 1){ rpattern += "|"; } > } >@@ -385,128 +170,6 @@ jQuery.extend( jQuery.fn.dataTableExt.oSort, { > > }()); > >-// Remove string between NSB NSB characters >-$.fn.dataTableExt.oSort['nsb-nse-asc'] = function(a,b) { >- var pattern = new RegExp("\x88.*\x89"); >- a = a.replace(pattern, ""); >- b = b.replace(pattern, ""); >- return (a > b) ? 1 : ((a < b) ? -1 : 0); >-} >-$.fn.dataTableExt.oSort['nsb-nse-desc'] = function(a,b) { >- var pattern = new RegExp("\x88.*\x89"); >- a = a.replace(pattern, ""); >- b = b.replace(pattern, ""); >- return (b > a) ? 1 : ((b < a) ? -1 : 0); >-} >- >-/* Define two custom functions (asc and desc) for basket callnumber sorting */ >-jQuery.fn.dataTableExt.oSort['callnumbers-asc'] = function(x,y) { >- var x_array = x.split("<div>"); >- var y_array = y.split("<div>"); >- >- /* Pop the first elements, they are empty strings */ >- x_array.shift(); >- y_array.shift(); >- >- x_array = jQuery.map( x_array, function( a ) { >- return parse_callnumber( a ); >- }); >- y_array = jQuery.map( y_array, function( a ) { >- return parse_callnumber( a ); >- }); >- >- x_array.sort(); >- y_array.sort(); >- >- x = x_array.shift(); >- y = y_array.shift(); >- >- if ( !x ) { x = ""; } >- if ( !y ) { y = ""; } >- >- return ((x < y) ? -1 : ((x > y) ? 1 : 0)); >-}; >- >-jQuery.fn.dataTableExt.oSort['callnumbers-desc'] = function(x,y) { >- var x_array = x.split("<div>"); >- var y_array = y.split("<div>"); >- >- /* Pop the first elements, they are empty strings */ >- x_array.shift(); >- y_array.shift(); >- >- x_array = jQuery.map( x_array, function( a ) { >- return parse_callnumber( a ); >- }); >- y_array = jQuery.map( y_array, function( a ) { >- return parse_callnumber( a ); >- }); >- >- x_array.sort(); >- y_array.sort(); >- >- x = x_array.pop(); >- y = y_array.pop(); >- >- if ( !x ) { x = ""; } >- if ( !y ) { y = ""; } >- >- return ((x < y) ? 1 : ((x > y) ? -1 : 0)); >-}; >- >-function parse_callnumber ( html ) { >- var array = html.split('<span class="callnumber">'); >- if ( array[1] ) { >- array = array[1].split('</span>'); >- return array[0]; >- } else { >- return ""; >- } >-} >- >-// see http://www.datatables.net/examples/advanced_init/footer_callback.html >-function footer_column_sum( api, column_numbers ) { >- // Remove the formatting to get integer data for summation >- var intVal = function ( i ) { >- if ( typeof i === 'number' ) { >- if ( isNaN(i) ) return 0; >- return i; >- } else if ( typeof i === 'string' ) { >- var value = i.replace(/[a-zA-Z ,.]/g, '')*1; >- if ( isNaN(value) ) return 0; >- return value; >- } >- return 0; >- }; >- >- >- for ( var indice = 0 ; indice < column_numbers.length ; indice++ ) { >- var column_number = column_numbers[indice]; >- >- var total = 0; >- var cells = api.column( column_number, { page: 'current' } ).nodes().to$().find("span.total_amount"); >- $(cells).each(function(){ >- total += intVal( $(this).html() ); >- }); >- total /= 100; // Hard-coded decimal precision >- >- // Update footer >- $( api.column( column_number ).footer() ).html(total.format_price()); >- }; >-} >- >-function filterDataTable( table, column, term ){ >- if( column ){ >- table.column( column ).search( term ).draw("page"); >- } else { >- table.search( term ).draw("page"); >- } >-} >- >-jQuery.fn.dataTable.ext.errMode = function(settings, note, message) { >- console.warn(message); >-}; >- > (function($) { > > $.fn.api = function(options, columns_settings, add_filters) { >@@ -632,12 +295,12 @@ jQuery.fn.dataTable.ext.errMode = function(settings, note, message) { > > return newnode.text().replace( /\n/g, ' ' ).trim(); > } >- } >+ }; > > var export_buttons = [ > { > extend: 'excelHtml5', >- text: _("Excel"), >+ text: __("Excel"), > exportOptions: { > columns: exportColumns, > format: export_format >@@ -645,7 +308,7 @@ jQuery.fn.dataTable.ext.errMode = function(settings, note, message) { > }, > { > extend: 'csvHtml5', >- text: _("CSV"), >+ text: __("CSV"), > exportOptions: { > columns: exportColumns, > format: export_format >@@ -653,7 +316,7 @@ jQuery.fn.dataTable.ext.errMode = function(settings, note, message) { > }, > { > extend: 'copyHtml5', >- text: _("Copy"), >+ text: __("Copy"), > exportOptions: { > columns: exportColumns, > format: export_format >@@ -661,7 +324,7 @@ jQuery.fn.dataTable.ext.errMode = function(settings, note, message) { > }, > { > extend: 'print', >- text: _("Print"), >+ text: __("Print"), > exportOptions: { > columns: exportColumns, > format: export_format >@@ -673,10 +336,10 @@ jQuery.fn.dataTable.ext.errMode = function(settings, note, message) { > { > fade: 100, > className: "dt_button_clear_filter", >- titleAttr: _("Clear filter"), >+ titleAttr: __("Clear filter"), > enabled: false, >- text: '<i class="fa fa-lg fa-remove"></i> <span class="dt-button-text">' + _("Clear filter") + '</span>', >- action: function ( e, dt, node, config ) { >+ text: '<i class="fa fa-lg fa-remove"></i> <span class="dt-button-text">' + __("Clear filter") + '</span>', >+ action: function ( e, dt, node ) { > dt.search( "" ).draw("page"); > node.addClass("disabled"); > } >@@ -690,8 +353,8 @@ jQuery.fn.dataTable.ext.errMode = function(settings, note, message) { > fade: 100, > columns: included_ids, > className: "columns_controls", >- titleAttr: _("Columns settings"), >- text: '<i class="fa fa-lg fa-gear"></i> <span class="dt-button-text">' + _("Columns") + '</span>', >+ titleAttr: __("Columns settings"), >+ text: '<i class="fa fa-lg fa-gear"></i> <span class="dt-button-text">' + __("Columns") + '</span>', > exportOptions: { > columns: exportColumns > } >@@ -705,20 +368,12 @@ jQuery.fn.dataTable.ext.errMode = function(settings, note, message) { > autoClose: true, > fade: 100, > className: "export_controls", >- titleAttr: _("Export or print"), >- text: '<i class="fa fa-lg fa-download"></i> <span class="dt-button-text">' + _("Export") + '</span>', >+ titleAttr: __("Export or print"), >+ text: '<i class="fa fa-lg fa-download"></i> <span class="dt-button-text">' + __("Export") + '</span>', > buttons: export_buttons > } > ); > >- if ( add_filters ) { >- // Duplicate the table header row for columnFilter >- thead_row = this.find('thead tr'); >- clone = thead_row.clone().addClass('filters_row'); >- clone.find("th.NoSort").html(''); >- thead_row.before(clone); >- } >- > $(".dt_button_clear_filter, .columns_controls, .export_controls").tooltip(); > > return $(this).dataTable(settings); >-- >2.11.0
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
|
Splinter Review
Attachments on
bug 25775
:
105928
|
113331
|
113332
|
114153
|
114998
|
114999
|
115094