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

(-)a/koha-tmpl/opac-tmpl/bootstrap/en/includes/recordedbooks-checkout.inc (+15 lines)
Line 0 Link Here
1
<div id="recordedbooks-checkout" class="modal hide" tabindex="-1" role="dialog" aria-labelledby="recordedbooks-checkout-label" aria-hidden="true">
2
    <div class="modal-header">
3
        <button type="button" class="closebtn" data-dismiss="modal" aria-hidden="true">×</button>
4
        <h3 id="recordedbooks-checkout-label">Checkout</h3>
5
    </div>
6
    <form action="#" method="post" id="recordedbooks-checkout-form">
7
        <div class="modal-body">
8
                <input type="hidden" name="id" value="" />
9
        </div>
10
        <div class="modal-footer">
11
            <input type="submit" class="btn btn-primary recordedbooks-checkout-submit" value="Checkout" />
12
            <a href="#" data-dismiss="modal" aria-hidden="true" class="cancel">Cancel</a>
13
        </div>
14
    </form> <!-- /#recordedbooks-checkout-form -->
15
</div>  <!-- /#recordedbooks-checkout  -->
(-)a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-recordedbooks-search.tt (+168 lines)
Line 0 Link Here
1
[% USE Koha %]
2
[% INCLUDE 'doc-head-open.inc' %]
3
<title>[% IF ( LibraryNameTitle ) %][% LibraryNameTitle %][% ELSE %]Koha online[% END %] catalog &rsaquo; RecordedBooks search for '[% q | html %]'</title>
4
[% INCLUDE 'doc-head-close.inc' %]
5
[% BLOCK cssinclude %]
6
<link rel="stylesheet" type="text/css" href="[% interface %]/[% theme %]/css/jquery.rating.css" />
7
<style>
8
.actions a.addtocart {
9
    display: inline;
10
}
11
</style>
12
[% END %]
13
</head>
14
[% INCLUDE 'bodytag.inc' bodyid='recordedbooks-results-page' bodyclass='scrollto' %]
15
[% INCLUDE 'masthead.inc' %]
16
17
    <div class="main">
18
        <ul class="breadcrumb">
19
            <li><a href="/cgi-bin/koha/opac-main.pl">Home</a> <span class="divider">&rsaquo;</span></li>
20
            <li><a href="#">RecordedBooks search for '[% q | html %]'</a></li>
21
        </ul>
22
23
        <div class="container-fluid">
24
            <div class="row-fluid">
25
                <div class="span2">
26
                    [% IF ( OpacNav || OpacNavBottom ) %]
27
                        [% INCLUDE 'navigation.inc' %]
28
                    [% END %]
29
                </div>
30
                <div class="span10">
31
                    <div id="recordedbooks-results-content" class="maincontent searchresults">
32
                        <h1>RecordedBooks search for '[% q | html %]'</h1>
33
                            <div id="breadcrumbs">
34
                                <p></p>
35
                            </div>
36
37
                            <div id="top-pages">
38
                                <div class="pagination pagination-small">
39
                                </div>
40
                            </div>
41
42
                            <table id="recordedbooks-results-list" class="table table-striped">
43
                                <tbody>
44
                                </tbody>
45
                            </table>
46
47
                            <div id="bottom-pages">
48
                                <div class="pagination pagination-small">
49
                                </div>
50
                            </div>
51
52
                    </div> <!-- / #recordedbooks-results-content -->
53
                </div> <!-- / .span10 -->
54
            </div> <!-- / .row-fluid -->
55
        </div> <!-- / .container-fluid -->
56
    </div> <!-- / .main -->
