Bugzilla – Attachment 42002 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 automaticly fill out purchase suggestions
Bug-14242-Use-ISBN-field-to-automaticly-fill-out-p.patch (text/plain), 16.54 KB, created by
Martin Stenberg
on 2015-08-26 20:34:25 UTC
(
hide
)
Description:
Bug 14242: Use ISBN-field to automaticly fill out purchase suggestions
Filename:
MIME Type:
Creator:
Martin Stenberg
Created:
2015-08-26 20:34:25 UTC
Size:
16.54 KB
patch
obsolete
>From 79c71cfa1481c482ca428be9a56178231a9aaf17 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 automaticly fill out purchase > suggestions > >Add new jQuery plugin "autofill" which transforms selected element(s) into >search fields for Google Books API and automaticly fills requested fields with >search result. > >Use in OPAC purchase suggestions to automaticly 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 >--- > .../atomicupdate/bug_14242-autofill_syspref.sql | 1 + > installer/data/mysql/sysprefs.sql | 1 + > .../prog/en/modules/admin/preferences/opac.pref | 7 + > .../bootstrap/en/includes/opac-bottom.inc | 4 + > .../bootstrap/en/modules/opac-suggestions.tt | 24 ++- > koha-tmpl/opac-tmpl/bootstrap/js/autofill.js | 202 +++++++++++++++++++++ > 6 files changed, 237 insertions(+), 2 deletions(-) > create mode 100644 installer/data/mysql/atomicupdate/bug_14242-autofill_syspref.sql > create mode 100644 koha-tmpl/opac-tmpl/bootstrap/js/autofill.js > >diff --git a/installer/data/mysql/atomicupdate/bug_14242-autofill_syspref.sql b/installer/data/mysql/atomicupdate/bug_14242-autofill_syspref.sql >new file mode 100644 >index 0000000..3cb4ffb >--- /dev/null >+++ b/installer/data/mysql/atomicupdate/bug_14242-autofill_syspref.sql >@@ -0,0 +1 @@ >+INSERT IGNORE INTO systempreferences (`variable`, `value`, `options`, `explanation`,`type`) VALUES ('OPACAutoFill', '0', NULL, 'Automaticly fill forms with data from Google Books API','YesNo'); >diff --git a/installer/data/mysql/sysprefs.sql b/installer/data/mysql/sysprefs.sql >index ac79f44..3a28dde 100644 >--- a/installer/data/mysql/sysprefs.sql >+++ b/installer/data/mysql/sysprefs.sql >@@ -238,6 +238,7 @@ INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` > ('OAI-PMH:MaxCount','50',NULL,'OAI-PMH maximum number of records by answer to ListRecords and ListIdentifiers queries','Integer'), > ('OCLCAffiliateID','','','Use with FRBRizeEditions and XISBN. You can sign up for an AffiliateID here: http://www.worldcat.org/wcpa/do/AffiliateUserServices?method=initSelfRegister','free'), > ('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 2fd6867..4ee9d8d 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 >@@ -475,6 +475,13 @@ OPAC: > yes: Display > no: Don't display > - the acquisition details on OPAC detail pages. >+ - >+ - pref: OPACAutoFill >+ default: 0 >+ choices: >+ yes: Enable >+ no: Disable >+ - automatic form filling with data from Google Books API. > Policy: > - > - pref: singleBranchMode >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 1d350ea..72867d2 100644 >--- a/koha-tmpl/opac-tmpl/bootstrap/en/includes/opac-bottom.inc >+++ b/koha-tmpl/opac-tmpl/bootstrap/en/includes/opac-bottom.inc >@@ -195,6 +195,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 ) %] > <script type="text/javascript" src="[% interface %]/[% theme %]/js/bakertaylorimages.js"></script> > <script type="text/javascript"> >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 09032e4..9b41158 100644 >--- a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-suggestions.tt >+++ b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-suggestions.tt >@@ -33,12 +33,19 @@ > <p>Only the title is required, but the more information you enter the easier it will be for the librarians to find the title you're requesting. The "Notes" field can be used to provide any additional information.</p> > > <form action="/cgi-bin/koha/opac-suggestions.pl" method="post"> >- <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><label class="required" for="title">Title:</label><input type="text" id="title" name="title" class="span6" maxlength="255" /></li> > <li><label for="author">Author:</label><input type="text" id="author" name="author" class="span6" maxlength="80" /></li> > <li><label for="copyrightdate">Copyright date:</label><input type="text" id="copyrightdate" name="copyrightdate" size="4" maxlength="4" /></li> >- <li><label for="isbn">Standard number (ISBN, ISSN or other):</label><input type="text" id="isbn" name="isbn" maxlength="80" /></li> >+ [% IF NOT Koha.Preference( 'OPACAutoFill' ) %] >+ <li><label for="isbn">Standard number (ISBN, ISSN or other):</label><input type="text" id="isbn" name="isbn" maxlength="80" /></li> >+ [% END %] > <li><label for="publishercode">Publisher:</label><input type="text" id="publishercode" name="publishercode" class="span6" maxlength="80" /></li> > <li><label for="collectiontitle">Collection title:</label><input type="text" id="collectiontitle" name="collectiontitle" class="span6" maxlength="80" /></li> > <li><label for="place">Publication place:</label><input type="text" id="place" name="place" maxlength="80" /></li> >@@ -282,6 +289,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, { > "aaSorting": [[ 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 0000000..f6c487a >--- /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.5.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