Bugzilla – Attachment 169029 Details for
Bug 14322
Add option to create a shareable link for item searches
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 14322: Add shareable link button to item search
Bug-14322-Add-shareable-link-button-to-item-search.patch (text/plain), 16.63 KB, created by
Brendan Lawlor
on 2024-07-15 20:54:07 UTC
(
hide
)
Description:
Bug 14322: Add shareable link button to item search
Filename:
MIME Type:
Creator:
Brendan Lawlor
Created:
2024-07-15 20:54:07 UTC
Size:
16.63 KB
patch
obsolete
>From 76c42ded602bfc28ba51f50237e43a5bab6b4dc2 Mon Sep 17 00:00:00 2001 >From: Brendan Lawlor <blawlor@clamsnet.org> >Date: Fri, 12 Jul 2024 16:03:57 +0000 >Subject: [PATCH] Bug 14322: Add shareable link button to item search > >This patch adds a 'Copy shareable link' button to the item search results page. >When pasted into the browser the item search form will be prefilled. >The item search form submission still gets it's parameters from the form. > >Test plan: >1. Apply patch >2. Try some item searches (try searches using the '+ New field' button too) >3. On the results page click the 'Copy shareable link' button >4. Paste the link into the browser and hit enter >5. Notice the item search form is filled out exactly as you did earlier >6. Click 'Search' and confirm the results are as you would expect >7. Click 'Edit search', modify the search and search again >8. Test the 'Copy shareable link' button again >9. Test pasting the example link below >10. With default ktd data the search will return one result for: > Intermediate Perl / Schwartz, Randal L. > >http://localhost:8081/cgi-bin/koha/catalogue/itemsearch.pl?homebranch_op=%3D&homebranch=CPL&holdingbranch_op=%3D&holdingbranch=CPL&location_op=%3D&location=GEN&itype_op=%3D&itype=BK&ccode_op=%3D&ccode=REF¬forloan_op=!%3D¬forloan=1&itemlost_op=!%3D&itemlost=1&withdrawn_op=!%3D&withdrawn=1&damaged_op=!%3D&damaged=1&onloan=&f=publishercode&op=like&q=O'Reilly%2C&c=and&f=publicationyear&op=like&q=2006&c=and&f=title&op=not%20like&q=Javascript%20%3A&c=and&f=author&op=not%20like&q=Carlson%2C%20Lucas.&itemcallnumber_from=&itemcallnumber_to=&issues_op=%3E&issues=&datelastborrowed_op=%3E&datelastborrowed=&format=shareable >--- > catalogue/itemsearch.pl | 5 +- > .../prog/en/modules/catalogue/itemsearch.tt | 195 +++++++++++++----- > 2 files changed, 148 insertions(+), 52 deletions(-) > >diff --git a/catalogue/itemsearch.pl b/catalogue/itemsearch.pl >index bd25081c0d..a8134712f4 100755 >--- a/catalogue/itemsearch.pl >+++ b/catalogue/itemsearch.pl >@@ -90,6 +90,8 @@ if (defined $format and $format eq 'json') { > } elsif (defined $format and $format eq 'barcodes') { > # Retrieve all results > $cgi->param('rows', 0); >+} elsif (defined $format and $format eq 'shareable') { >+ # get the item search parameters from the url and fill form > } elsif (defined $format) { > die "Unsupported format $format"; > } >@@ -119,7 +121,7 @@ if ( Koha::MarcSubfieldStructures->search( { frameworkcode => '', kohafield => ' > $template->param( has_new_status => 1 ); > } > >-if ( defined $format ) { >+if ( defined $format and $format ne 'shareable') { > # Parameters given, it's a search > > my $filter = { >@@ -351,6 +353,7 @@ $template->param( > damageds => \@damageds, > items_search_fields => \@items_search_fields, > authorised_values_json => to_json($authorised_values), >+ query => $cgi, > ); > > output_html_with_http_headers $cgi, $cookie, $template->output; >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/itemsearch.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/itemsearch.tt >index 59b4c9225a..1fea9090ed 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/itemsearch.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/itemsearch.tt >@@ -37,30 +37,59 @@ > <div class="form-field form-field-select"> > <label class="form-field-label" for="[% name | html %]">[% INCLUDE form_label label=name %]</label> > <select id="[% name | html %]_op" name="[% name | html %]_op"> >- <option value="=">is</option> >- <option value="!=" >is not</option> >+ [% IF query.param(name _ '_op') == '=' || !query.param(name _ '_op') %] >+ <option value="=" selected="selected">is</option> >+ <option value="!=" >is not</option> >+ [% ELSE %] >+ <option value="=">is</option> >+ <option value="!=" selected="selected">is not</option> >+ [% END %] > </select> > <select id="[% name | html %]" name="[% name | html %]" multiple="multiple" size="[% options.size < 4 ? options.size + 1 : 4 | html %]"> >- <option value="" selected="selected"> >- [% IF (empty_option) %][% INCLUDE form_label label=empty_option %][% ELSE %]<span>All</span>[% END %] >- </option> >+ [% IF query.param(name).size == 0 %] >+ <option value="" selected="selected"> >+ [% IF (empty_option) %][% INCLUDE form_label label=empty_option %][% ELSE %]<span>All</span>[% END %] >+ </option> >+ [% END %] > [% FOREACH option IN options %] >+ [% IF query.param(name).grep(option.value).size %] >+ <option value="[% option.value | html %]" selected="selected">[% option.label | html %]</option> >+ [% ELSE %] > <option value="[% option.value | html %]">[% option.label | html %]</option> >+ [% END %] > [% END %] > </select> > </div> > [% END %] > > [% BLOCK form_field_select_option %] >- <option value="[% value | html %]">[% INCLUDE form_label label=value %]</option> >+ [% IF query.param('f').$i == value || query.param('f') == value %] >+ <option value="[% value | html %]" selected="selected">[% INCLUDE form_label label=value %]</option> >+ [% ELSE %] >+ <option value="[% value | html %]">[% INCLUDE form_label label=value %]</option> >+ [% END %] > [% END %] > > [% BLOCK form_field_select_text %] >+ [% SET i = loop.count - 1 %] > <div class="form-field form-field-select-text"> >- <select name="c" class="form-field-conjunction" disabled="disabled"> >- <option value="and">AND</option> >- <option value="or">OR</option> >- </select> >+ [% IF loop.first || !query.param('f') %] >+ <select name="c" class="form-field-conjunction" disabled="disabled"> >+ <option value="and">AND</option> >+ <option value="or">OR</option> >+ </select> >+ [% ELSE %] >+ [% SET j = i - 1 %] >+ <select name="c" class="form-field-conjunction"> >+ [% IF query.param('c').$j == 'and' %] >+ <option value="and" selected="selected">AND</option> >+ <option value="or">OR</option> >+ [% ELSE %] >+ <option value="and">AND</option> >+ <option value="or" selected="selected">OR</option> >+ [% END %] >+ </select> >+ [% END %] > <select name="f" class="form-field-column"> > [% INCLUDE form_field_select_option value='barcode' %] > [% INCLUDE form_field_select_option value='itemcallnumber' %] >@@ -84,22 +113,16 @@ > </optgroup> > [% END %] > </select> >- [% IF params.exists('op') %] >- <select name="op" class="form-field-not"> >- <option value="like">is</option> >- [% IF params.op == 'not like' %] >- <option value="not like" selected="selected">is not</option> >- [% ELSE %] >- <option value="not like">is not</option> >- [% END %] >- </select> >- [% ELSE %] >- <select name="op" class="form-field-not"> >- <option value="like">is</option> >- <option value="not like">is not</option> >- </select> >- [% END %] >- <input type="text" name="q" class="form-field-value" value="" /> >+ <select name="op" class="form-field-not"> >+ [% IF query.param('op').$i == 'not like' || query.param('op') == 'not like' %] >+ <option value="like">is</option> >+ <option value="not like" selected="selected">is not</option> >+ [% ELSE %] >+ <option value="like">is</option> >+ <option value="not like">is not</option> >+ [% END %] >+ </select> >+ <input type="text" name="q" class="form-field-value" value="[% query.param('q').$i ? query.param('q').$i : query.param('q') | html %]"/> > </div> > [% END %] > >@@ -210,16 +233,34 @@ > [% END %] > <div class="form-field"> > <label class="form-field-label">Availability:</label> >- <input type="radio" name="onloan" id="onloan_indifferent" value="" checked="checked"/> >+ [% IF query.param('onloan') == '' %] >+ <input type="radio" name="onloan" id="onloan_indifferent" value="" checked="checked"/> >+ [% ELSE %] >+ <input type="radio" name="onloan" id="onloan_indifferent" value=""/> >+ [% END %] > <label for="onloan_indifferent">Ignore</label> >- <input type="radio" name="onloan" id="onloan_yes" value="IS NOT NULL" /> >+ [% IF query.param('onloan') == 'IS NOT NULL' %] >+ <input type="radio" name="onloan" id="onloan_yes" value="IS NOT NULL" checked="checked"/> >+ [% ELSE %] >+ <input type="radio" name="onloan" id="onloan_yes" value="IS NOT NULL"/> >+ [% END %] > <label for="onloan_yes">Checked out</label> >- <input type="radio" name="onloan" id="onloan_no" value="IS NULL" /> >+ [% IF query.param('onloan') == 'IS NULL' %] >+ <input type="radio" name="onloan" id="onloan_no" value="IS NULL" checked="checked"/> >+ [% ELSE %] >+ <input type="radio" name="onloan" id="onloan_no" value="IS NULL"/> >+ [% END %] > <label for="onloan_no">Not checked out</label> > </div> > </fieldset> > <fieldset> >- [% INCLUDE form_field_select_text %] >+ [% IF !query.param('f') %] >+ [% INCLUDE form_field_select_text %] >+ [% ELSE %] >+ [% FOREACH field IN query.param('f') %] >+ [% INCLUDE form_field_select_text %] >+ [% END %] >+ [% END %] > <p class="hint">You can use the following wildcard characters: % _</p> > <p class="hint">% matches any number of characters</p> > <p class="hint">_ matches only a single character</p> >@@ -227,12 +268,12 @@ > <fieldset> > <div class="form-field"> > <label class="form-field-label" for="itemcallnumber_from">From call number:</label> >- <input type="text" id="itemcallnumber_from" name="itemcallnumber_from" value="" /> >+ <input type="text" id="itemcallnumber_from" name="itemcallnumber_from" value="[% query.param('itemcallnumber_from') | html %]" /> > <span class="hint">(inclusive)</span> > </div> > <div class="form-field"> > <label class="form-field-label" for="itemcallnumber_to">To call number:</label> >- <input type="text" id="itemcallnumber_to" name="itemcallnumber_to" value="" /> >+ <input type="text" id="itemcallnumber_to" name="itemcallnumber_to" value="[% query.param('itemcallnumber_to') | html %]" /> > <span class="hint">(inclusive)</span> > </div> > [% IF ( has_new_status ) %] >@@ -241,21 +282,49 @@ > <div class="form-field"> > <label class="form-field-label" for="issues_op">Checkout count:</label> > <select id="issues_op" name="issues_op"> >- <option value=">">></option> >- <option value="<"><</option> >- <option value="=">=</option> >- <option value="!=">!=</option> >+ [% IF query.param('issues_op') == '>' %] >+ <option value=">" selected="selected">></option> >+ [% ELSE %] >+ <option value=">">></option> >+ [% END %] >+ [% IF query.param('issues_op') == '<' %] >+ <option value="<" selected="selected"><</option> >+ [% ELSE %] >+ <option value="<"><</option> >+ [% END %] >+ [% IF query.param('issues_op') == '=' %] >+ <option value="=" selected="selected">=</option> >+ [% ELSE %] >+ <option value="=">=</option> >+ [% END %] >+ [% IF query.param('issues_op') == '!=' %] >+ <option value="!=" selected="selected">!=</option> >+ [% ELSE %] >+ <option value="!=">!=</option> >+ [% END %] > </select> >- <input type="text" name="issues" /> >+ <input type="text" name="issues" value="[% query.param('issues') | html %]"/> > </div> > <div class="form-field"> > <label class="form-field-label" for="datelastborrowed_op">Last checkout date:</label> > <select id="datelastborrowed_op" name="datelastborrowed_op"> >- <option value=">">After</option> >- <option value="<">Before</option> >- <option value="=">On</option> >+ [% IF query.param('datelastborrowed_op') == '>' %] >+ <option value=">" selected="selected">After</option> >+ [% ELSE %] >+ <option value=">">After</option> >+ [% END %] >+ [% IF query.param('datelastborrowed_op') == '<' %] >+ <option value="<" selected="selected">Before</option> >+ [% ELSE %] >+ <option value="<">Before</option> >+ [% END %] >+ [% IF query.param('datelastborrowed_op') == '=' %] >+ <option value="=" selected="selected">On</option> >+ [% ELSE %] >+ <option value="=">On</option> >+ [% END %] > </select> >- <input type="text" name="datelastborrowed" /> >+ <input type="text" name="datelastborrowed" value="[% query.param('datelastborrowed') | html %]"/> > <span class="hint">ISO Format (YYYY-MM-DD)</span> > </div> > </fieldset> >@@ -368,6 +437,20 @@ > } > } > >+ function getParams($form) { >+ var params = []; >+ $form.find('select:not(:disabled) option:selected,input[type="text"]:not(:disabled),input[type="hidden"]:not(:disabled),input[type="radio"]:checked').each(function() { >+ if ( $(this).prop('tagName').toLowerCase() == 'option' ) { >+ var name = $(this).parents('select').first().attr('name'); >+ var value = $(this).val(); >+ params.push({ 'name': name, 'value': value }); >+ } else { >+ params.push({ 'name': $(this).attr('name'), 'value': $(this).val() }); >+ } >+ }); >+ return params; >+ } >+ > function submitForm($form) { > var tr = '' > + ' <tr>' >@@ -451,6 +534,24 @@ > $('#item-search-block').show(); > }); > >+ var getShareableLink = $('<a>') >+ .attr('href', '#') >+ .html("<i class='fa fa-copy'></i> " + _("Copy shareable link") ) >+ .addClass('btn btn-secondary') >+ .on('click', function(e) { >+ e.preventDefault(); >+ var params = getParams( $('#itemsearchform') ); >+ params = params.map(p => { >+ if(p.name === 'format') { >+ return { ...p, value: 'shareable' }; >+ } >+ return p; >+ }) >+ var url = window.location.origin + window.location.pathname + '?' + $.param(params); >+ navigator.clipboard.writeText(url); >+ $(this).tooltip({trigger: 'manual', title: 'Copied!'}).tooltip('show'); >+ }); >+ > var results_heading = $('<div>').addClass('results-heading') > .append("<h1>" + _("Item search results") + "</h1>") > .append($('<p>').append(advSearchLink)) >@@ -458,21 +559,13 @@ > .addClass("btn-toolbar") > .attr("id","toolbar") > .append(editSearchLink) >+ .append(getShareableLink) > ); > $('#results-wrapper').empty() > .append(results_heading) > .append(table); > >- var params = []; >- $form.find('select:not(:disabled) option:selected,input[type="text"]:not(:disabled),input[type="hidden"]:not(:disabled),input[type="radio"]:checked').each(function() { >- if ( $(this).prop('tagName').toLowerCase() == 'option' ) { >- var name = $(this).parents('select').first().attr('name'); >- var value = $(this).val(); >- params.push({ 'name': name, 'value': value }); >- } else { >- params.push({ 'name': $(this).attr('name'), 'value': $(this).val() }); >- } >- }); >+ var params = getParams($form); > > $('#results').dataTable($.extend(true, {}, dataTablesDefaults, { > "destroy": true, >-- >2.39.2
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 14322
:
164962
|
168084
|
168768
|
168863
|
169029
|
169033
|
169304
|
169305
|
169306
|
169948
|
169949
|
169950
|
169951
|
169952
|
169969
|
169970
|
169971
|
169972
|
169973
|
170347
|
170348
|
170349
|
170350
|
170351
|
170352
|
170721
|
170722
|
170723
|
170724
|
170725
|
170726
|
170727