Bugzilla – Attachment 116620 Details for
Bug 14242
Use ISBN-field to fill out purchase suggestions using Google Books API
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 14242: Use ISBN-field to automatically fill out purchase suggestions
Bug-14242-Use-ISBN-field-to-automatically-fill-out.patch (text/plain), 18.36 KB, created by
Aleisha Amohia
on 2021-02-10 01:44:27 UTC
(
hide
)
Description:
Bug 14242: Use ISBN-field to automatically fill out purchase suggestions
Filename:
MIME Type:
Creator:
Aleisha Amohia
Created:
2021-02-10 01:44:27 UTC
Size:
18.36 KB
patch
obsolete
>From 40c2024f77e272e848299efb336c024fa8380a65 Mon Sep 17 00:00:00 2001 >From: Martin Stenberg <martin@xinxidi.net> >Date: Wed, 26 Aug 2015 20:22:30 +0200 >Subject: [PATCH] Bug 14242: Use ISBN-field to automatically fill out purchase > suggestions > >Add new jQuery plugin "autofill" which transforms selected element(s) into >search fields for Google Books API and automatically fills requested fields with >search result. > >Use in OPAC purchase suggestions to automatically fill out fields when entering >ISBN-number. > >Test plan: >1. Run updatedatabase.pl >2. Enable system precference "OPACSuggestionAutoFill" >3. Log into OPAC and go to purchase suggestions page >4. Write a valid ISBN (such as 0-9690745-2-2 or 978-1-78416-110-1) into the ISBN > field and press the edit icon next to the field, or unfocus the field. >5. Title, Author, Publisher and Item Type fields should now be filled > automatically. >6. Press "undo" to undo - should restore all fields that the API pull filled to empty >--- > .../atomicupdate/bug_14242-autofill_syspref.perl | 6 + > installer/data/mysql/mandatory/sysprefs.sql | 1 + > .../prog/en/modules/admin/preferences/opac.pref | 7 + > .../bootstrap/en/modules/opac-suggestions.tt | 36 +++- > koha-tmpl/opac-tmpl/bootstrap/js/autofill.js | 209 +++++++++++++++++++++ > 5 files changed, 253 insertions(+), 6 deletions(-) > create mode 100644 installer/data/mysql/atomicupdate/bug_14242-autofill_syspref.perl > create mode 100644 koha-tmpl/opac-tmpl/bootstrap/js/autofill.js > >diff --git a/installer/data/mysql/atomicupdate/bug_14242-autofill_syspref.perl b/installer/data/mysql/atomicupdate/bug_14242-autofill_syspref.perl >new file mode 100644 >index 0000000000..c56eae70ef >--- /dev/null >+++ b/installer/data/mysql/atomicupdate/bug_14242-autofill_syspref.perl >@@ -0,0 +1,6 @@ >+$DBversion = 'XXX'; >+if( CheckVersion( $DBversion ) ) { >+ $dbh->do(q{ INSERT IGNORE INTO systempreferences (`variable`, `value`, `options`, `explanation`,`type`) VALUES ('OPACSuggestionAutoFill', '0', NULL, 'Automatically fill OPAC suggestion form with data from Google Books API','YesNo') }); >+ >+ NewVersion( $DBversion, 14242, "Add OPACSuggestionAutoFill system preference"); >+} >diff --git a/installer/data/mysql/mandatory/sysprefs.sql b/installer/data/mysql/mandatory/sysprefs.sql >index eab5e66838..82b4e70463 100644 >--- a/installer/data/mysql/mandatory/sysprefs.sql >+++ b/installer/data/mysql/mandatory/sysprefs.sql >@@ -371,6 +371,7 @@ INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` > ('OAI-PMH:DeletedRecord','persistent','Koha\'s deletedbiblio table will never be deleted (persistent), might be deleted (transient), or will never have any data in it (no)','transient|persistent|no','Choice'), > ('OAI-PMH:MaxCount','50',NULL,'OAI-PMH maximum number of records by answer to ListRecords and ListIdentifiers queries','Integer'), > ('OPACAcquisitionDetails','0','','Show the acquisition details at the OPAC','YesNo'), >+('OPACSuggestionAutoFill','0',NULL,'Automatically fill OPAC suggestion form with data from Google Books API','YesNo'), > ('OpacAddMastheadLibraryPulldown','0','','Adds a pulldown menu to select the library to search on the opac masthead.','YesNo'), > ('OpacAdvSearchMoreOptions','pubdate,itemtype,language,subtype,sorting,location','Show search options for the expanded view (More options)','pubdate|itemtype|language|subtype|sorting|location','multiple'), > ('OpacAdvSearchOptions','pubdate,itemtype,language,sorting,location','Show search options','pubdate|itemtype|language|subtype|sorting|location','multiple'), >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/opac.pref b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/opac.pref >index 25db7ab70d..6137d060b5 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/opac.pref >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/opac.pref >@@ -531,6 +531,13 @@ OPAC: > no: Don't display > - a library selection list for news items in the OPAC. > - >+ - pref: OPACSuggestionAutoFill >+ default: 0 >+ choices: >+ yes: Enable >+ no: Disable >+ - OPAC suggestions form automatically filling with data from Google Books API. >+ - > - "Use the following as the OPAC ISBD template:" > - pref: OPACISBD > type: textarea >diff --git a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-suggestions.tt b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-suggestions.tt >index 49f3c49d31..642a1685a7 100644 >--- a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-suggestions.tt >+++ b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-suggestions.tt >@@ -71,6 +71,12 @@ > <form action="/cgi-bin/koha/opac-suggestions.pl" method="post" id="add_suggestion_form"> > <fieldset class="rows"> > <ol> >+ [% IF Koha.Preference( 'OPACSuggestionAutoFill' ) %] >+ <li> >+ <label for="isbn">Standard number (ISBN, ISSN or other):</label> >+ <input type="text" id="isbn" name="isbn" maxlength="80" style="margin-right:10px;margin-top:10px;" size="15"/> >+ </li> >+ [% END %] > <li> > [% IF ( title_required ) %] > <label for="title" class="required">Title:</label> >@@ -97,17 +103,18 @@ > <li> > <div title="Copyright or publication year, for example: 2016"> > [% IF ( copyrightdate_required ) %] >- <label for="copyrightdate" class="required">Copyright date:</label> >- <input type="text" id="copyrightdate" name="copyrightdate" pattern="[12]\d{3}" size="4" maxlength="4" value="[% copyrightdate | html %]" required="required" /> >- <span class="required">Required</span> >+ <label for="copyrightdate" class="required">Publication year:</label> >+ <input type="text" id="copyrightdate" name="copyrightdate" pattern="[12]\d{3}" size="10" maxlength="4" value="[% copyrightdate | html %]" required="required" /> >+ <span class="required">Required</span> > [% ELSE %] >- <label for="copyrightdate">Copyright date:</label> >- <input type="text" id="copyrightdate" name="copyrightdate" pattern="[12]\d{3}" size="4" maxlength="4" value="[% copyrightdate | html %]" /> >+ <label for="copyrightdate">Publication year:</label> >+ <input type="text" id="copyrightdate" name="copyrightdate" pattern="[12]\d{3}" size="10" maxlength="4" value="[% copyrightdate | html %]" /> > [% END %] >+ <span class="hint">Copyright or publication year, for example: 2016</span> > </div> > </li> > [% END %] >- [% UNLESS ( isbn_hidden )%] >+ [% UNLESS ( isbn_hidden or Koha.Preference('OPACSuggestionAutoFill') ) %] > <li> > [% IF ( isbn_required ) %] > <label for="isbn" class="required">Standard number (ISBN, ISSN or other):</label> >@@ -470,6 +477,9 @@ > > [% INCLUDE 'opac-bottom.inc' %] > [% BLOCK jsinclude %] >+[% IF ( Koha.Preference("OPACSuggestionAutoFill") ) %] >+ [% Asset.js("js/autofill.js") | $raw %] >+[% END %] > [% INCLUDE 'datatables.inc' %] > <script> > [% IF ( loggedinusername ) %] >@@ -486,6 +496,20 @@ > } > [% END %] > >+ [% IF Koha.Preference( 'OPACSuggestionAutoFill' ) %] >+ $(function() { >+ $('#isbn').autofill({ >+ 'volumeInfo.title': {target: 'title', effect: 'flash'}, >+ 'volumeInfo.authors': {target: 'author', effect: 'flash'}, >+ 'volumeInfo.publisher': {target: 'publishercode', effect: 'flash'}, >+ 'volumeInfo.publishedDate': {target: 'copyrightdate', effect: 'flash'}, >+ /* google books api seem to only have books, so if we got a result >+ * item, type will be a book, so set to BK (book). */ >+ 'kind': {target: 'itemtype', handle: function(t,v) { t.val('BK'); },}, >+ }); >+ }); >+ [% END %] >+ > $(function() { > $("#suggestt").dataTable($.extend(true, {}, dataTablesDefaults, { > "order": [[ 1, "asc" ]], >diff --git a/koha-tmpl/opac-tmpl/bootstrap/js/autofill.js b/koha-tmpl/opac-tmpl/bootstrap/js/autofill.js >new file mode 100644 >index 0000000000..e76de81fd4 >--- /dev/null >+++ b/koha-tmpl/opac-tmpl/bootstrap/js/autofill.js >@@ -0,0 +1,209 @@ >+/* >+ * Plugin dealing with the Google API based on jQuery autofill plugin >+ * https://plugins.jquery.com/autofill/ >+ * >+ * Automatically fills form inputs with relevant data based on search result >+ * Modified for OPAC Suggestion form >+ */ >+ >+(function ($) { >+ function typeString(o) { >+ if (typeof o != 'object') >+ return typeof o; >+ >+ if (o === null) >+ return "null"; >+ >+ //object, array, function, date, regexp, string, number, boolean, error >+ var internalClass = Object.prototype.toString.call(o) >+ .match(/\[object\s(\w+)\]/)[1]; >+ >+ return internalClass.toLowerCase(); >+ } >+ >+ var AutoFiller = function (elm, fields, type) { >+ var self = this; >+ self.type = type; >+ self.$elm = $(elm); >+ self.fields = fields; >+ >+ var MSG_UNDO_AUTOFILL_SUGGESTION = __("Clear form"); >+ var MSG_SEARCH_GOOGLE_BOOKS = __("Search Google Books"); >+ >+ /* decorate element as autofiller */ >+ self.$undo = $('<input type="button" class="btn btn-info btn-sm" style="display:none;margin-left:5px;" value="' + MSG_UNDO_AUTOFILL_SUGGESTION + '" />'); >+ self.$fillbtn = $('<input type="button" class="btn btn-primary btn-sm" value="' + MSG_SEARCH_GOOGLE_BOOKS + '" />'); >+ self.$error = $('<span class="add-on" style="display:none;padding-left:5px;"></span>'); >+ self.$elm.after(self.$error); >+ self.$elm.after(self.$undo); >+ self.$elm.after(self.$fillbtn); >+ >+ for(var key in fields) { >+ if( fields.hasOwnProperty(key) && typeof fields[key] === 'object' ) { >+ var $target = $('#' + self.fields[key].target); >+ self.fields[key].$target = $target; >+ } >+ } >+ >+ self.$fillbtn.click(function(){ >+ /* clear fields first */ >+ for(var key in self.fields) { >+ var field = self.fields[key]; >+ field.$target.trigger('autofill-undo'); >+ } >+ /* only allow forced update once every second */ >+ if(Date.now() - self.lastupdate > 1000) { >+ self.$elm.trigger('change'); >+ } >+ }); >+ >+ self.$undo.click(function(){ >+ for(var key in self.fields) { >+ var field = self.fields[key]; >+ //field.$target.val(""); >+ field.$target.trigger('autofill-undo'); >+ } >+ self.$undo.hide(); >+ }); >+ >+ self.$elm.change(function() { >+ self.lastupdate = Date.now(); >+ self.$error.html(''); >+ self.$error.hide(); >+ /* give user some feedback that the request is in progress */ >+ self.$fillbtn.fadeOut(1000).fadeIn(1000); >+ if ( self.$elm.val()) { >+ var gAPI = 'https://www.googleapis.com/books/v1/volumes?q='; >+ gAPI += self.$elm.val().replace(/\-/g, ''); >+ gAPI += '&maxResults=1'; >+ $.getJSON(gAPI, function (response) { >+ if(response.totalItems == 0) { >+ self.$error.html(__('Sorry, nothing found.')); >+ self.$error.show(); >+ return; >+ } >+ >+ var undos = 0; >+ var item = response.items[0]; >+ for(var key in self.fields) { >+ var filled = false; >+ var value = eval('item.'+key); >+ var field = self.fields[key]; >+ >+ /* field handled by caller */ >+ if('handle' in field) { >+ if(typeof field.handle === 'function') >+ field.handle(field.$target, value); >+ >+ continue; /* next please */ >+ } >+ >+ /* wouldn't know what to do with result unless we have a >+ * target */ >+ if( ! field.$target ) >+ continue; >+ >+ /* handle differently depending on datatype */ >+ switch(typeString(value)) { >+ case 'array': >+ switch(field.$target.prop('nodeName').toUpperCase()) { >+ case 'TEXTAREA': >+ undos++; >+ field.$target.bind('autofill-undo', field.$target.text(), function(e){$(this).text(e.data);}); >+ field.$target.text(value.join(', ')); >+ break; >+ case 'INPUT': >+ default: >+ undos++; >+ field.$target.bind('autofill-undo', field.$target.val(), function(e){$(this).val(e.data);}); >+ field.$target.val(value.join(', ')); >+ break; >+ } >+ break; >+ default: >+ switch(field.$target.prop('nodeName').toUpperCase()) { >+ case 'TEXTAREA': >+ undos++; >+ field.$target.bind('autofill-undo', field.$target.text(), function(e){$(this).text(e.data);}); >+ field.$target.text(value); >+ break; >+ case 'SELECT': >+ case 'INPUT': >+ default: >+ undos++; >+ field.$target.bind('autofill-undo', field.$target.val(), function(e){$(this).val(e.data);}); >+ field.$target.val(value); >+ break; >+ } >+ } >+ >+ switch(field.effect) { >+ case 'flash': >+ field.$target.fadeOut(500).fadeIn(500); >+ break; >+ } >+ } >+ >+ if(undos > 0) >+ self.$undo.show(); >+ >+ }); >+ } >+ }); >+ }; >+ >+ /* >+ * @fields object: Google Books API item propreties map for >+ * mapping against a target element. Expected >+ * type: >+ * { >+ * GoogleBooksItem.property: {target: ELEM, >+ * handle: function(target, value), >+ * effect: jQuery effects, >+ * } >+ * } >+ * >+ * "target" is optional and if specified alone (i.e no >+ * handle proprety) autofill will automaticly fill this >+ * target element with returned data. >+ * >+ * "handle" is optional and will be called when ajax request >+ * has finished and target is matched. Function specifies >+ * two arguments: target and value. Target is the target >+ * element specified by "target" and value is the value >+ * returned by Google Books API for the matched property. >+ * >+ * If a handle function is given, full control of result data >+ * is given to the handle function. >+ * >+ * "effect" is optional and specifies effect name of effect >+ * to use for the target once value has been set. Can be one of: >+ * >+ * - 'flash' >+ * >+ * @type string: defines the query type, default to input name >+ * For example <input type="text" name="isbn"></input> >+ * will search for isbn by default >+ * >+ * @EXAMPLE >+ * >+ * $('#isbn').autofill({ >+ * 'volumeInfo.title': {target: 'title', effect: 'flash'}, >+ * 'volumeInfo.authors': {target: 'author'}, >+ * 'volumeInfo.publisher': {target: 'publishercode'}, >+ * 'selfLink': {handle: function(t,v){window.location=v;}} >+ * }); >+ * */ >+ $.fn.autofill = function(fields, type) { >+ if(type === undefined) // default to input name >+ type = this.attr('name'); >+ >+ return this.each(function(i){ >+ var plugin = $.data(this, "plugin_autofill"); >+ if (plugin) >+ plugin.destroy(); >+ >+ $.data(this, "plugin_autofill", new AutoFiller(this, fields, type)); >+ }); >+ }; >+}(jQuery)); >-- >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 14242
:
42002
|
55949
|
56061
|
56062
|
56070
|
56071
|
56072
|
56073
|
56074
|
56075
|
84760
|
84761
|
84762
|
84763
|
84764
|
84840
|
85031
|
85032
|
85033
|
85034
|
85035
|
89643
|
89662
|
90157
|
90158
|
90159
|
90160
|
90161
|
90162
|
90250
|
90251
|
90252
|
90253
|
90254
|
90255
|
103527
|
103528
|
103529
|
103530
|
103531
|
103532
|
103533
|
108695
|
108696
|
108697
|
108698
|
108699
|
108700
|
108701
|
110141
|
110142
|
110143
|
110144
|
110145
|
110146
|
110147
|
110148
|
110493
|
110494
|
110495
|
110496
|
110497
|
110498
|
110499
|
110500
|
110501
|
110990
|
112597
|
112598
|
112599
|
112600
|
112601
|
112602
|
112603
|
112604
|
112605
|
112606
|
112607
|
113162
|
113163
|
113164
|
113165
|
113166
|
113167
|
116620
|
116712
|
116968
|
116989
|
125380
|
125381
|
125382
|
131219
|
131220
|
131221
|
131222
|
133985
|
133986
|
133987
|
133988
|
134273
|
134274
|
134275
|
134276
|
134277
|
134278