57
58
[% INCLUDE 'recordedbooks-checkout.inc' %]
59
60
[% INCLUDE 'opac-bottom.inc' %]
61
[% BLOCK jsinclude %]
62
<script type="text/javascript" src="[% interface %]/[% theme %]/js/recordedbooks.js"></script>
63
<script type="text/javascript" src="[% interface %]/[% theme %]/lib/jquery/plugins/jquery.rating.js"></script>
64
<script type="text/javascript">
65
var querystring = "[% q |replace( "'", "\'" ) |replace( '\n', '\\n' ) |replace( '\r', '\\r' ) |html %]";
66
var results_per_page = [% OPACnumSearchResults || 20 %];
67
68
function search( page ) {
69
    $( '#recordedbooks-status' ).html( _("Searching RecordedBooks...") + ' <img class="throbber" src="[% interface %]/lib/jquery/plugins/themes/classic/throbber.gif" /></span>' );
70
71
    KOHA.RecordedBooks.search( querystring, results_per_page, page, function( data ) {
72
        if ( data.error ) {
73
            $( '#recordedbooks-status' ).html( '<strong class="unavailable">' + _("Error searching RecordedBooks collection") + ': ' + data.error + '</strong>' );
74
            return;
75
        }
76
77
        if ( !data.total ) {
78
            $( '#recordedbooks-status' ).html( '<strong>' + _("No results found in the library's RecordedBooks collection.") + '</strong>' );
79
            return;
80
        }
81
82
        $( '#recordedbooks-results-list tbody' ).empty();
83
84
        $( '#recordedbooks-status' ).html( '<strong>' + _("Found") + ' ' + data.total + ' ' + _("results in the library's RecordedBooks collection.") + '</strong>' );
85
86
        for ( var i = 0; data.items[i]; i++ ) {
87
            var prod = data.items[i];
88
            var results = [];
89
90
            results.push( '<tr>' );
91
92
            results.push( '<td class="info"><span class="title">' );
93
            if (prod.url) results.push( '<a href="', prod.url, '" target="recordedbooks">' );
94
            results.push( prod.title );
95
            if (prod.url) results.push( '</a>' );
96
            results.push( '</span>' );
97
            results.push( '<p>' + _("by") + ' ', prod.author, '</p>' );
98
            if (prod.description) results.push( '<p>' + prod.description, '</p>' );
99
            results.push( '<span class="results_summary mediatype"><span class="label">' + _("Type:") + ' </span>', prod.media, '</span>' );
100
101
            results.push( '</td>' );
102
103
            results.push( '<td>' );
104
            if ( prod.images && prod.images.medium ) {
105
                if (prod.url) results.push( '<a href="', prod.url, '" target="recordedbooks">' );
106
                results.push( '<img class="thumbnail" src="', prod.images.medium, '" />' );
107
                if (prod.url) results.push( '</a>' );
108
            }
109
            results.push( '</td>' );
110
111
            results.push( '</tr>' );
112
            var $tr = $( results.join( '' ));
113
            $( '#recordedbooks-results-list tbody' ).append( $tr );
114
115
            $tr.find( '.info' ).each(function() {
116
                KOHA.RecordedBooks.add_actions(this, prod.isbn);
117
            });
118
        }
119
120
        $( '#recordedbooks-results-list tr:odd' ).addClass( 'highlight' );
121
122
        var pages = [];
123
124
        var max_page = Math.floor( data.total / results_per_page );
125
        if (data.total == page*results_per_page) max_page++;
126
127
        if ( page != 1 ) {
128
            pages.push( '<li><a class="od-nav" href="#" data-page="' + (page - 1) + '">&laquo; ' + _("Previous") + '</a></li>' );
129
        }
130
131
        for ( var p = Math.max( 0, page - 9 ); p <= Math.min( max_page, p + 9 ); p++ ) {
132
            if ( p == page ) {
133
                pages.push( ' <li class="active"><a href="#">' + ( p + 1 ) + '</a></li>' );
134
            } else {
135
                pages.push( ' <li><a class="od-nav" href="#" data-page="' +  p + '">' + p + '</a></li>' );
136
            }
137
        }
138
139
        if ( page < max_page ) {
140
            pages.push( ' <li><a class="od-nav" href="#" data-page="' + (page + 1) + '">' + _("Next") + ' &raquo;</a></li>' );
141
        }
142
143
        if ( pages.length > 1 ) $( '#top-pages, #bottom-pages' ).find( '.pagination' ).html( '<ul>' + pages.join( '' ) + '</ul>');
144
145
        $( '#recordedbooks-results-list input.star' ).rating();
146
    } );
147
}
148
149
$( document ).ready( function() {
150
    $( '#breadcrumbs p' )
151
        .append( ' ' )
152
        .append( '<span id="recordedbooks-status"></span>' );
153
154
    $( document ).on( 'click', 'a.od-nav', function() {
155
        search( $( this ).data( 'page' ) );
156
        return false;
157
    });
158
159
    [% IF ( loggedinusername ) %]
160
    KOHA.RecordedBooks.with_account_details("#breadcrumbs", function() {
161
        search( 1 );
162
    });
163
    [% ELSE %]
164
        search( 1 );
165
    [% END %]
166
} );
167
</script>
168
[% END %]
(-)a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-results.tt (+18 lines)
Lines 590-595 Link Here
590
[% END %]
590
[% END %]
591
[% IF ( OpacStarRatings == 'all' || Koha.Preference('Babeltheque') ) %]<script type="text/javascript" src="[% interface %]/[% theme %]/lib/jquery/plugins/jquery.rating.js"></script>[% END %]
591
[% IF ( OpacStarRatings == 'all' || Koha.Preference('Babeltheque') ) %]<script type="text/javascript" src="[% interface %]/[% theme %]/lib/jquery/plugins/jquery.rating.js"></script>[% END %]
592
[% IF ( OverDriveEnabled ) %]<script type="text/javascript" src="[% interface %]/[% theme %]/js/overdrive.js"></script>[% END %]
592
[% IF ( OverDriveEnabled ) %]<script type="text/javascript" src="[% interface %]/[% theme %]/js/overdrive.js"></script>[% END %]
593
[% IF ( RecordedBooksEnabled ) %]<script type="text/javascript" src="[% interface %]/[% theme %]/js/recordedbooks.js"></script>[% END %]
593
<script type="text/javascript" src="[% interface %]/[% theme %]/lib/jquery/plugins/jquery.checkboxes.min.js"></script>
594
<script type="text/javascript" src="[% interface %]/[% theme %]/lib/jquery/plugins/jquery.checkboxes.min.js"></script>
594
[% IF ( OpacHighlightedWords ) %]<script type="text/javascript" src="[% interface %]/[% theme %]/lib/jquery/plugins/jquery.highlight-3.js"></script>
595
[% IF ( OpacHighlightedWords ) %]<script type="text/javascript" src="[% interface %]/[% theme %]/lib/jquery/plugins/jquery.highlight-3.js"></script>
595
[% END %]<script type="text/javascript">
596
[% END %]<script type="text/javascript">
Lines 901-906 $(document).ready(function(){ Link Here
901
            }
902
            }
