Bugzilla – Attachment 112597 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), 15.21 KB, created by
Aleisha Amohia
on 2020-10-28 02:24:39 UTC
(
hide
)
Description:
Bug 14242: Use ISBN-field to automatically fill out purchase suggestions
Filename:
MIME Type:
Creator:
Aleisha Amohia
Created:
2020-10-28 02:24:39 UTC
Size:
15.21 KB
patch
obsolete
>From b4e8842253adcc64713e95d122536a6516045055 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 "OPACAutoFill" >3. Log into OPAC and go to purchase suggetions page >4. Write a valid ISBN 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 > automaticly. >6. Press "undo" to undo - should restore all changed fields to original values > >Tested all patches together, works as expected. >Signed-off-by: Marc <veron@veron.ch> > >Signed-off-by: Maryse Simard <maryse.simard@inlibro.com> > >Signed-off-by: Lisette Scheer <lisetteslatah@gmail.com> >--- > installer/data/mysql/mandatory/sysprefs.sql | 1 + > .../prog/en/modules/admin/preferences/opac.pref | 7 + > .../bootstrap/en/includes/opac-bottom.inc | 4 + > .../bootstrap/en/modules/opac-suggestions.tt | 22 ++- > koha-tmpl/opac-tmpl/bootstrap/js/autofill.js | 202 +++++++++++++++++++++ > 5 files changed, 234 insertions(+), 2 deletions(-) > create mode 100644 koha-tmpl/opac-tmpl/bootstrap/js/autofill.js > >diff --git a/installer/data/mysql/mandatory/sysprefs.sql b/installer/data/mysql/mandatory/sysprefs.sql >index 0e9f488055..b2ce37903e 100644 >--- a/installer/data/mysql/mandatory/sysprefs.sql >+++ b/installer/data/mysql/mandatory/sysprefs.sql >@@ -368,6 +368,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'), >+('OPACAutoFill','0',NULL,'Automaticly fill forms 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 3d8cd4fab9..3f0a49fb77 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: OPACAutoFill >+ default: 0 >+ choices: >+ yes: Enable >+ no: Disable >+ - automatic form 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/includes/opac-bottom.inc b/koha-tmpl/opac-tmpl/bootstrap/en/includes/opac-bottom.inc >index 1641593395..e7625718eb 100644 >--- a/koha-tmpl/opac-tmpl/bootstrap/en/includes/opac-bottom.inc >+++ b/koha-tmpl/opac-tmpl/bootstrap/en/includes/opac-bottom.inc >@@ -279,6 +279,10 @@ $.widget.bridge('uitooltip', $.ui.tooltip); > </script> > [% END %] > >+[% IF ( Koha.Preference('OPACAutoFill') ) %] >+ <script type="text/javascript" src="[% interface %]/[% theme %]/js/autofill.js"></script> >+[% END %] >+ > [% IF ( BakerTaylorEnabled ) %] > [% Asset.js("js/bakertaylorimages.js") | $raw %] > <script> >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 956a254805..149f0d33cc 100644 >--- a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-suggestions.tt >+++ b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-suggestions.tt >@@ -64,7 +64,12 @@ > [% END %] > > <form action="/cgi-bin/koha/opac-suggestions.pl" method="post" id="add_suggestion_form"> >- <fieldset class="rows"> >+ [% IF Koha.Preference( 'OPACAutoFill' ) %] >+ <fieldset class="rows well" style="margin-bottom: 3em;padding-top: 5px;"> >+ <label for="isbn">Standard number (ISBN, ISSN or other):</label><input type="text" id="isbn" name="isbn" maxlength="80" /> >+ </fieldset> >+ [% END %] >+ <fieldset class="rows [% IF Koha.Preference( 'OPACAutoFill' ) %]well[% END %]"> > <ol> > <li> > [% IF ( title_required ) %] >@@ -102,7 +107,7 @@ > </div> > </li> > [% END %] >- [% UNLESS ( isbn_hidden )%] >+ [% UNLESS ( isbn_hidden && Koha.Preference('OPACAutoFill' )%] > <li> > [% IF ( isbn_required ) %] > <label for="isbn" class="required">Standard number (ISBN, ISSN or other):</label> >@@ -482,6 +487,19 @@ > } > [% END %] > >+ [% IF Koha.Preference( 'OPACAutoFill' ) %] >+ $(function() { >+ $('#isbn').autofill({ >+ 'volumeInfo.title': {target: 'title', effect: 'flash'}, >+ 'volumeInfo.authors': {target: 'author', effect: 'flash'}, >+ 'volumeInfo.publisher': {target: 'publishercode', 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..f6c487a86b >--- /dev/null >+++ b/koha-tmpl/opac-tmpl/bootstrap/js/autofill.js >@@ -0,0 +1,202 @@ >+/* >+ * jQuery autofill plugin >+ * >+ * Automaticly fills form inputs with relevant data based on search result >+ */ >+ >+(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; >+ >+ /* decorate element as autofiller */ >+ var $inputgroup = $('<div class="input-prepend">'); >+ self.$undo = $('<span class="add-on" style="display:none;cursor:pointer;">undo</span>'); >+ self.$fillbtn = $('<span class="add-on"><i class="icon-edit" style="cursor:pointer;"></i></span>'); >+ self.$error = $('<span class="add-on" style="display:none;"></span>'); >+ self.$elm.wrap($inputgroup); >+ 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(){ >+ /* 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.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); >+ >+ var gAPI = 'https://www.googleapis.com/books/v1/volumes?q='; >+ if(self.type) >+ gAPI += self.type + ':'; >+ gAPI += self.$elm.val(); >+ 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