View | Details | Raw Unified | Return to bug 14242
Collapse All | Expand All

(-)a/installer/data/mysql/atomicupdate/bug_14242-autofill_syspref.sql (+1 lines)
Line 0 Link Here
1
INSERT IGNORE INTO systempreferences (`variable`, `value`, `options`, `explanation`,`type`) VALUES ('OPACAutoFill', '0', NULL, 'Automaticly fill forms with data from Google Books API','YesNo');
(-)a/installer/data/mysql/sysprefs.sql (+1 lines)
Lines 278-283 INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` Link Here
278
('OAI-PMH:MaxCount','50',NULL,'OAI-PMH maximum number of records by answer to ListRecords and ListIdentifiers queries','Integer'),
278
('OAI-PMH:MaxCount','50',NULL,'OAI-PMH maximum number of records by answer to ListRecords and ListIdentifiers queries','Integer'),
279
('OCLCAffiliateID','','','Use with FRBRizeEditions and XISBN. You can sign up for an AffiliateID here: http://www.worldcat.org/wcpa/do/AffiliateUserServices?method=initSelfRegister','free'),
279
('OCLCAffiliateID','','','Use with FRBRizeEditions and XISBN. You can sign up for an AffiliateID here: http://www.worldcat.org/wcpa/do/AffiliateUserServices?method=initSelfRegister','free'),
280
('OPACAcquisitionDetails','0','','Show the acquisition details at the OPAC','YesNo'),
280
('OPACAcquisitionDetails','0','','Show the acquisition details at the OPAC','YesNo'),
281
('OPACAutoFill','0',NULL,'Automaticly fill forms with data from Google Books API','YesNo'),
281
('OpacAddMastheadLibraryPulldown','0','','Adds a pulldown menu to select the library to search on the opac masthead.','YesNo'),
282
('OpacAddMastheadLibraryPulldown','0','','Adds a pulldown menu to select the library to search on the opac masthead.','YesNo'),
282
('OpacAdvSearchMoreOptions','pubdate,itemtype,language,subtype,sorting,location','Show search options for the expanded view (More options)','pubdate|itemtype|language|subtype|sorting|location','multiple'),
283
('OpacAdvSearchMoreOptions','pubdate,itemtype,language,subtype,sorting,location','Show search options for the expanded view (More options)','pubdate|itemtype|language|subtype|sorting|location','multiple'),
283
('OpacAdvSearchOptions','pubdate,itemtype,language,sorting,location','Show search options','pubdate|itemtype|language|subtype|sorting|location','multiple'),
284
('OpacAdvSearchOptions','pubdate,itemtype,language,sorting,location','Show search options','pubdate|itemtype|language|subtype|sorting|location','multiple'),
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/opac.pref (+7 lines)
Lines 503-508 OPAC: Link Here
503
                  no: Don't display
503
                  no: Don't display
504
            - the acquisition details on OPAC detail pages.
504
            - the acquisition details on OPAC detail pages.
505
        -
505
        -
506
            - pref: OPACAutoFill
507
              default: 0
508
              choices:
509
                  yes: Enable
510
                  no: Disable
511
            - automatic form filling with data from Google Books API.
512
        -
506
            - "Use the following as the OPAC ISBD template:"
513
            - "Use the following as the OPAC ISBD template:"
507
            - pref: OPACISBD
514
            - pref: OPACISBD
508
              type: textarea
515
              type: textarea
(-)a/koha-tmpl/opac-tmpl/bootstrap/en/includes/opac-bottom.inc (+4 lines)
Lines 214-219 $.widget.bridge('uitooltip', $.ui.tooltip); Link Here
214
    </script>
214
    </script>
215
[% END %]
215
[% END %]
216
216
217
[% IF ( Koha.Preference('OPACAutoFill') ) %]
218
    <script type="text/javascript" src="[% interface %]/[% theme %]/js/autofill.js"></script>
219
[% END %]
220
217
[% IF ( BakerTaylorEnabled ) %]
221
[% IF ( BakerTaylorEnabled ) %]
218
    <script type="text/javascript" src="[% interface %]/[% theme %]/js/bakertaylorimages.js"></script>
222
    <script type="text/javascript" src="[% interface %]/[% theme %]/js/bakertaylorimages.js"></script>
219
    <script type="text/javascript">
223
    <script type="text/javascript">
(-)a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-suggestions.tt (-2 / +22 lines)
Lines 39-45 Link Here
39
                            <p>Only certain fields (marked in red) are 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>
39
                            <p>Only certain fields (marked in red) are 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>
40
40
41
                            <form action="/cgi-bin/koha/opac-suggestions.pl" method="post" id="add_suggestion_form">
41
                            <form action="/cgi-bin/koha/opac-suggestions.pl" method="post" id="add_suggestion_form">
42
                                <fieldset class="rows">
42
                                [% IF Koha.Preference( 'OPACAutoFill' ) %]
43
                                <fieldset class="rows well" style="margin-bottom: 3em;padding-top: 5px;">
44
                                    <label for="isbn">Standard number (ISBN, ISSN or other):</label><input type="text" id="isbn" name="isbn"  maxlength="80" />
45
                                </fieldset>
46
                                [% END %]
47
                                    <fieldset class="rows [% IF Koha.Preference( 'OPACAutoFill' ) %]well[% END %]">
43
                                    <ol>
48
                                    <ol>
44
                                        <li><label for="title">Title:</label><input type="text" id="title" name="title" class="span6" maxlength="255" /></li>
49
                                        <li><label for="title">Title:</label><input type="text" id="title" name="title" class="span6" maxlength="255" /></li>
45
                                        <li><label for="author">Author:</label><input type="text" id="author" name="author" class="span6" maxlength="80" /></li>
50
                                        <li><label for="author">Author:</label><input type="text" id="author" name="author" class="span6" maxlength="80" /></li>
Lines 48-54 Link Here
48
                                            <label for="copyrightdate">Copyright date:</label><input type="text" id="copyrightdate" name="copyrightdate" pattern="[12]\d{3}" size="4" maxlength="4" />
53
                                            <label for="copyrightdate">Copyright date:</label><input type="text" id="copyrightdate" name="copyrightdate" pattern="[12]\d{3}" size="4" maxlength="4" />
49
                                            </div>
54
                                            </div>
50
                                        </li>
55
                                        </li>
51
                                        <li><label for="isbn">Standard number (ISBN, ISSN or other):</label><input type="text" id="isbn" name="isbn"  maxlength="80" /></li>
56
                                        [% IF NOT Koha.Preference( 'OPACAutoFill' ) %]
57
                                        <li><label for="isbn">Standard number (ISBN, ISSN or other):</label><input type="text" id="isbn" name="isbn" maxlength="80" /></li>
58
                                        [% END %]
52
                                        <li><label for="publishercode">Publisher:</label><input type="text" id="publishercode" name="publishercode" class="span6" maxlength="80" /></li>
59
                                        <li><label for="publishercode">Publisher:</label><input type="text" id="publishercode" name="publishercode" class="span6" maxlength="80" /></li>
53
                                        <li><label for="collectiontitle">Collection title:</label><input type="text" id="collectiontitle" name="collectiontitle" class="span6" maxlength="80" /></li>
60
                                        <li><label for="collectiontitle">Collection title:</label><input type="text" id="collectiontitle" name="collectiontitle" class="span6" maxlength="80" /></li>
54
                                        <li><label for="place">Publication place:</label><input type="text" id="place" name="place"  maxlength="80" /></li>
61
                                        <li><label for="place">Publication place:</label><input type="text" id="place" name="place"  maxlength="80" /></li>
Lines 290-295 Link Here
290
        }
297
        }
291
    [% END %]
298
    [% END %]
292
299
300
    [% IF Koha.Preference( 'OPACAutoFill' ) %]
301
    $(function() {
302
        $('#isbn').autofill({
303
            'volumeInfo.title': {target: 'title', effect: 'flash'},
304
            'volumeInfo.authors': {target: 'author', effect: 'flash'},
305
            'volumeInfo.publisher': {target: 'publishercode', effect: 'flash'},
306
            /* google books api seem to only have books, so if we got a result
307
             * item, type will be a book, so set to BK (book). */
308
            'kind': {target: 'itemtype', handle: function(t,v) { t.val('BK'); },},
309
        });
310
    });
311
    [% END %]
312
293
    $(function() {
313
    $(function() {
294
        $("#suggestt").dataTable($.extend(true, {}, dataTablesDefaults, {
314
        $("#suggestt").dataTable($.extend(true, {}, dataTablesDefaults, {
295
            "aaSorting": [[ 1, "asc" ]],
315
            "aaSorting": [[ 1, "asc" ]],
(-)a/koha-tmpl/opac-tmpl/bootstrap/js/autofill.js (-1 / +202 lines)
Line 0 Link Here
0
- 
1
/*
2
 * jQuery autofill plugin
3
 *
4
 * Automaticly fills form inputs with relevant data based on search result
5
 */
6
7
(function ($) {
8
    function typeString(o) {
9
        if (typeof o != 'object')
10
            return typeof o;
11
12
        if (o === null)
13
            return "null";
14
15
        //object, array, function, date, regexp, string, number, boolean, error
16
        var internalClass = Object.prototype.toString.call(o)
17
            .match(/\[object\s(\w+)\]/)[1];
18
19
        return internalClass.toLowerCase();
20
    }
21
22
    var AutoFiller = function (elm, fields, type) {
23
        var self = this;
24
        self.type = type;
25
        self.$elm = $(elm);
26
        self.fields = fields;
27
28
        /* decorate element as autofiller */
29
        var $inputgroup = $('<div class="input-prepend">');
30
        self.$undo = $('<span class="add-on" style="display:none;cursor:pointer;">undo</span>');
31
        self.$fillbtn = $('<span class="add-on"><i class="icon-edit" style="cursor:pointer;"></i></span>');
32
        self.$error = $('<span class="add-on" style="display:none;"></span>');
33
        self.$elm.wrap($inputgroup);
34
        self.$elm.after(self.$error);
35
        self.$elm.after(self.$undo);
36
        self.$elm.after(self.$fillbtn);
37
38
        for(var key in fields) {
39
            if( fields.hasOwnProperty(key) && typeof fields[key] === 'object' ) {
40
                var $target = $('#' + self.fields[key].target);
41
                self.fields[key].$target = $target;
42
            }
43
        }
44
45
        self.$fillbtn.click(function(){
46
            /* only allow forced update once every second */
47
            if(Date.now() - self.lastupdate > 1000) {
48
                self.$elm.trigger('change');
49
            }
50
        });
51
52
        self.$undo.click(function(){
53
            for(var key in self.fields) {
54
                var field = self.fields[key];
55
                field.$target.trigger('autofill-undo');
56
            }
57
            self.$undo.hide();
58
        });
59
60
        self.$elm.change(function() {
61
            self.lastupdate = Date.now();
62
            self.$error.html('');
63
            self.$error.hide();
64
            /* give user some feedback that the request is in progress */
65
            self.$fillbtn.fadeOut(1000).fadeIn(1000);
66
67
            var gAPI = 'https://www.googleapis.com/books/v1/volumes?q=';
68
            if(self.type)
69
                gAPI += self.type + ':';
70
            gAPI += self.$elm.val();
71
            gAPI += '&maxResults=1';
72
73
            $.getJSON(gAPI, function (response) {
74
                if(response.totalItems == 0) {
75
                    self.$error.html('Sorry, nothing found.');
76
                    self.$error.show();
77
                    return;
78
                }
79
80
                var undos = 0;
81
                var item = response.items[0];
82
                for(var key in self.fields) {
83
                    var filled = false;
84
                    var value = eval('item.'+key);
85
                    var field = self.fields[key];
86
87
                    /* field handled by caller */
88
                    if('handle' in field) {
89
                        if(typeof field.handle === 'function')
90
                            field.handle(field.$target, value);
91
92
                        continue; /* next please */
93
                    }
94
95
                    /* wouldn't know what to do with result unless we have a
96
                     * target */
97
                    if( ! field.$target )
98
                        continue;
99
100
                    /* handle differently depending on datatype */
101
                    switch(typeString(value)) {
102
                        case 'array':
103
                            switch(field.$target.prop('nodeName').toUpperCase()) {
104
                                case 'TEXTAREA':
105
                                    undos++;
106
                                    field.$target.bind('autofill-undo', field.$target.text(), function(e){$(this).text(e.data);});
107
                                    field.$target.text(value.join(', '));
108
                                    break;
109
                                case 'INPUT':
110
                                default:
111
                                    undos++;
112
                                    field.$target.bind('autofill-undo', field.$target.val(), function(e){$(this).val(e.data);});
113
                                    field.$target.val(value.join(', '));
114
                                    break;
115
                            }
116
                            break;
117
                        default:
118
                            switch(field.$target.prop('nodeName').toUpperCase()) {
119
                                case 'TEXTAREA':
120
                                    undos++;
121
                                    field.$target.bind('autofill-undo', field.$target.text(), function(e){$(this).text(e.data);});
122
                                    field.$target.text(value);
123
                                    break;
124
                                case 'SELECT':
125
                                case 'INPUT':
126
                                default:
127
                                    undos++;
128
                                    field.$target.bind('autofill-undo', field.$target.val(), function(e){$(this).val(e.data);});
129
                                    field.$target.val(value);
130
                                    break;
131
                            }
132
                    }
133
134
                    switch(field.effect) {
135
                        case 'flash':
136
                            field.$target.fadeOut(500).fadeIn(500);
137
                            break;
138
                    }
139
                }
140
141
                if(undos > 0)
142
                    self.$undo.show();
143
144
            });
145
        });
146
    };
147
148
    /*
149
     * @fields object: Google Books API item propreties map for
150
     *                 mapping against a target element. Expected
151
     *                 type:
152
     *                 {
153
     *                  GoogleBooksItem.property: {target: ELEM,
154
     *                                             handle: function(target, value),
155
     *                                             effect: jQuery effects,
156
     *                                            }
157
     *                 }
158
     *
159
     *                 "target" is optional and if specified alone (i.e no
160
     *                 handle proprety) autofill will automaticly fill this
161
     *                 target element with returned data.
162
     *
163
     *                 "handle" is optional and will be called when ajax request
164
     *                 has finished and target is matched. Function specifies
165
     *                 two arguments: target and value. Target is the target
166
     *                 element specified by "target" and value is the value
167
     *                 returned by Google Books API for the matched property.
168
     *
169
     *                 If a handle function is given, full control of result data
170
     *                 is given to the handle function.
171
     *
172
     *                 "effect" is optional and specifies effect name of effect
173
     *                 to use for the target once value has been set. Can be one of:
174
     *
175
     *                      - 'flash'
176
     *
177
     * @type string: defines the query type, default to input name
178
     *               For example <input type="text" name="isbn"></input>
179
     *               will search for isbn by default
180
     *
181
     * @EXAMPLE
182
     *
183
     *  $('#isbn').autofill({
184
     *      'volumeInfo.title': {target: 'title', effect: 'flash'},
185
     *      'volumeInfo.authors': {target: 'author'},
186
     *      'volumeInfo.publisher': {target: 'publishercode'},
187
     *      'selfLink': {handle: function(t,v){window.location=v;}}
188
     *  });
189
     * */
190
    $.fn.autofill = function(fields, type) {
191
        if(type === undefined) // default to input name
192
            type = this.attr('name');
193
194
        return this.each(function(i){
195
            var plugin = $.data(this, "plugin_autofill");
196
            if (plugin)
197
                plugin.destroy();
198
199
            $.data(this, "plugin_autofill", new AutoFiller(this, fields, type));
200
        });
201
    };
202
}(jQuery));

Return to bug 14242