902
        } );
903
        } );
903
    [% END %]
904
    [% END %]
905
    [% IF ( RecordedBooksEnabled ) %]
906
        var $recordedbooks_results = $( '<div id="recordedbooks-results">' + _( 'Searching RecordedBooks...' ) + ' <img class="throbber" src="[% interface %]/lib/jquery/plugins/themes/classic/throbber.gif" /></div>' );
907
        $( '#numresults' ) .append( ' ' )
908
            .append( $recordedbooks_results );
909
        KOHA.RecordedBooks.search( querystring, [% OPACnumSearchResults || "null" %], null, function( data ) {
910
            if ( data.error ) {
911
                $recordedbooks_results.html( _( 'Error searching RecordedBooks collection' )  + ': ' + data.error);
912
                return;
913
            }
914
915
            if ( data.total > 0 ) {
916
                $recordedbooks_results.html( _( 'Found' ) + ' <a href="/cgi-bin/koha/opac-recordedbooks-search.pl?q=' + escape( querystring ) + '">' + data.total + ' ' + _( 'results' ) + '</a> ' + _( 'in RecordedBooks collection' ) );
917
            } else {
918
                $recordedbooks_results.remove();
919
            }
920
        } );
921
    [% END %]
904
    [% IF ( OpenLibrarySearch ) %]
922
    [% IF ( OpenLibrarySearch ) %]
905
        var $openlibrary_results = $( '<div id="openlibrary-results">' + _( 'Searching Open Library...' ) + ' <img class="throbber" src="[% interface %]/lib/jquery/plugins/themes/classic/throbber.gif" /></div>' );
923
        var $openlibrary_results = $( '<div id="openlibrary-results">' + _( 'Searching Open Library...' ) + ' <img class="throbber" src="[% interface %]/lib/jquery/plugins/themes/classic/throbber.gif" /></div>' );
906
        $( '#numresults' ) .append( ' ' )
924
        $( '#numresults' ) .append( ' ' )
(-)a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-user.tt (-1 / +25 lines)
Lines 158-167 Using this account is not recommended because some parts of Koha will not functi Link Here
158
                            [% IF ( OverDriveCirculation ) %]
158
                            [% IF ( OverDriveCirculation ) %]
159
                            <li><a href="#opac-user-overdrive">OverDrive Account</a></li>
159
                            <li><a href="#opac-user-overdrive">OverDrive Account</a></li>
160
                            [% END %]
160
                            [% END %]
161
                            [% IF ( RecordedBooksCirculation ) %]
162
                            <li><a href="#opac-user-recordedbooks">RecordedBooks Account</a></li>
163
                            [% END %]
161
                        </ul>
164
                        </ul>
162
165
163
                        <div id="opac-user-overdrive">
166
                        <div id="opac-user-overdrive">
164
                        </div>
167
                        </div>
168
                        <div id="opac-user-recordedbooks">
169
                        </div>
165
                        <div id="opac-user-checkouts">
170
                        <div id="opac-user-checkouts">
166
                            [% IF ( issues_count ) %]
171
                            [% IF ( issues_count ) %]
167
                                <form id="renewselected" action="/cgi-bin/koha/opac-renew.pl" method="post">
172
                                <form id="renewselected" action="/cgi-bin/koha/opac-renew.pl" method="post">
Lines 886-891 Using this account is not recommended because some parts of Koha will not functi Link Here
886
[% IF ( OverDriveCirculation ) %]
891
[% IF ( OverDriveCirculation ) %]
887
[% INCLUDE 'overdrive-checkout.inc' %]
892
[% INCLUDE 'overdrive-checkout.inc' %]
888
[% END %]
893
[% END %]
894
[% IF ( RecordedBooksCirculation ) %]
895
[% INCLUDE 'recordedbooks-checkout.inc' %]
896
[% END %]
889
897
890
[% INCLUDE 'opac-bottom.inc' %]
898
[% INCLUDE 'opac-bottom.inc' %]
891
899
Lines 1039-1045 Using this account is not recommended because some parts of Koha will not functi Link Here
1039
        });
1047
        });
1040
        //]]>
1048
        //]]>
1041
    </script>
1049
    </script>
1042
    [% IF Koha.Preference('OverDriveCirculation') %]
1050
    [% IF OverDriveCirculation %]
1043
    <script type="text/javascript" src="[% interface %]//[% theme %]/js/overdrive.js"></script>
1051
    <script type="text/javascript" src="[% interface %]//[% theme %]/js/overdrive.js"></script>
1044
    <script type="text/JavaScript">
1052
    <script type="text/JavaScript">
1045
    $(document).ready(function() {
1053
    $(document).ready(function() {
Lines 1057-1060 Using this account is not recommended because some parts of Koha will not functi Link Here
1057
    });
1065
    });
1058
    </script>
1066
    </script>
1059
    [% END %]
1067
    [% END %]
1068
    [% IF RecordedBooksCirculation %]
1069
    <script type="text/javascript" src="[% interface %]//[% theme %]/js/recordedbooks.js"></script>
1070
    <script type="text/JavaScript">
1071
    $(document).ready(function() {
1072
    [% IF ( recordedbooks_error ) %]
1073
        KOHA.RecordedBooks.display_error("#opac-user-recordedbooks", "[% recordedbooks_error.dquote %]");
1074
    [% END %]
1075
    [% IF ( recordedbooks_tab ) %]
1076
        $("#opac-user-views").tabs("select", "#opac-user-recordedbooks");
1077
    [% END %]
1078
        $("#opac-user-recordedbooks").each( function() {
1079
            KOHA.RecordedBooks.display_account_details(this);
1080
        } );
1081
    });
1082
    [% END %]
1083
    </script>
1060
[% END %]
1084
[% END %]
(-)a/koha-tmpl/opac-tmpl/bootstrap/js/recordedbooks.js (+325 lines)
Line 0 Link Here
1
if ( typeof KOHA == "undefined" || !KOHA ) {
2
    var KOHA = {};
3
}
4
5
KOHA.RecordedBooks = new function() {
6
    var svc_url = '/cgi-bin/koha/svc/recordedbooks';
7
8
    var error_div = $('<div class="recordedbooks-error">');
9
    function display_error ( error ) {
10
        error_div.text(error);
11
    }
12
13
    var details = null;
14
15
    function is_identified() {
16
        return details ? details.is_identified : false;
17
    }
18
19
    var checkout_popup = null;
20
    $( document ).ready(function() {
21
        checkout_popup = $("#recordedbooks-checkout");
22
    });
23
24
    function display_account (container, data) {
25
        if (!data.is_identified) {
26
            return;
27
        }
28
29
        if (data.checkouts) {
30
            var checkouts_div = $('<div class="recordedbooks-div">').html('<h3>' + _("Checkouts") + '</h3>');
31
            var items = data.checkouts.items;
32
            var checkouts_list;
33
            if (items.length == 0) {
34
                checkouts_list = _("No checkouts");
35
            } else {
36
                checkouts_list = $('<ul class="recordedbooks-list">');
37
                data.checkouts.items.forEach(function(item) {
38
                    item_line(checkouts_list, item);
39
                });
40
            }
41
            checkouts_div.append(checkouts_list);
42
            $(container).append(checkouts_div);
43
        }
44
45
        if (data.holds) {
46
            var holds_div = $('<div class="recordedbooks-div">').html('<h3>' + _("Holds") + '</h3>');
47
            var items = data.holds.items;
48
            var holds_list;
49
            if (items.length == 0) {
50
                holds_list = _("No holds");
51
            } else {
52
                holds_list = $('<ul class="recordedbooks-list">');
53
                data.holds.items.forEach(function(item) {
54
                    item_line(holds_list, item);
55
                });
56
            }
57
            holds_div.append(holds_list);
58
            $(container).append(holds_div);
59
        }
60
    }
61
62
    function item_line(ul_el, item) {
63
        var line = $('<li class="recordedbooks-item">');
64
        if (item.images) {
65
            var thumb_url = item.images.small;
66
            if (thumb_url) {
67
                $('<img class="recordedbooks-item-thumbnail">')
68
                    .attr("src", thumb_url)
69
                    .appendTo(line);
70
            }
71
        }
72
        $('<div class="recordedbooks-item-title">')
73
            .text(item.title)
74
            .appendTo(line);
75
        $('<div class="recordedbooks-item-subtitle">')
76
            .text(item.subtitle)
77
            .appendTo(line);
78
        $('<div class="recordedbooks-item-author">')
79
            .text(item.author)
80
            .appendTo(line);
81
        if (item.files && item.files.length > 0) {
82
            downloads = $('<div class="recordedbooks-item-author">')
83
                .text("Downloads")
84
                .appendTo(line);
85
            render_downloads(downloads, item.files);
86
        }
87
        var actions = $('<span class="actions">');
88
        display_actions(actions, item.isbn);
89
        $('<div id="action_'+item.isbn+'" class="actions-menu">')
90
            .append(actions)
91
            .appendTo(line);
92
93
        $(ul_el).append(line);
94
    }
95
96
    function render_downloads(el, files) {
97
        if (files.length == 0) return;
98
        var file_spec = files.shift();
99
        if (/^https?:\/\/api\./.test(file_spec.url)) {
100
            $.ajax({
101
                dataType: "json",
102
                url: file_spec.url,
103
                success: function (data) {
104
                    append_download_link(el, data.url, data.id);
105
                    render_downloads(el, files);
106
                },
107
                error: function(jqXHR, textStatus, errorThrown) {
108
                    display_error(errorThrown);
109
                }
110
            });
111
        } else {
112
            append_download_link(el, file_spec.url, file_spec.filename);
113
            render_downloads(el, files);
114
        }
115
    }
116
    function append_download_link(el, url, text) {
117
        var p = $("<p>");
118
        $( '<a href="' + url + '" target="recordedbooks">' )
119
            .text(text)
120
            .appendTo(p);
121
        el.append(p);
122
    }
123
124
    function svc_ajax ( method, params, success_callback, callback_for_error_too ) {
125
        // remove when jquery is upgraded
126
        for (var key in params) {
127
            if (params[key] === null) delete params[key];
128
        }
129
        return $.ajax({
130
            method: method,
131
            dataType: "json",
132
            url: svc_url,
133
            data: params,
134
            success: function (data) {
135
                if (data.error && !callback_for_error_too) {
136
                    display_error(data.error);
137
                }
138
                success_callback(data);
139
            },
140
            error: function(jqXHR, textStatus, errorThrown) {
141
                if (callback_for_error_too) {
142
                    success_callback({error: errorThrown});
143
                    return;
144
                }
145
                display_error(errorThrown);
146
            }
147
        });
148
    }
149
150
    function load_account_details ( callback ) {
151
        svc_ajax('get', { action: "account" }, function(data) {
152
            details = data;
153
            callback(data);
154
        });
155
    }
156
157
    function item_action (params, el) {
158
        var isbn = params.isbn;
159
        svc_ajax('post', params, function(data) {
160
            if (data.checkouts) {
161
                details.checkouts = data.checkouts;
162
            }
163
            if (data.holds) {
164
                details.holds = data.holds;
165
            }
166
            display_actions(el, isbn);
167
        });
168
    }
169
170
    function item_is_checked_out (isbn) {
171
        if ( !(details && details.checkouts) ) {
172
            return null;
173
        }
174
        var isbn_uc = isbn.toUpperCase();
175
        var items = details.checkouts.items;
176
        for (var i = 0; i < items.length; i++) {
177
            if ( items[i].isbn.toUpperCase() == isbn_uc ) {
178
                return items[i];
179
            }
180
        }
181
        return null;
182
    }
183
184
    function item_is_on_hold (isbn) {
185
        if ( !(details && details.holds) ) {
186
            return false;
187
        }
188
        var isbn_uc = isbn.toUpperCase();
189
        var items = details.holds.items;
190
        for (var i = 0; i < items.length; i++) {
191
            if ( items[i].isbn.toUpperCase() == isbn_uc ) {
192
                return items[i];
193
            }
194
        }
195
        return null;
196
    }
197
198
    function display_actions(el, isbn) {
199
        $(el).empty();
200
        if (is_identified()) {
201
202
            var item = item_is_checked_out(isbn);
203
            if (item) {
204
                var expires = new Date(item.expires);
205
                $('<span class="recordedbooks-item-status">')
206
                    .text(_("Checked out until") + " " + expires.toLocaleString())
207
                    .appendTo(el);
208
                $(el).append(" ");
209
210
                if (item.url) {
211
                    var download = $('<a href="'+item.url+'">').appendTo(el);
212
                    decorate_button(download, _("Download"));
213
                    $(el).append(" ");
214
                }
215
216
                $(el).append( ajax_button(_("Check in"), function() {
217
                    if( confirm(_("Are you sure you want to return this item?")) ) {
218
                        item_action({action: "return", isbn: isbn}, el);
219
                    }
220
                }) );
221
222
                return item;
223
            }
224
225
            item = item_is_on_hold(isbn);
226
            if (item) {
227
                $('<span class="recordedbooks-status">')
228
                    .text(_("On hold"))
229
                    .appendTo(el);
230
                $(el).append(" ");
231
            }
232
233
            if(checkout_popup) {
234
                $(el).append( ajax_button(_("Check out"), function() {
235
                    if( confirm(_("Are you sure you want to checkout this item?")) ) {
236
                        svc_ajax('post', {action: "checkout", isbn: isbn}, function(data) {
237
                            if (data.checkouts) {
238
                                details.checkouts = data.checkouts;
239
                            }
240
                            if (data.holds) {
241
                                details.holds = data.holds;
242
                            }
243
                            item = display_actions(el, isbn);
244
                        });
245
                    }
246
                }) );
247
            }
248
            if (!item) {
249
                $(el).append( ajax_button(_("Place hold"), function() {
250
                    item_action({action: "place_hold", isbn: isbn}, el);
251
                }) );
252
            }
253
254
            if (item) {
255
                $(el).append( ajax_button(_("Cancel"), function() {
256
                    if( confirm(_("Are you sure you want to cancel this hold?")) ) {
257
                        item_action({action: "remove_hold", isbn: isbn}, el);
258
                    }
259
                }) );
260
            }
261
            return item;
262
        }
263
    }
264
265
    function ajax_button(label, on_click) {
266
        var button = $('<a href="#">')
267
            .click(function(e) {
268
                e.preventDefault();
269
                on_click();
270
            });
271
        decorate_button(button, label);
272
        return button;
273
    }
274
275
    function decorate_button(button, label) {
276
        $(button)
277
            .addClass("btn btn-primary btn-mini")
278
            .css("color","white")
279
            .text(label);
280
    }
281
282
    this.with_account_details = function( el, callback ) {
283
        $(el).append(error_div);
284
        load_account_details( callback );
285
    }
286
287
    this.display_account_details = function( el ) {
288
        $(el).empty().append(error_div);
289
        load_account_details(function(data) {
290
            display_account(el, data);
291
        });
292
    };
293
294
    this.display_error = function( el, error ) {
295
        $(el).empty().append(error_div);
296
        display_error(error);
297
    };
298
299
    this.is_identified = is_identified;
300
301
    this.add_actions = function(el, isbn) {
302
        var actions = $('<span class="actions">');
303
        display_actions(actions, isbn);
304
        $('<div id="action_'+isbn+'" class="actions-menu">')
305
            .append(actions)
306
            .appendTo(el);
307
    };
308
309
    this.search = function( q, page_size, page, callback ) {
310
        svc_ajax('get', { action: "search", q: q, page_size: page_size, page: page }, function (data) {
311
            var results;
312
            if (data.results) {
313
                results = data.results;
314
                if (!results.total) {
315
                    var total = results.items.length;
316
                    if ( total == results.page_size ) total = total + "+";
317
                    results.total = total;
318
                }
319
            }
320
            else results = {};
321
            results.error = data.error;
322
            callback(results);
323
        }, true);
324
    };
325
}
(-)a/koha-tmpl/opac-tmpl/bootstrap/less/opac.less (-1 / +1 lines)
Lines 2297-2303 td img { Link Here
2297
}
2297
}
2298
2298
2299
2299
2300
#overdrive-results, #openlibrary-results {
2300
#overdrive-results, #recordedbooks-results, #openlibrary-results {
2301
    font-weight: bold;
2301
    font-weight: bold;
2302
    padding-left: 1em;
2302
    padding-left: 1em;
2303
}
2303
}
(-)a/opac/opac-recordedbooks-search.pl (+42 lines)
Line 0 Link Here
1
#!/usr/bin/perl
2
3
# Copyright 2013 ByWater
4
#
5
# This file is part of Koha.
6
#
7
# Koha is free software; you can redistribute it and/or modify it
8
# under the terms of the GNU General Public License as published by
9
# the Free Software Foundation; either version 3 of the License, or
10
# (at your option) any later version.
11
#
12
# Koha is distributed in the hope that it will be useful, but
13
# WITHOUT ANY WARRANTY; without even the implied warranty of
14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
# GNU General Public License for more details.
16
#
17
# You should have received a copy of the GNU General Public License
18
# along with Koha; if not, see <http://www.gnu.org/licenses>.
19
20
use strict;
21
use warnings;
22
23
use CGI qw ( -utf8 );
24
25
use C4::Auth qw(:DEFAULT);
26
use C4::Output;
27
28
my $cgi = new CGI;
29
30
# Getting the template and auth
31
my ($template, $loggedinuser, $cookie)
32
= get_template_and_user({template_name => "opac-recordedbooks-search.tt",
33
                                query => $cgi,
34
                                type => "opac",
35
                                debug => 1,
36
                                authnotrequired => 1,
37
                                });
38
39
$template->{'VARS'}->{'q'} = $cgi->param('q');
40
$template->{'VARS'}->{'limit'} = C4::Context->preference('OPACnumSearchResults');
41
42
output_html_with_http_headers $cgi, $cookie, $template->output;
(-)a/opac/opac-search.pl (-3 / +6 lines)
Lines 985-993 $template->{VARS}->{IDreamBooksReviews} = C4::Context->preference('IDreamBooksRe Link Here
985
$template->{VARS}->{IDreamBooksReadometer} = C4::Context->preference('IDreamBooksReadometer');
985
$template->{VARS}->{IDreamBooksReadometer} = C4::Context->preference('IDreamBooksReadometer');
986
$template->{VARS}->{IDreamBooksResults} = C4::Context->preference('IDreamBooksResults');
986
$template->{VARS}->{IDreamBooksResults} = C4::Context->preference('IDreamBooksResults');
987
987
988
if ($offset == 0 && IsOverDriveEnabled()) {
988
if ($offset == 0) {
989
    $template->param(OverDriveEnabled => 1);
989
    if (IsOverDriveEnabled()) {
990
    $template->param(OverDriveLibraryID => C4::Context->preference('OverDriveLibraryID'));
990
        $template->param(OverDriveEnabled => 1);
991
        $template->param(OverDriveLibraryID => C4::Context->preference('OverDriveLibraryID'));
992
    }
993
    $template->param(RecordedBooksEnabled => C4::Context->preference( 'RecordedBooksClientSecret' ) && C4::Context->preference( 'RecordedBooksLibraryID' ));
991
}
994
}
992
995
993
    $template->param( borrowernumber    => $borrowernumber);
996
    $template->param( borrowernumber    => $borrowernumber);
(-)a/opac/opac-user.pl (+1 lines)
Lines 321-326 $template->param( Link Here
321
    OverDriveCirculation => C4::Context->preference('OverDriveCirculation') || 0,
321
    OverDriveCirculation => C4::Context->preference('OverDriveCirculation') || 0,
322
    overdrive_error      => scalar $query->param('overdrive_error') || undef,
322
    overdrive_error      => scalar $query->param('overdrive_error') || undef,
323
    overdrive_tab        => scalar $query->param('overdrive_tab') || 0,
323
    overdrive_tab        => scalar $query->param('overdrive_tab') || 0,
324
    RecordedBooksCirculation => C4::Context->preference('RecordedBooksClientSecret') && C4::Context->preference('RecordedBooksLibraryID'),
324
);
325
);
325
326
326
my $patron_messages = Koha::Patron::Messages->search(
327
my $patron_messages = Koha::Patron::Messages->search(
(-)a/opac/svc/recordedbooks (-1 / +148 lines)
Line 0 Link Here
0
- 
1
#!/usr/bin/perl
2
3
# Copyright 2016 Catalyst IT
4
# This file is part of Koha.
5
#
6
# Koha is free software; you can redistribute it and/or modify it
7
# under the terms of the GNU General Public License as published by
8
# the Free Software Foundation; either version 3 of the License, or
9
# (at your option) any later version.
10
#
11
# Koha is distributed in the hope that it will be useful, but
12
# WITHOUT ANY WARRANTY; without even the implied warranty of
13
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
# GNU General Public License for more details.
15
#
16
# You should have received a copy of the GNU General Public License
17
# along with Koha; if not, see <http://www.gnu.org/licenses>.
18
19
use Modern::Perl;
20
use CGI qw ( -utf8 );
21
use JSON qw(encode_json);
22
use C4::Auth qw(checkauth);
23
use C4::Output;
24
use Koha::Logger;
25
use Koha::ExternalContent::RecordedBooks;
26
27
our $cgi = new CGI;
28
my $logger = Koha::Logger->get({ interface => 'opac' });
29
my $page_url = $cgi->referer();
30
31
my ( $user, $cookie, $sessionID, $flags ) = checkauth( $cgi, 1, {}, 'opac' );
32
33
my $action = $cgi->param('action') or response_bad_request("No 'action' specified");
34
35
($user && $sessionID) || $action eq 'search' or response_bad_request("User not logged in");
36
37
local $@;
38
my $rb = eval { Koha::ExternalContent::RecordedBooks->new({ koha_session_id => $sessionID }) };
39
unless ($rb) {
40
    $logger->error($@) if $@;
41
    response({
42
        error => $@,
43
        is_identified => JSON::false,
44
    });
45
}
46
47
my $is_identified = $rb->is_identified;
48
my %data = (
49
    is_identified => $is_identified ? JSON::true : JSON::false,
50
);
51
response(\%data) unless $is_identified || $action eq 'search';
52
53
eval {
54
    {
55
        $action eq 'search' && do {
56
            my $query = $cgi->param('q');
57
            my $page  = $cgi->param('page');
58
            my $page_size = $cgi->param('page_size');
59
            my $sort = $cgi->param('sort');
60
            my $res = $rb->search({
61
                query => $query,
62
                page  => $page,
63
                page_size => $page_size,
64
                sort => $sort,
65
            });
66
            $data{results} = $res;
67
            last;
68
        };
69
70
        $action eq 'account' && do {
71
            eval {
72
                $data{account} = $rb->patron;
73
                $data{checkouts} = $rb->checkouts;
74
                $data{holds} = $rb->holds;
75
            };
76
            response_bad_request($rb->error_message($@)) if $@;
77
            last;
78
        };
79
80
        $action eq 'checkout' && do {
81
            my $isbn = $cgi->param('isbn')
82
              or response_bad_request("No 'isbn' specified");
83
            my $format = $cgi->param('format');
84
            $data{action} = eval {  $rb->checkout($isbn, $format) };
85
            response_bad_request($rb->error_message($@)) if $@;
86
87
            eval {
88
                $data{checkouts} = $rb->checkouts;
89
                $data{holds} = $rb->holds;
90
            };
91
            $data{error} = $rb->error_message($@) if $@;
92
            last;
93
        };
94
95
        $action eq 'return' && do {
96
            my $isbn = $cgi->param('isbn')
97
              or response_bad_request("No 'isbn' specified");
98
            $data{action} = eval { $rb->return($isbn) };
99
            response_bad_request($rb->error_message($@)) if $@;
100
101
            $data{checkouts} = eval { $rb->checkouts };
102
            $data{error} = $rb->error_message($@) if $@;
103
            last;
104
        };
105
106
        $action eq 'place_hold' && do {
107
            my $isbn = $cgi->param('isbn')
108
              or response_bad_request("No 'isbn' specified");
109
            $data{action} = eval { $rb->place_hold($isbn) };
110
            response_bad_request($rb->error_message($@)) if $@;
111
112
            $data{holds} = eval { $rb->holds };
113
            $data{error} = $rb->error_message($@) if $@;
114
            last;
115
        };
116
117
        $action eq 'remove_hold' && do {
118
            my $isbn = $cgi->param('isbn')
119
              or response_bad_request("No 'isbn' specified");
120
            $data{action} = eval { $rb->remove_hold($isbn) };
121
            response_bad_request($rb->error_message($@)) if $@;
122
123
            $data{holds} = eval { $rb->holds };
124
            $data{error} = $rb->error_message($@) if $@;
125
            last;
126
        };
127
128
        response_bad_request("Invalid 'action': $action");
129
    }
130
};
131
if ($@) {
132
    $logger->error($@);
133
    $data{error} = $rb->error_message("$@");
134
}
135
136
response(\%data);
137
138
139
sub response_bad_request {
140
    my ($error) = @_;
141
    response({error => $error}, "400 $error");
142
}
143
sub response {
144
    my ($data, $status_line) = @_;
145
    $status_line ||= "200 OK";
146
    output_with_http_headers $cgi, undef, encode_json($data), 'json', $status_line;
147
    exit;
148
}

Return to bug 17602