From 941af4d01c728d8518330c73feb8588852db1e65 Mon Sep 17 00:00:00 2001 From: Alex Arnaud <alex.arnaud@biblibre.com> Date: Wed, 12 Oct 2016 07:02:19 +0000 Subject: [PATCH] Bug 15565: Place multiple holds at once for the same record on staff and OPAC. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Test plan: 1. Create an circulation rule to use for testing the patches on this bug report. Ensure it has a value greater than 1 for 'Holds allowed', 'Holds per record (count)', and 'Item level holds' is enabled. 2. Also ensure the 'RequestOnOpac' syspref is set to 'Allow'. 3. Go to the reservation page (request.pl) of a biblio in the staff client with more than one item. 4. Notice beside each item a radio button is displayed preventing you from being able to select multiple items to place a hold on. 5. Go to the reservation page (opac-reserve.pl) of the same biblio in the OPAC also notice a radio button is displayed beside every item. 6. Apply patches 7. Repeat step 3 and 5 and notice in both the staff client and OPAC checkboxes rather than radio buttons are displayed beside each item so you can select multiple items for reservation at a time. 8. From staff interface, place several item-level holds for the same user on the same record at once: - check that you are warned if you exceed "Holds per record (count)" (circulation rules) for this record. - check also maxReserves system preference. 9. From opac, place several item-level and record level holds for the same user on the same record at once: - check that can't exceed "Holds per record (count)" for this record. This is enforced by all unticked item checkboxes being disabled after the number of ticked checkboxes equals the 'Holds per record (count)' (circulation rules) value. - check also maxReserves system preference. Do the same in OPAC and staff by selecting several record (multi-hold). Signed-off-by: Séverine QUEUNE <severine.queune@bulac.fr> Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com> Signed-off-by: Benjamin Rokseth <benjamin.rokseth@deichman.no> --- .../prog/en/modules/reserve/request.tt | 16 +- .../opac-tmpl/bootstrap/en/modules/opac-reserve.tt | 200 +- koha-tmpl/opac-tmpl/bootstrap/less/opac.less | 2644 ++++++++++++++++++++ opac/opac-reserve.pl | 166 +- reserve/placerequest.pl | 32 +- 5 files changed, 2852 insertions(+), 206 deletions(-) create mode 100644 koha-tmpl/opac-tmpl/bootstrap/less/opac.less diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/request.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/request.tt index 212c205..ab05306 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/request.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/request.tt @@ -14,6 +14,7 @@ [% END %] [% INCLUDE 'doc-head-close.inc' %] [% Asset.css("css/datatables.css") | $raw %] + </head> <body id="circ_request" class="catalog"> @@ -312,9 +313,9 @@ Hold must be record level </span> [% ELSIF ( itemloo.available ) %] - <input type="radio" name="checkitem" value="[% itemloo.itemnumber | html %]" /> + <input type="checkbox" name="checkitem" value="[% itemloo.itemnumber %]" /> [% ELSIF ( itemloo.override ) %] - <input type="radio" name="checkitem" class="needsoverride" value="[% itemloo.itemnumber | html %]" /> + <input type="checkbox" name="checkitem" class="needsoverride" value="[% itemloo.itemnumber %]" /> <i class="fa fa-exclamation-triangle fa-lg" style="color:gold" alt="Requires override of hold policy"/></i> [% ELSE %] <span class="error"> @@ -729,6 +730,8 @@ [% END %][% END %][% END %] }; var MSG_NO_ITEMS_AVAILABLE = _("A hold cannot be requested on any of these items."); + var MSG_EXCEEDED_HOLDS_PER_RECORD = _("Patron has exceeded the number of holds for this record."); + var remainingHolds = "[% remaining_holds_for_record %]"; $(document).ready(function() { function ToggleHoldsToPlace() { @@ -853,17 +856,20 @@ } }); $("input[name=checkitem]").click(function() { - onechecked = 0; + numchecked = 0; $("input[name=checkitem]").each(function() { if(this.checked){ - onechecked = 1; + numchecked = 1; } }); - if(onechecked == 1){ + if(numchecked == 1){ $("#requestany").prop("checked", false); } else { $("#requestany").prop("checked",true); } + if (remainingHolds - numchecked < 0) { + alert(MSG_EXCEEDED_HOLDS_PER_RECORD); + } }); var prev_rank_request; $("select[name=rank-request]").on("focus", function() { diff --git a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-reserve.tt b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-reserve.tt index ca7a4b3..4372454 100644 --- a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-reserve.tt +++ b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-reserve.tt @@ -145,20 +145,18 @@ <form action="/cgi-bin/koha/opac-reserve.pl" method="post" id="hold-request-form"> <input type="hidden" name="place_reserve" value="1"/> <!-- These values are set dynamically by js --> - <input type="hidden" name="biblionumbers" id="biblionumbers"/> - <input type="hidden" name="selecteditems" id="selections"/> <div id="bigloop"> [% FOREACH bibitemloo IN bibitemloop %] <div class="holdrow"> + <input id="remaining_holds_[% bibitemloo.biblionumber %]" type="hidden" value="[% bibitemloo.remaining_holds_for_record %]"/> <p> [% IF ( bibitemloo.holdable ) %] - <input class="reserve_mode" name="reserve_mode" type="hidden" value="single"/> - <input class="single_bib" name="single_bib" type="hidden" value="[% bibitemloo.biblionumber | html %]"/> - <span class="confirmjs_hold" title="[% bibitemloo.biblionumber | html %]" style="padding:.3em"></span> - <span class="confirm_nonjs"> - <input type="radio" class="confirmbox checkitem [% bibitemloo.biblionumber | html %]" name="[% bibitemloo.biblionumber | html %]" checked="checked" id="single_[% bibitemloo.biblionumber | html %]" value="any" /> - <label class="confirm_label" for="single_[% bibitemloo.biblionumber | html %]">Place a hold on </label> + <span title="[% bibitemloo.biblionumber %]" style="padding:.3em"> + <label> + <input class="biblionumbers" name="biblionumbers" type="checkbox" value="[% bibitemloo.biblionumber %]" checked="checked"> + Place a hold on + </label> </span> [% END # / bibitemloo.holdable %] @@ -225,7 +223,7 @@ <li class="branch"> <label for="branch_[% bibitemloo.biblionumber | html %]">Pick up location:</label> [% UNLESS ( bibitemloo.holdable ) %] - <select name="branch" id="branch_[% bibitemloo.biblionumber | html %]" disabled="disabled"> + <select name="branch_[% bibitemloo.biblionumber %]" id="branch_[% bibitemloo.biblionumber %]" disabled="disabled"> [% PROCESS options_for_libraries libraries => Branches.all( selected => branch ) %] </select> [% ELSE %] @@ -299,30 +297,40 @@ </li> [% END # / IF OpacHoldNotes %] - [% IF bibitemloo.itemholdable %] - <!-- ITEM HOLDS --> - <li class="lradio place_on_type" style="display:none;"> - [% IF NOT bibitemloo.force_hold %] - <label class="radio inline" for="reqany_[% bibitemloo.biblionumber | html %]">Next available item</label> - <input type="radio" name="reqtype_[% bibitemloo.biblionumber | html %]" - id="reqany_[% bibitemloo.biblionumber | html %]" - class="selectany" - value="Any" - checked="checked" - /> - [% END %] - <label class="radio inline" for="reqspecific_[% bibitemloo.biblionumber | html %]">A specific item</label> - <input type="radio" name="reqtype_[% bibitemloo.biblionumber | html %]" - id="reqspecific_[% bibitemloo.biblionumber | html %]" - class="selectspecific" - value="Specific" + <!-- ITEM HOLDS --> + <li class="lradio place_on_type" style="display:none;"> + <label class="radio inline" for="reqany_[% bibitemloo.biblionumber %]">Next available item</label> + <input type="radio" name="reqtype_[% bibitemloo.biblionumber %]" + id="reqany_[% bibitemloo.biblionumber %]" + class="selectany" + value="Any" + checked="checked" /> - </li> - [% END # / IF bibitemloo.itemholdable %] + <label class="radio inline" for="reqspecific_[% bibitemloo.biblionumber %]">A specific item</label> + <input type="radio" name="reqtype_[% bibitemloo.biblionumber %]" + id="reqspecific_[% bibitemloo.biblionumber %]" + class="selectspecific" + value="Specific" + /> + </li> </ul> - [% IF bibitemloo.itemholdable %] - <table class="copiesrow table table-bordered table-striped" id="copiesrow_[% bibitemloo.biblionumber | html %]"> + [% IF bibitemloo.remaining_holds_for_record > 1 %] + [% SET count = 1 %] + <div id="holds_to_place_[% bibitemloo.biblionumber %]" class="hold-options holds-to-place"> + <label>Holds to place (count)</label> + <select name="holds_to_place_count_[% bibitemloo.biblionumber %]"> + [% WHILE count <= bibitemloo.remaining_holds_for_record %] + <option value="[% count %]">[% count %]</option> + [% SET count = count + 1 %] + [% END %] + </select> + </div> + [% ELSE %] + <input type="hidden" name="holds_to_place_count_[% bibitemloo.biblionumber %]" value="1" /> + [% END %] + + <table class="copiesrow table table-bordered table-striped" id="copiesrow_[% bibitemloo.biblionumber %]"> <caption>Select a specific item:</caption> <tr> <th>Copy number</th> @@ -345,9 +353,9 @@ <tr class="[% itemLoo.backgroundcolor | html %]"> <td class="copynumber"> [% IF ( itemLoo.available ) %] - <input type="radio" class="checkitem checkitem_[% bibitemloo.biblionumber | html %]" name="checkitem_[% bibitemloo.biblionumber | html %]" value="[% itemLoo.itemnumber | html %]" /> + <input type="checkbox" class="checkitem checkitem_[% bibitemloo.biblionumber %]" name="checkitem_[% bibitemloo.biblionumber %]" value="[% itemLoo.itemnumber %]" /> [% ELSE %] - <input disabled="disabled" type="radio" class="checkitem" name="checkitem" value="[% itemLoo.itemnumber | html %]" + <input disabled="disabled" type="checkbox" class="checkitem" name="checkitem" value="[% itemLoo.itemnumber %]" style="display:none;" /> <img src="[% interface | html %]/lib/famfamfam/silk/cross.png" alt="Cannot be put on hold" title="Cannot be put on hold" /> [% END %] @@ -420,9 +428,8 @@ </td> </tr> [% END # / FOREACH itemLoo IN bibitemloo.itemLoop%] - </table> <!-- / #copiesrow_[% bibitemloo.biblionumber | html %] --> - [% END # / IF ( bibitemloo.itemholdable )%] - </div> <!-- / #hold-options-[% bibitemloo.biblionumber | html %] --> + </table> <!-- / #copiesrow_[% bibitemloo.biblionumber %] --> + </div> <!-- / #hold-options-[% bibitemloo.biblionumber %] --> </fieldset> [% END # / IF ( bibitemloo.holdable ) %] </div> <!-- / .holdrow --> @@ -444,6 +451,7 @@ <script> // <![CDATA[ var MSG_NO_ITEM_SELECTED = _("Expecting a specific item selection."); + var MSG_MAX_HOLDS_EXCEEDED = _("Maximum number of reserve exceded."); // Clear the contents of an input field $(".clearfield").on("click",function(e){ @@ -453,8 +461,8 @@ // Select the first item available function select_first_available(id){ - var radios = $("input:radio[name='checkitem_" + id + "']"); - $(radios).first().attr("checked", "checked"); + var checkboxes = $("input:checkbox[name='checkitem_" + id + "']"); + $(checkboxes).first().attr("checked", "checked"); } $(document).ready(function() { @@ -475,14 +483,16 @@ } }); - // click on a first td check the confirmjs checkbox - $("td.hold").click(function(e){ - if(e.target.tagName.toLowerCase() == 'td'){ - $(this).find("input.confirmjs").each( function() { - $(this).attr('checked', !$(this).attr('checked')); - $(this).change(); - }); - } + $('.checkitem').click(function(e) { + var bibNum = suffixOf($(this).attr("name"), "_"); + var nbCheked = $("input[name='checkitem_"+bibNum+"']:checked").length; + var remaining = $("input[id='remaining_holds_"+bibNum+"']").val(); + if (nbCheked >= remaining) { + $("input[name='checkitem_"+bibNum+"']:not(:checked)").attr('disabled', 'disabled'); + } + else { + $('.checkitem_'+bibNum).attr('disabled', false); + } }); $(".toggle-hold-options").on("click",function(e){ @@ -497,15 +507,24 @@ // Hides all 'specific copy' table rows on load. $(".copiesrow").hide(); + $(".holds-to-place").show(); [% FOREACH bibitemloo IN bibitemloop %] - [% IF bibitemloo.force_hold %] - $("#toggle-hold-options-[% bibitemloo.biblionumber | html %]").click(); - $("#reqspecific_[% bibitemloo.biblionumber | html %]").click(); - $("#copiesrow_[% bibitemloo.biblionumber | html %]").show(); - [% END %] - [% IF bibitemloo.reqholdnotes %] - $("#holdnotes_[% bibitemloo.biblionumber | html %]").attr( 'required', true ); - [% END %] + [% IF bibitemloo.force_hold %] + [% IF bibitemloo.force_hold == 'item' %] + $("#toggle-hold-options-[% bibitemloo.biblionumber %]").click(); + $("#reqspecific_[% bibitemloo.biblionumber %]").attr('checked', true); + $("#holds_to_place_[% bibitemloo.biblionumber %]").hide(); + $("#copiesrow_[% bibitemloo.biblionumber %]").show(); + [% ELSIF bibitemloo.force_hold == 'record' %] + $("#toggle-hold-options-[% bibitemloo.biblionumber %]").click(); + $("#reqany_[% bibitemloo.biblionumber %]").attr('checked', true); + [% END %] + $("#reqany_[% bibitemloo.biblionumber %]").attr('disabled', 'disabled'); + $("#reqspecific_[% bibitemloo.biblionumber %]").attr('disabled', 'disabled'); + [% END %] + [% IF bibitemloo.reqholdnotes %] + $("#holdnotes_[% bibitemloo.biblionumber %]").attr( 'required', true ); + [% END %] [% END %] $(".date-format").each(function(){ @@ -522,40 +541,37 @@ $("#" + op + fieldID).val(""); }); - // Replace non-JS single-selection with multi-selection capability. - $(".reserve_mode").val("multi"); - $(".confirm_nonjs").remove(); - $(".confirmjs_hold").each(function(){ - var bib = $(this).attr("title"); - var html = "<label><input type =\"checkbox\" class=\"confirmjs\" checked=\"checked\""; - html += "value=\"" + bib + "\" id=\"" + bib + "\" /> " + _("Place a hold on") + " </label> "; - $(this).html(html); - }); - $(".confirmjs_nohold").each(function(){ - var bib = $(this).attr("title"); - var html = "<label><input type =\"checkbox\" class=\"confirmjs\" disabled=\"disabled\""; - html += "value=\"" + bib + "\" id=\"" + bib + "\" />" + _("Place a hold on: ") + "</label>"; - $(this).html(html); - }); - // expand or collapse the copiesrow tr function toggle_copiesrow(biblioNum) { var checkbox = $("input:checkbox[value='"+biblioNum+"']"); newCopiesRowId = "#copiesrow_" + biblioNum; + holdsToPlaceCountId = "#holds_to_place_" + biblioNum; var select_specific = $("#reqspecific_"+biblioNum).is(":checked"); // If the checkbox is checked AND we want a specific item, we display the items block if ( $(checkbox).is(":checked") && select_specific ) { $(newCopiesRowId).show(); + $(holdsToPlaceCountId).hide(); } else { $(newCopiesRowId).hide(); + $(holdsToPlaceCountId).show(); } }; - $("#place_on_hdr").show(); + function total_requested() { + var total = 0; + $("input[name='biblionumbers']:checked").each(function() { + var biblioNum = $(this).val(); + if ($("#reqspecific_" + biblioNum + ":checked").size() > 0) { + total += parseInt($("input[name='checkitem_'"+biblioNum+"]:checked").length); + } else { + total += parseInt($("select[name='holds_to_place_count_"+biblioNum+"']").val()); + } + }); + return total; + } $(".place_on_type").show(); // onload, selectany is checked - $(".selectany").attr("checked", "checked"); // If the user is *allowed* to choose a specific item // The first one is preselected @@ -564,8 +580,8 @@ select_first_available(id); }); - // On confirmsjs change - $(".confirmjs").change(function(){ + // On biblionumbers change + $(".biblionumbers").change(function(){ var id = suffixOf($(this).attr("id"), "_"); // If I m checked, I enable radio buttons if ( $(this).is(":checked") ) { @@ -587,35 +603,22 @@ toggle_copiesrow(id); }); - // Show or hide holds notes - $(".shownotes").click(function(){ - biblioNum = suffixOf($(this).attr("id"), "_"); - $("#notesrow_"+biblioNum).toggle(); - }); - // When 'Place Hold' button is clicked $(".placehold").click(function(){ - var biblionumbers = ""; - var selections = ""; - - [% IF new_reserves_allowed %] - if ($(".confirmjs:checked").size() > [% new_reserves_allowed | html %] ) { - alert(MSG_MAX_HOLDS_EXCEEDED); - return false; - } - [% END %] + if (total_requested() + [% reserves_count %] > [% maxreserves %]) { + alert(MSG_MAX_HOLDS_EXCEEDED); + return false; + } - if ($(".confirmjs:checked").size() == 0) { + if ($("input[name='biblionumbers']:checked").size() == 0) { alert(MSG_NO_RECORD_SELECTED); return false; } // Find the items with the 'Hold' box checked var badBib = null; - $(".confirmjs:checked").each(function() { + $("input[name='biblionumbers']:checked").each(function() { var biblioNum = $(this).val(); - biblionumbers += biblioNum + "/"; - selections += biblioNum + "/"; // If required hold note is empty, make it visible if( $("#holdnotes_"+biblioNum).attr( 'required' ) && $("#holdnotes_"+biblioNum).val() == '' ) { @@ -632,18 +635,8 @@ alert(MSG_NO_ITEM_SELECTED); badBib = biblioNum; return false; - } else { - selections += $(item).val(); } } - selections += "/"; - - // Add the pickup location - var branchSel = $("#branch_" + biblioNum); - if (branchSel.size() > 0) { - selections += $(branchSel).val(); - } - selections += "/"; return true; }); @@ -651,9 +644,6 @@ return false; } - $("#selections").val(selections); - $("#biblionumbers").val(biblionumbers); - return true; }); diff --git a/koha-tmpl/opac-tmpl/bootstrap/less/opac.less b/koha-tmpl/opac-tmpl/bootstrap/less/opac.less new file mode 100644 index 0000000..40e0e91 --- /dev/null +++ b/koha-tmpl/opac-tmpl/bootstrap/less/opac.less @@ -0,0 +1,2644 @@ +@import "mixins.less"; +body { + background-color: #EAEAE6; +} + + /* Sticky footer styles */ +html, +body { + height: 100%; + /* The html and body elements cannot have any padding or margin. */ +} + +.no-js { + .dateformat { + display: inline; + white-space: nowrap; + } + .modal-body { + padding: 0; + } + .selections-toolbar { + display: none; + } +} + +.js { + .dateformat { + display: none; + } +} + +/* Wrapper for page content to push down footer */ +#wrap { + min-height: 100%; + height: auto !important; + height: 100%; + /* Negative indent footer by it's height */ + // margin: 0 auto -60px; +} + +/* Set the fixed height of the footer here */ +#changelanguage { + // height: 60px; +} + +.popup { + padding-left : 0; + padding-right: 0; +} + +a { + color: @links; + &.cancel { + padding-left : 1em; + } + &:visited { + color: @links; + } + &.title { + font-weight: bold; + font-size : 108%; + } + &.btn { + &:visited { + color : #333; + } + } + &.btn-primary { + &:visited { + color : #FFF; + } + } + &.login-link { + color: #A6D8ED; + font-weight: bold; + } +} + +.ui-widget-content a, +.ui-widget-content a:visited { + color: @links; +} + +h1 { + font-size : 140%; + line-height: 150%; + &#libraryname { + background: transparent url(../images/logo-koha.png) no-repeat scroll 0%; + border: 0; + float: left !important; + margin: 0; + padding: 0; + width: 120px; + a { + border: 0; + cursor: pointer; + display: block; + height: 0px !important; + margin: 0; + overflow: hidden; + padding: 40px 0 0; + text-decoration: none; + width: 120px; + } + } +} + +h2 { + + font-size : 130%; + line-height: 150%; +} +h3 { + + font-size : 120%; + line-height: 150%; +} +h4 { + + font-size : 110%; +} +h5 { + + font-size : 100%; +} + +caption { + font-size: 120%; + font-weight: bold; + margin : 0; + text-align: left; +} + +input, +textarea { + width: auto; +} + +.input-fluid { + width : 50%; +} + +legend { + font-size: 110%; + font-weight: bold; +} + +table, td { + background-color: #FFF; +} + +td { + .btn { + white-space: nowrap; + } + .btn-link { + padding: 0; + } +} + +#advsearches, +#booleansearch { + label { + display: inline; + } +} + +#basketcount { + display : inline; + margin : 0; + padding : 0; + span { + background-color : #FFC; + color : #000; + display : inline; + font-size : 80%; + font-weight : normal; + margin : 0 0 0 .9em; + padding : 0 .3em 0 .3em; + .border-radius-all(3px); + } +} + + +#members { + display: block; + p { + color : #EEE; + } + a { + &.logout { + color : #E8583C; + font-weight: bold; + padding : 0 .3em 0 .3em; + } + } +} + +#koha_url p { + color: #666666; + float : right; + margin: 0; +} + +#moresearches { + margin: .5em 0; + padding: 0 .8em; + li { + display: inline; + white-space: nowrap; + &:after { + content : " | "; + } + + } + ul { + margin : 0; + } +} + +#moresearches li:last-child:after { + content : ""; +} + +#news { + margin : .5em 0; +} + +.newscontainer { + border: 1px solid #ddd; + border-bottom-width: 0; + border-top-left-radius: 5px; + border-top-right-radius: 5px; +} + +.newsheader { + background-color: #ecede6; + border-bottom: 1px solid #ddd; + margin: 0; + padding: 8px; +} + +.newsbody { + padding: 8px; +} + +.newsfooter { + border-bottom: 1px solid #ddd; + font-style: italic; + padding: 4px 8px; +} + +#opacheader { + background-color: #DDD; +} + +#selections, +.selections { + font-weight : bold; +} + +.actions { + a { + white-space: nowrap; + &.hold { + background-image : url("../images/sprite.png"); /* Place hold small */ + background-position : -5px -542px; + background-repeat: no-repeat; + margin-right : 1em; + padding-left : 21px; + text-decoration : none; + } + &.article_request { + background-image : url("../images/sprite.png"); /* Place hold small */ + background-position : -2px -26px; + background-repeat: no-repeat; + margin-right : 1em; + padding-left : 21px; + text-decoration : none; + } + &.addtocart { + background-image : url("../images/sprite.png"); /* Cart small */ + background-position : -5px -572px; + background-repeat: no-repeat; + margin-right : 1em; + padding-left : 20px; + text-decoration : none; + } + &.addtoshelf { + background-image : url("../images/sprite.png"); /* MARC view */ + background-position: -5px -27px; + background-repeat: no-repeat; + margin-right : 1em; + padding-left : 20px; + text-decoration : none; + } + &.addtolist { + background-position: -5px -27px; + margin-right : 1em; + padding-left : 20px; + text-decoration : none; + } + &.tag_add { + background-position: -5px -1110px; + margin-right : 1em; + padding-left : 20px; + text-decoration : none; + } + /* List contents remove from list link */ + &.removefromlist { + background-position : -8px -690px; /* Delete */ + margin-right : 1em; + text-decoration : none; + padding-left : 15px; + } + } +} + +/* Override Bootstrap alert */ +.alert { + background: #fffbe5; /* Old browsers */ + background: -moz-linear-gradient(top, #fffbe5 0%, #fff0b2 9%, #fff1a8 89%, #f7e665 100%); /* FF3.6+ */ + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#fffbe5), color-stop(9%,#fff0b2), color-stop(89%,#fff1a8), color-stop(100%,#f7e665)); /* Chrome,Safari4+ */ + background: -webkit-linear-gradient(top, #fffbe5 0%,#fff0b2 9%,#fff1a8 89%,#f7e665 100%); /* Chrome10+,Safari5.1+ */ + background: -o-linear-gradient(top, #fffbe5 0%,#fff0b2 9%,#fff1a8 89%,#f7e665 100%); /* Opera 11.10+ */ + background: -ms-linear-gradient(top, #fffbe5 0%,#fff0b2 9%,#fff1a8 89%,#f7e665 100%); /* IE10+ */ + background: linear-gradient(to bottom, #fffbe5 0%,#fff0b2 9%,#fff1a8 89%,#f7e665 100%); /* W3C */ + filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#fffbe5', endColorstr='#f7e665',GradientType=0 ); /* IE6-9 */ + border-color : #D6C43B; + color: #333; +} + +/* Override Bootstrap alert.alert-info */ +.alert-info { + background: #f4f6fa; /* Old browsers */ + background: -moz-linear-gradient(top, #f4f6fa 0%, #eaeef5 4%, #e8edf6 96%, #cddbf2 100%); /* FF3.6+ */ + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#f4f6fa), color-stop(4%,#eaeef5), color-stop(96%,#e8edf6), color-stop(100%,#cddbf2)); /* Chrome,Safari4+ */ + background: -webkit-linear-gradient(top, #f4f6fa 0%,#eaeef5 4%,#e8edf6 96%,#cddbf2 100%); /* Chrome10+,Safari5.1+ */ + background: -o-linear-gradient(top, #f4f6fa 0%,#eaeef5 4%,#e8edf6 96%,#cddbf2 100%); /* Opera 11.10+ */ + background: -ms-linear-gradient(top, #f4f6fa 0%,#eaeef5 4%,#e8edf6 96%,#cddbf2 100%); /* IE10+ */ + background: linear-gradient(to bottom, #f4f6fa 0%,#eaeef5 4%,#e8edf6 96%,#cddbf2 100%); /* W3C */ + filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f4f6fa', endColorstr='#cddbf2',GradientType=0 ); /* IE6-9 */ + border-color : #C5D1E5; + color: #333; +} + +/* Override Bootstrap alert.alert-success */ +.alert-success { + background: #f8ffe8; /* Old browsers */ + background: -moz-linear-gradient(top, #f8ffe8 0%, #e3f5ab 4%, #dcf48d 98%, #9ebf28 100%); /* FF3.6+ */ + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#f8ffe8), color-stop(4%,#e3f5ab), color-stop(98%,#dcf48d), color-stop(100%,#9ebf28)); /* Chrome,Safari4+ */ + background: -webkit-linear-gradient(top, #f8ffe8 0%,#e3f5ab 4%,#dcf48d 98%,#9ebf28 100%); /* Chrome10+,Safari5.1+ */ + background: -o-linear-gradient(top, #f8ffe8 0%,#e3f5ab 4%,#dcf48d 98%,#9ebf28 100%); /* Opera 11.10+ */ + background: -ms-linear-gradient(top, #f8ffe8 0%,#e3f5ab 4%,#dcf48d 98%,#9ebf28 100%); /* IE10+ */ + background: linear-gradient(to bottom, #f8ffe8 0%,#e3f5ab 4%,#dcf48d 98%,#9ebf28 100%); /* W3C */ + filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f8ffe8', endColorstr='#9ebf28',GradientType=0 ); /* IE6-9 */ + border-color : #9FBA35; + color: #333; +} + +.breadcrumb { + background-color: #F2F2EF; + font-size: 85%; + list-style: none outside none; + margin: 10px 20px; + padding: 5px 10px; + .border-radius-all(7px); +} + +.form-inline { + display : inline; + padding: 0; + margin: 0; + fieldset { + margin: 0.3em 0; + padding: 0.3em; + } +} + +.main { + background-color: #FFF; + border: 1px solid #D2D2CF; + .border-radius-all(7px); + .shadowed; + margin-top : 0.5em; + margin-bottom: 0.5em; +} + +.mastheadsearch { + .border-radius-all(7px); + padding: .8em; + margin: .5em 0; + background: #c7c7c1; + /* Old browsers */ + background: -moz-linear-gradient(top, #c7c7c1 38%, #a7a7a2 100%); + /* FF3.6+ */ + background: -webkit-gradient(linear, left top, left bottom, color-stop(38%,#c7c7c1), color-stop(100%,#a7a7a2)); + /* Chrome,Safari4+ */ + background: -webkit-linear-gradient(top, #c7c7c1 38%,#a7a7a2 100%); + /* Chrome10+,Safari5.1+ */ + background: -o-linear-gradient(top, #c7c7c1 38%,#a7a7a2 100%); + /* Opera 11.10+ */ + background: -ms-linear-gradient(top, #c7c7c1 38%,#a7a7a2 100%); + /* IE10+ */ + background: linear-gradient(to bottom, #c7c7c1 38%,#a7a7a2 100%); + /* W3C */ + filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#c7c7c1', endColorstr='#a7a7a2',GradientType=0 ); + /* IE6-9 */ + label { + font-size: 115%; + font-weight: bold; + } +} + +.navbar-inverse .brand, .navbar-inverse .nav > li > a { + color: #9FE1FF; + font-weight: bold; +} + +.navbar-fixed-bottom.navbar-static-bottom { + margin-top : .5em; + position: static; +} + +#changelanguage .nav > .active > p { + padding : 0 15px; +} + +.table-striped tbody > tr:nth-child(odd) > td, +.table-striped tbody > tr:nth-child(odd) > th { + background-color: #F4F4F4; +} + + +/* jQuery UI standard tabs */ +.ui-tabs-nav .ui-tabs-active a, +.ui-tabs-nav a:hover, +.ui-tabs-nav a:focus, +.ui-tabs-nav a:active, +.ui-tabs-nav span.a { + background: none repeat scroll 0 0 transparent; + outline: 0 none; +} + +.ui-widget, +.ui-widget input, +.ui-widget select, +.ui-widget textarea, +.ui-widget button { + font-family : inherit; + font-size : inherit; +} + +ul.ui-tabs-nav li { + list-style : none; +} +.ui-tabs.ui-widget-content { + background : transparent none; + border : 0; +} + +.ui-tabs .ui-tabs-panel { + border : 1px solid #D8D8D8; + margin-bottom: 1em; +} +.ui-tabs-nav.ui-widget-header { + border : 0; + background : none; +} +.ui-tabs .ui-tabs-nav li { + background: #F3F3F3 none; + border-color: #D8D8D8; + margin-right : .4em; +} + +.ui-tabs .ui-tabs-nav li.ui-tabs-active { + background-color : #FFF; + border : 1px solid #D8D8D8; + border-bottom: 0; +} +.ui-tabs .ui-tabs-nav li.ui-tabs-active a { + color : #000; + font-weight : bold; +} + +.ui-tabs .ui-tabs-nav li.ui-state-default.ui-state-hover { + background : #F3F3F3 none; +} + +.ui-tabs .ui-tabs-nav li.ui-tabs-active.ui-state-hover { + background : #FFF none; +} + +.ui-tabs .ui-state-default a, +.ui-tabs .ui-state-default a:link, +.ui-tabs .ui-state-default a:visited { + color: #006699; +} + +.ui-tabs .ui-state-hover a, +.ui-tabs .ui-state-hover a:link, +.ui-tabs .ui-state-hover a:visited { + color: #990033; +} + +.statictabs { + ul { + background: none repeat scroll 0 0 transparent; + border: 0 none; + margin: 0; + padding: 0.2em 0.2em 0; + border-bottom-right-radius: 4px; + border-bottom-left-radius: 4px; + border-top-right-radius: 4px; + border-top-left-radius: 4px; + color: #222222; + font-weight: bold; + font-size: 100%; + line-height: 1.3; + list-style: none outside none; + outline: 0 none; + text-decoration: none; + &:before { + content: ""; + display: table; + } + &:after { + clear: both; + content: ""; + display: table; + } + } + li { + background: none repeat scroll 0 0 #E6F0F2; + border: 1px solid #B9D8D9; + border-bottom: 0 none !important; + border-top-right-radius: 4px; + border-top-left-radius: 4px; + float: left; + list-style: none outside none; + margin-bottom: 0; + margin-right: 0.4em; + padding: 0; + position: relative; + white-space: nowrap; + top: 1px; + color: #555555; + font-weight: normal; + &.active { + background-color: #FFFFFF; + color: #212121; + font-weight: normal; + padding-bottom: 1px; + } + a { + color: #004D99; + cursor: pointer; + float: left; + padding: 0.5em 1em; + text-decoration: none; + &:hover { + background-color : #EDF4F5; + border-top-right-radius: 4px; + border-top-left-radius: 4px; + color : #538200; + } + } + &.active { + a { + color: #000000; + font-weight: bold; + cursor: text; + background: none repeat scroll 0 0 transparent; + outline: 0 none; + } + } + } + .tabs-container { + border: 1px solid #B9D8D9; + background: none repeat scroll 0 0 transparent; + display: block; + padding: 1em 1.4em; + border-bottom-right-radius: 4px; + border-bottom-left-radius: 4px; + color: #222222; + } +} + +/* End jQueryUI tab styles */ + +/* jQuery UI Datepicker */ +.ui-datepicker table {width: 100%; font-size: .9em; border : 0; border-collapse: collapse; margin:0 0 .4em; } +.ui-datepicker th { background : transparent none; padding: .7em .3em; text-align: center; font-weight: bold; border: 0; } + +.ui-datepicker-trigger { + vertical-align: middle; + margin : 0 3px; +} +.ui-datepicker { + .shadowed; +} +/* End jQueryUI datepicker styles */ + + +/* jQueryUI Core */ + +.ui-widget-content { + border: 1px solid #AAA; + background: #ffffff none; + color: #222222; +} +.ui-widget-header { + border: 1px solid #AAA; + background: #E6F0F2 none; + color: #222222; + font-weight: bold; +} +.ui-state-default, +.ui-widget-content .ui-state-default, +.ui-widget-header .ui-state-default { + border: 1px solid #AAA; + background: #F4F8F9 none; + font-weight: normal; + color: #555555; +} +.ui-state-hover, +.ui-widget-content .ui-state-hover, +.ui-widget-header .ui-state-hover, +.ui-state-focus, +.ui-widget-content .ui-state-focus, +.ui-widget-header .ui-state-focus { + border: 1px solid #AAA; + background: #E6F0F2 none; + font-weight: normal; + color: #212121; +} +.ui-state-active, +.ui-widget-content .ui-state-active, +.ui-widget-header .ui-state-active { + border: 1px solid #aaaaaa; + background: #ffffff none; + font-weight: normal; + color: #212121; +} +.ui-state-highlight, +.ui-widget-content .ui-state-highlight, +.ui-widget-header .ui-state-highlight {border: 1px solid #fcefa1; + background: #fbf9ee; + color: #363636; +} +.ui-state-error, +.ui-widget-content .ui-state-error, +.ui-widget-header .ui-state-error {border: 1px solid #cd0a0a; + background: #fef1ec; + color: #cd0a0a; +} + +/* end jQueryUI core */ + +/* jQueryUI autocomplete */ + +.ui-autocomplete { + position: absolute; + cursor: default; + .shadowed; +} +.ui-autocomplete.ui-widget-content .ui-state-hover { + border: 1px solid #AAA; + background: #E6F0F2 none; + font-weight: normal; + color: #212121; +} +.ui-autocomplete-loading { + background: #FFF url("../../img/loading-small.gif") right center no-repeat; +} +.ui-menu li { + list-style:none; +} + +/* end jQueryUI autocomplete */ + + + +th { + background-color: #ECEDE6; +} + +.item-thumbnail { + max-width: none; +} + +.no-image { + background-color : #FFF; + border: 1px solid #AAA; + color : #979797; + display:block; + font-size : 86%; + font-weight : bold; + text-align : center; + width : 75px; + .border-radius-all(3px); +} + +#bookcover .no-image { + margin-right : 10px; + margin-bottom : 10px; +} + +td.overdue { + color : #cc3333; +} +table { + font-size: 90%; +} +th.sum { + text-align: right; +} + +td.sum { + background-color: #FFC; + font-weight: bold; +} + +th[scope=row] { + background-color: transparent; + text-align : right; +} + +.required { + color : #C00; +} + +.label { + background-color: transparent; + color: inherit; + display: inline; + font-weight: normal; + padding : 0; + text-shadow: none; +} + +.blabel { + background-color: #999999; + border-radius: 3px; + color: #ffffff; + display: inline-block; + font-weight: bold; + padding: 2px 4px; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); +} + +.label-important { + background-color: #b94a48; +} +.label-warning { + background-color: #f89406; +} +.label-success { + background-color: #468847; +} +.label-info { + background-color: #3a87ad; +} +.label-inverse { + background-color: #333333; +} + +fieldset { + &.rows { + float : left; + font-size : 90%; + clear : left; + margin: .9em 0 0 0; + padding: 0; + width: 100%; + legend { + font-weight: bold; + font-size : 130%; + } + label, + .label { + float: left; + font-weight : bold; + width: 9em; + margin-right: 1em; + text-align: right; + } + label { + &.lradio { + float: none; + margin: inherit; + width: auto; + } + } + fieldset { + margin : 0; + padding : .3em; + } + ol { + padding: 1em 1em 0 1em; + list-style-type: none; + &.lradio { + label { + width : auto; + float : none; + margin-right : 0; + &.lradio { + float : left; + width : 12em; + margin-right : 1em; + } + } + } + } + li { + float : left; + clear : left; + padding-bottom: 1em; + list-style-type: none; + width: 100%; + &.lradio { + padding-left: 8.5em; + width : auto; + label { + float : none; + width : auto; + margin : 0 0 0 1em; + } + } + } + .hint { + display: block; + margin-left : 11em; + } + } + &.action { + clear : both; + float : none; + border : none; + margin : 0; + padding : 1em 0 .3em 0; + width : auto; + p { + margin-bottom : 1em; + } + } + table { + font-size: 100%; + } +} + +div.rows+div.rows { + margin-top : .6em; +} + +div.rows { + float : left; + clear : left; + margin: 0 0 0 0; + padding: 0; + width: 100%; + span.label { + float: left; + font-weight : bold; + width: 9em; + margin-right: 1em; + text-align: left; + } + ol { + list-style-type: none; + margin-left : 0; + padding: .5em 1em 0 0; + } + li { + border-bottom : 1px solid #EEE; + float : left; + clear : left; + padding-bottom: .2em; + padding-top: .1em; + list-style-type: none; + width: 100%; + } + ul { + li { + margin-left : 7.3em; + &:first-child { + float: none; + clear: none; + margin-left: 0; + } + } + } + ol li li { + border-bottom: 0; + } +} + +/* different sizes for different tags in opac-tags.tt */ +.tagweight0 { + font-size: 12px; +} + +.tagweight1 { + font-size: 14px; +} + +.tagweight2 { + font-size: 16px; +} + +.tagweight3 { + font-size: 18px; +} + +.tagweight4 { + font-size: 20px; +} + +.tagweight5 { + font-size: 22px; +} + +.tagweight6 { + font-size: 24px; +} + +.tagweight7 { + font-size: 26px; +} + +.tagweight8 { + font-size: 28px; +} + +.tagweight9 { + font-size: 30px; +} + +.toolbar { + background-color : #EEEEEE; + border : 1px solid #E8E8E8; + font-size : 85%; + padding:3px 3px 5px 5px; + vertical-align : middle; + a { + white-space: nowrap; + } + label { + display: inline; + font-size: 100%; + font-weight : bold; + margin-left : .5em; + } + select { + font-size: 97%; + height: auto; + line-height: inherit; + padding: 0; + margin: 0; + width : auto; + white-space: nowrap; + } + .hold, + #tagsel_tag { + padding-left: 28px; + font-size: 97%; + font-weight: bold; + } + #tagsel_form { + margin-top : .5em; + } + li { + display : inline; + list-style : none; + a { + border-left : 1px solid #e8e8e8; + } + &:first-child { + a { + border-left : 0; + } + } + } + ul { + padding-left : 0; + } +} + +#basket .toolbar { + padding: 7px 5px 9px 9px; +} + +#selections-toolbar, +.selections-toolbar { + background: -moz-linear-gradient(top, #b2b2b2 0%, #e0e0e0 14%, #e8e8e8 100%); /* FF3.6+ */ + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#b2b2b2), color-stop(14%,#e0e0e0), color-stop(100%,#e8e8e8)); /* Chrome,Safari4+ */ + background: -webkit-linear-gradient(top, #b2b2b2 0%,#e0e0e0 14%,#e8e8e8 100%); /* Chrome10+,Safari5.1+ */ + background: -o-linear-gradient(top, #b2b2b2 0%,#e0e0e0 14%,#e8e8e8 100%); /* Opera 11.10+ */ + background: -ms-linear-gradient(top, #b2b2b2 0%,#e0e0e0 14%,#e8e8e8 100%); /* IE10+ */ + background: linear-gradient(top, #b2b2b2 0%,#e0e0e0 14%,#e8e8e8 100%); /* W3C */ + filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#e0e0e0', endColorstr='#e8e8e8',GradientType=0 ); /* IE6-9 */ + margin : 0 0 1em 0; + padding-top : .5em; + padding-left : 10px; +} + +.list-actions { + display : inline; +} + +#tagsel_span input.submit, +#tagsel_tag { + border : 0; + background-color: transparent; + font-size : 100%; + color: #0076B2; + cursor : pointer; + background-image : url("../images/sprite.png"); /* Tags */ + background-position : 1px -643px; + background-repeat : no-repeat; + padding-left : 25px; + text-decoration: none; +} + +#tagsel_tag.disabled { + background-position : -1px -667px; +} + + +#tagsel_span input:hover, +#selections-toolbar input.hold:hover { + color: #005580; + text-decoration: underline; +} + +#tagsel_span input.disabled, +#tagsel_span input.disabled:hover, +#tagsel_span input.hold.disabled, +#tagsel_span input.hold.disabled:hover, +#selections-toolbar input.hold.disabled, +#selections-toolbar input.hold.disabled:hover, +#selections-toolbar a.disabled, +#selections-toolbar a.disabled:hover, +.selections-toolbar a.disabled, +.selections-toolbar a.disabled:hover { + color: #888888; + text-decoration: none; + padding-left : 23px; +} + +.results_summary { + display: block; + font-size : 85%; + color: #707070; + padding : 0 0 .5em 0; + .results_summary { + font-size : 100%; + } + &.actions { + margin-top : .5em; + } + &.tagstatus { + display: inline; + } + .label { + color: #202020; + } + a { + font-weight: normal; + } +} + +#views { + margin-bottom : .5em; + padding : 0 2em 0.2em 0.2em; +} + +.view { + background-color : #F3F3F3; + border: 1px solid #C9C9C9; + border-radius: 4px; + display: inline-block; + padding: 0.2em 0.5em; + white-space: nowrap; +} + +#bibliodescriptions, +#isbdcontents { + clear : left; + margin-top : .5em; +} + +.view { + a, + span { + background-image: url("../images/sprite.png"); + background-repeat : no-repeat; + font-size : 87%; + padding-left: 15px; + text-decoration: none; + } +} + +.view { + a { + font-weight : normal; + } +} + +.current-view { + background-color: #fff; + font-weight: bold; +} + +#MARCview { + background-position: -9px -27px; +} +#ISBDview { + background-position: -10px -56px; +} +#Normalview { + background-position: -8px 3px; +} + +#bookcover { + float : left; + margin : 0; + padding : 0; + .no-image { + margin-right : 10px; + margin-bottom : 10px; + } + img { + margin : 0 1em 1em 0; + } +} + +/* pagination */ +.results-pagination { + position: absolute; + top:32px; + left: -1px; + width: 100%; + height:auto; + border: 1px solid #D0D0D0; + display: none; + background-color:#F3F3F3; + padding-bottom:10px; + z-index: 100; +} + + +.back { + float:right; + input { + background:none!important; + color:#999!important; + } +} + +.pagination_list { + ul { + padding-top: 40px; + padding-left:0px; + } + li { + list-style:none; + float:bottom; + padding:4px; + color:#999; + &.highlight { + background-color : #F3F3F3; + border-top : 1px solid #DDDDDD; + border-bottom : 1px solid #DDDDDD; + } + a { + padding-left:0px; + } + } + .li_pag_index { + color: #999999; + float: left; + font-size: 15px; + font-weight: bold; + padding-right: 10px; + text-align: right; + width: 13px; + } +} + +.nav_results { + background-color: #F3F3F3; + border: 1px solid #D0D0D0; + font-size: 95%; + font-weight: bold; + margin-top: 0.5em; + position:relative; + .l_Results { + a { + background:#E1E1E1 url("../images/sprite.png") no-repeat 0px -504px; /* Browse results menu */ + color:#006699; + display:block; + padding:8px 28px; + text-decoration:none; + } + &:hover { + background-color:#D9D9D9; + } + } +} + +.pg_menu { + margin: 0; + border-top: 1px solid #D0D0D0; + white-space : nowrap; + li { + color:#B2B2B2; + display:inline; + list-style:none; + margin: 0; + &.back_results { + a { + border-left: 1px solid #D0D0D0; + border-right: 1px solid #D0D0D0; + } + } + a, + span { + background-color: #F3F3F3; + display : block; + float:left; + padding:.4em .5em; + text-decoration:none; + font-weight:normal; + text-align:center; + } + span { + color : #B2B2B2; + } + } +} + +#listResults{ + li { + background-color:#999999; + color:#C5C5C5; + font-weight:normal; + display:block; + margin-right:1px; + font-size: 80%; + padding: 0; + text-align:center; + min-width:18px; + &:hover { + background-color:#006699; + } + a { + color:#FFFFFF; + font-weight:normal; + } + } +} + +/* nav */ +.nav_pages { + .close_pagination { + padding-right: 10px; + position: absolute; + right: 3px; + top: -25px; + } + .close_pagination a { + text-decoration:none!important; + } + ul { + padding-top: 10px; + } + li { + list-style:none; + float:left; + padding:4px; + color:#999; + a { + text-decoration:none!important; + &:hover { + text-decoration:underline; + } + } + ul { + float:left; + } + } +} + +/* action buttons */ +#action { + margin : .5em 0 0 0; + background-color : #F3F3F3; + border : 1px solid #E8E8E8; + padding-bottom : 3px; + li { + list-style : none; + margin : .2em; + padding : .3em 0; + } + a { + font-weight: bold; + text-decoration : none; + } +} + +#export, +#moresearches_menu { + li { + padding : 0; + margin : 0; + a { + font-weight: normal; + &.menu-inactive { + font-weight: bold; + } + } + } +} + +#format, +#furthersearches { + padding-left : 35px; +} +.highlight_controls { + float: left; +} +a.addtocart, +a.addtoshelf, +a.brief, +a.deleteshelf, +a.deleteshelf.disabled, +a.detail, +a.download, +a.editshelf, +a.empty, +a.hide, +a.highlight_toggle, +a.hold, +a.hold.disabled, +a.incart, +a.new, +a.print-small, +a.print-large, +a.removeitems, +a.removeitems.disabled, +a.reserve, +a.article_request, +a.send, +a.tag_add, +a.removefromlist, +input.hold, +input.hold.disabled, +input.editshelf, +.newshelf, +.newshelf.disabled, +.deleteshelf { + background-image: url("../images/sprite.png"); + background-repeat: no-repeat; +} + + +a.addtocart { + background-position: -5px -265px; /* Cart */ + padding-left : 35px; +} + +a.addtoshelf { + background-position: -5px -225px; /* Virtual shelf */ + padding-left : 35px; +} + +a.brief { + + background-position : -2px -868px; /* Zoom out */ + text-decoration : none; + padding-left : 27px; +} + +a.cartRemove { + color: #cc3333; + font-size : 90%; + margin : 0; + padding: 0; +} + +a.detail { + background-position : -2px -898px; /* Zoom in */ + text-decoration : none; + padding-left : 27px; +} + +a.download { + background-position : -5px -348px; /* Download */ + padding-left : 20px; + text-decoration : none; +} + +a.editshelf { + background-position : 2px -348px; /* List edit */ + padding-left : 26px; + text-decoration : none; +} + +a.empty { + background-position : 2px -598px; /* Trash */ + text-decoration : none; + padding-left : 30px; +} + +a.hide { + background-position: -3px -814px; /* Close */ + text-decoration : none; + padding-left : 26px; +} + +a.highlight_toggle { + background-position: -5px -841px; /* Highlight */ + display: none; + padding-left : 35px; +} + +a.hold, +input.hold { + background-position : -2px -453px; /* Toolbar place hold */ + text-decoration : none; + padding-left : 23px; +} + +a.hold.disabled, +input.hold.disabled { + background-position : -5px -621px; /* Place hold disabled */ +} + +a.incart { + background-position: -5px -265px; /* Cart */ + color : #666; + padding-left : 35px; +} + +a.new { + background-image : url("../images/sprite.png"); /* New */ + background-position : -4px -922px; + padding-left : 23px; + text-decoration : none; +} + +a.print-small { + background-position : 0px -423px; /* Toolbar print */ + text-decoration : none; + padding-left : 30px; +} + +a.print-large { + background-position : -5px -186px; /* Toolbar print */ + text-decoration : none; + padding-left : 35px; +} + +a.removeitems, +a.deleteshelf { + background-position : 2px -690px; /* Delete */ + text-decoration : none; + padding-left : 25px; +} + +a.removeitems.disabled, +a.deleteshelf.disabled { + background-position : 2px -712px; /* Delete disabled */ +} + +a.reserve { + background-position: -6px -144px; /* Place hold */ + padding-left : 35px; +} + +a.article_request { + background-position: 0px -24px; /* Place article request */ + padding-left : 35px; +} + +a.send { + background-position : 2px -386px; /* Email */ + text-decoration : none; + padding-left : 28px; +} + +a.tag_add { + background-position: 3px -1111px; /* Tag results */ + padding-left : 27px; + text-decoration: none; +} + +input.hold { + background-color: transparent; + border : 0; + color: #0076B2; + font-weight: bold; +} + +input.editshelf { + background-color: transparent; + background-position : 2px -736px; /* List edit */ + border : 0; + color : #006699; + cursor : pointer; + filter: none; + font-size : 100%; + padding-left : 29px; + text-decoration : none; +} + +.newshelf { + background-position: 2px -764px; /* List new */ + border : 0; + color : #006699; + cursor : pointer; + filter: none; + font-size : 100%; + padding-left : 28px; + text-decoration : none; +} + +.newshelf.disabled { + background-position: -4px -791px; /* List new disabled */ +} + +.deleteshelf { + background-color: transparent; + background-position : 2px -690px; /* Delete */ + border : 0; + color : #006699; + cursor : pointer; + filter: none; + font-size : 100%; + padding-left : 25px; + text-decoration : none; +} + +.links a { + font-weight : bold; +} + +.deleteshelf:hover { + color: #990033; +} + + +.editshelf:active, +.deleteshelf:active { + border : 0; +} + +#tagslist li { display : inline; } + +#login4tags { + background-image: url("../images/sprite.png"); /* Tag results disabled */ + background-position: -6px -1130px; + background-repeat: no-repeat; + padding-left : 20px; + text-decoration: none; +} + +.tag_results_input { + margin-left: 1em; + padding: 0.3em; + font-size: 12px; + input[type="text"] { + font-size: inherit; + margin : 0; + padding : 0; + } + label { + display : inline; + } +} + +.tagsinput { + input[type="text"] { + font-size: inherit; + margin : 0; + padding : 0; + } + label { + display : inline; + } +} + +.branch-info-tooltip { + display: none; +} + +.ui-tooltip-content p { + margin: 0.3em 0; +} + +#social_networks { + a { + background: transparent url("../images/social-sprite.png") no-repeat; + display: block; + height : 20px !important; + width : 20px; + text-indent : -999em; + } + span { + color: #274D7F; + display : block; + float : left; + font-size: 85%; + font-weight: bold; + line-height: 2em; + margin : .5em 0 .5em .5em !important; + } + div { + float : left !important; + margin : .5em 0 .5em .2em !important; + } + #facebook { + background-position : -7px -35px; + } + #twitter { + background-position : -7px -5px; + } + #linkedin { + background-position : -7px -95px; + } + #delicious { + background-position : -7px -66px; + } + #email { + background-position : -7px -126px; + } +} + +#marc { + td, + th { + background-color : transparent; + border : 0; + padding: 3px 5px; + text-align : left; + } + td:first-child { + text-indent : 2em; + } + p { + padding-bottom: .6em; + .label { + font-weight : bold; + } + } + ul { + padding-bottom: .6em; + } + .results_summary { + clear : left; + ul { + display : inline; + float : none; + clear : none; + margin: 0; + padding: 0; + list-style : none; + } + li { + display: inline; + } + } +} + +#items, +#items td +#items th { + border : 1px solid #EEE; + font-size : 90%; +} + +#plainmarc table { border: 0; margin: .7em 0 0 0; font-family: monospace; font-size: 95%; } +#plainmarc th { background-color : #FFF; border: 0; white-space: nowrap; text-align:left; vertical-align: top; padding: 2px; } +#plainmarc td { border: 0; padding : 2px; vertical-align: top; } + +#renewcontrols { + float: right; + font-size: 66%; +} + +#renewcontrols a { + background-repeat : no-repeat; + text-decoration:none; + padding : .1em .4em; + padding-left : 18px; +} + +#renewselected_link { + background-image : url("../images/sprite.png"); + background-position : -5px -986px; + background-repeat: no-repeat; +} + +#renewall_link { + background-image : url("../images/sprite.png"); + background-position : -8px -967px; + background-repeat: no-repeat; +} + +.authref { + text-indent: 2em; +} + +.authref .label { + font-style: italic; +} + +.authstanza { + margin-top: 1em; +} + +.authstanzaheading { + font-weight: bold; +} +.authorizedheading { + font-weight: bold; +} +.authstanza li { + margin-left: 0.5em; +} +.authres_notes, .authres_seealso, .authres_otherscript { + padding-top: .5em; +} +.authres_notes { + font-style: italic; +} + +#didyoumean { + background-color: #EEE; + border: 1px solid #E8E8E8; + box-sizing: border-box; + margin: .5em 1.5em; + text-align: left; + padding: 0.5em; + .border-radius-all(3px); + + &.dym-loaded { + border-color: #F4ECBE; + background-color: #FFFBEA; + } +} + +.suggestionlabel { + font-weight: bold; +} + +.searchsuggestion { + padding: 0.2em 0.5em; + display: inline-block; +} + +.authlink { + padding-left: 0.25em; +} +#hierarchies a { + font-weight: normal; + text-decoration: underline; + color: #069; +} + +#hierarchies a:hover { + color: #990033; +} + +#top-pages { + margin: 0 0 0.5em; +} +.dropdown-menu > li > a { + font-size: 90%; +} +a.listmenulink:link, +a.listmenulink:visited { + color : #0076B2; + font-weight: bold; +} +a.listmenulink:hover, +a.listmenulink:active { + color : #FFF; + font-weight: bold; +} +#cartDetails, +#cartUpdate, +#holdDetails, +#listsDetails { + background-color : #FFF; +// border: 1px solid #739acf; + border: 1px solid rgba(0, 0, 0, 0.2); + border-radius: 6px 6px 6px 6px; + box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + color : black; + display : none; + font-size: 90%; + margin : 0; + padding : 8px 20px; + text-align : center; + width : 180px; + z-index: 2; +} +#cartmenulink { + white-space: nowrap; +} + +#search-facets, +#menu { + border : 1px solid #D2D2CF; + .border-radius-all(7px); + ul { + margin : 0; + padding : .3em; + } + form { + margin : 0; + } + h4 { + font-size : 90%; + margin : 0 0 .6em 0; + text-align : center; + a { + background-color : #F2F2EF; + border-radius: 8px 8px 0 0; + border-bottom : 1px solid #D8D8D8; + display: block; + font-weight: bold; + padding : .7em .2em; + text-decoration: none; + } + } + li { + font-size: 90%; + font-weight : bold; + list-style-type : none; + li { + font-weight : normal; + font-size : 95%; + line-height: 125%; + margin-bottom : 2px; + padding : .1em .2em; + } + &.showmore { + a { + font-weight : bold; + text-indent : 1em; + } + } + } + a { + font-weight : normal; + text-decoration: underline; + } + .facet-count { + display: inline-block; + } + +} + +#menu { + font-size : 94%; + li { + list-style-type : none; + a { + background: #eeeeee; + text-decoration : none; + display : block; + border : 1px solid #D8D8D8; + border-radius: 5px 0 0 5px; + border-bottom-color: #999; + font-size : 111%; + padding : .4em .6em; + margin : .4em 0; + margin-right: -1px; + &:hover { + background: #eaeef5; + } + } + &.active { + a { + background-color : #FFF; + background-image : none; + border-right-width: 0; + font-weight : bold; + &:hover { + background-color : #fff; + } + } + } + } + h4 { + display: none; + } +} + +#addto { + max-width : 10em; +} + +/* Search results add to cart (lists disabled) */ +.addto a.addtocart { + background-image: url("../images/sprite.png"); /* Cart */ + background-position: -5px -266px; + background-repeat: no-repeat; + text-decoration : none; + padding-left : 33px; +} + +.searchresults { + p { + margin: 0; + padding: 0 0 .6em 0; + &.details { + color : #979797; + } + } + a { + &.highlight_toggle { + background-image: url("../images/sprite.png"); /* Highlight */ + background-position: -11px -841px; + background-repeat: no-repeat; + display: none; + font-weight: normal; + padding : 0 10px 0 21px; + } + } + .commentline { + background-color : rgb(255, 255, 204); + background-color : rgba(255, 255, 204, 0.4); + border : 1px solid #CCC; + display: inline-block; + .border-radius-all(3px); + .shadowed; + margin : .3em; + padding : .4em; + } + .commentline.yours { + background-color : rgb(239, 254, 213); + background-color : rgba(239, 254, 213, 0.4); + } +} + +.commentline .avatar { + float : right; + padding-left : .5em; +} + +/* style for search terms in catalogsearch */ +.term { + /* color : blue; */ + color : #990000; + background-color : #FFFFCC; +} + +/* style for shelving location in catalogsearch */ +.shelvingloc { + display : block; + font-style : italic; +} +#CheckAll, +#CheckNone, +.CheckAll, +.CheckNone { + font-weight : normal; + margin : 0 .5em; + text-decoration: underline; +} + +span.sep { + color: #888; + padding: 0 .2em 0 .5em; + text-shadow: 1px 1px 0 #FFF; +} + +/* style for PM-generated pagination bar */ +.pages { + margin: 20px 0; +} +.pages span:first-child, +.pages a:first-child { + border-width: 1px 1px 1px 1px; + border-bottom-left-radius: 3px; + border-top-left-radius: 3px; +} + +.pages span:last-child, +.pages a:last-child { + border-width: 1px 1px 1px 0; + border-bottom-right-radius: 3px; + border-top-right-radius: 3px; +} + +.pages .inactive, +.pages .currentPage, +.pages a { + -moz-border-bottom-colors: none; + -moz-border-left-colors: none; + -moz-border-right-colors: none; + -moz-border-top-colors: none; + background-color: #FFFFFF; + border-color: #DDDDDD; + border-image: none; + border-style: solid; + border-width: 1px 1px 1px 0; + float: left; + font-size: 11.9px; + line-height: 20px; + padding: 4px 12px; + text-decoration: none; +} + +.pages .inactive { + background-color: #F5F5F5; +} + +.pages a[rel='last'] { + border-bottom-right-radius: 3px; + border-top-right-radius: 3px; +} + +.hold-message { + background-color: #FFF0B1; + display: inline-block; + margin: 0.5em; + padding: 0.2em 0.5em; + .border-radius-all(3px); +} +.reserve_date, +.expiration_date { + white-space: nowrap; +} +.close { + color: #0088CC; + position: inherit; + top: auto; + right : auto; + filter : none; + float : none; + font-size: inherit; + font-weight: normal; + opacity: inherit; + text-shadow: none; +} + +.close:hover { + color: #538200; + filter: inherit; + font-size: inherit; + opacity: inherit; +} + +/* Redefine a new style for Bootstrap's class "close" since we use that already */ +/* Use <a class="closebtn" href="#">×</a> */ +.alert .closebtn{position:relative;top:-2px;right:-21px;line-height:20px;} +.modal-header .closebtn{margin-top:2px;} +.closebtn{float:right;font-size:20px;font-weight:bold;line-height:20px;color:#000000;text-shadow:0 1px 0 #ffffff;opacity:0.2;filter:alpha(opacity=20);}.closebtn:hover{color:#000000;text-decoration:none;cursor:pointer;opacity:0.4;filter:alpha(opacity=40);} +button.closebtn{padding:0;cursor:pointer;background:transparent;border:0;-webkit-appearance:none;} +.btn-group label, +.btn-group select { + font-size: 13px; +} + +.span2 select { + width: 100%; +} + +.popup .main { + font-size: 90%; + padding: 0 1em; +} + +.popup legend { + line-height: 1.5em; + margin-bottom : .5em; +} + +.item-status { + display: block; + font-size: 95%; + margin-bottom: .5em; +} + +.available { + color : #006600; +} + +.unavailable { + color: #990033; +} + +.waiting,.intransit,.notforloan,.checkedout,.lost,.notonhold { + display : block; +} + +.notforloan { + color : #900; +} + +.lost { + color : #666; +} + +.suggestion { + background-color : #EEEEEB; + border : 1px solid #DDDED3; + margin : 1em auto; + padding : .5em; + width : 35%; + .border-radius-all(3px); +} + +.librarypulldown .transl1 { + width : auto; +} + +.nolibrarypulldown { + width : 68%; +} + +.nolibrarypulldown .transl1 { + width : 87%; +} + +#opac-main-search { + select { + width : auto; + max-width: 12em; + } +} + +#logo { + background:transparent url("../images/koha-logo-navbar.png") no-repeat scroll 0%; + border: 0; + float : left !important; + margin:0; + padding:0; + width:100px; + a { + border:0; + cursor:pointer; + display:block; + height:0px !important; + margin:0; + overflow:hidden; + padding:40px 0 0; + text-decoration:none; + width:100px; + } +} + +#user-menu-trigger { + display: none; + .icon-user { + background: transparent url("../lib/bootstrap/img/glyphicons-halflings-white.png") no-repeat; + background-position: -168px 0; + background-repeat: no-repeat; + height: 14px; + line-height: 14px; + margin : 12px 0 0; + vertical-align: text-top; + width: 14px; + } + .caret { + border-bottom-color: #999999; + border-top-color: #999999; + margin-top: 18px; + } +} + +/* Class to be added to toolbar when it starts being fixed at the top of the screen*/ +.floating { + -webkit-box-shadow: 0px 3px 2px 0px rgba(0, 0, 0, .4); + box-shadow: 0px 3px 2px 0px rgba(0, 0, 0, .4); + margin-top: 0; +} + +.tdlabel { + font-weight: bold; + display: none; +} + +td img { + max-width: none; +} + +#ulactioncontainer { + min-width: 16em; +} + +.notesrow { + label { + font-weight: bold; + } + span { + display: block; + } +} + +.thumbnail-shelfbrowser span { + margin: 0px auto; +} + +.dropdown-menu > li > a.menu-inactive:hover { + background : #FFF none; + color : #000; +} + +.table { + .sorting_asc { + padding-right: 19px; + background: url("../images/asc.gif") no-repeat scroll right center #ECEDE6; + } + .sorting_desc { + padding-right: 19px; + background: url("../images/desc.gif") no-repeat scroll right center #ECEDE6; + } + .sorting { + padding-right: 19px; + background: url("../images/ascdesc.gif") no-repeat scroll right center #ECEDE6; + } + .nosort, + .nosort.sorting_asc, + .nosort.sorting_desc, + .nosort.sorting { + padding-right: 19px; + background: #ECEDE6 none; + } + th, + td { + line-height: 135%; + } +} +.tags, .shelves { + ul { + display: inline; + list-style: none; + margin-left : 0; + li { + display: inline; + } + } +} +.coverimages { + float : right; +} +#i18nMenu { + margin-left : 1em; + li { + font-size : 85%; + li { + font-size: 100%; + } + li > a { + font-size : 100%; + &:hover { + color : #FFF; + } + } + a { + color : @links; + } + } + .dropdown-menu { + li { + p { + clear: both; + display: block; + font-weight: normal; + line-height: 20px; + padding: 3px 20px; + white-space: nowrap; + } + } + } +} + +#subjectsList, +#authorSearch { + label { + display :inline; + vertical-align: middle; + } + ul { + border-bottom: 1px solid #EEE; + list-style-type: none; + margin: 0; + padding: .6em 0; + } + li { + list-style-type: none; + margin: 0; + padding: 0; + } +} + + +#overdrive-results, #openlibrary-results { + font-weight: bold; + padding-left: 1em; +} + +.throbber { + vertical-align: middle; +} + +#overdrive-results-list .star-rating-control { + display: block; + overflow: auto; +} + +#shelfbrowser { + table { + margin : 0; + } + table, + td, + th { + border : 0; + font-size : 90%; + text-align : center; + } + td, + th { + padding: 3px 5px; + width : 20%; + } + a { + display : block; + font-size : 110%; + font-weight : bold; + text-decoration : none; + } + #browser_next, + #browser_previous { + background-image : url("../images/sprite.png"); + background-repeat: no-repeat; + width : 16px; + a { + cursor: pointer; + display : block; + height: 0 !important; + margin: 0; + overflow: hidden; + padding: 50px 0 0; + text-decoration: none; + width: 16px; + } + } + #browser_previous { + background-position: -9px -1007px; + } + #browser_next { + background-position: -9px -1057px; + } +} + +#holds { + margin : 0 auto; + max-width: 800px; +} +.holdrow { + clear : both; + padding: 0 1em 1em 1em; + border-bottom:1px solid #CCC; + margin-bottom:.5em; + fieldset { + border : 0; + margin : 0; + float: none; + .label { + font-size: 14px; + } + } + label { + display: inline; + } +} +.hold-options { + clear : both; +} +.toggle-hold-options { + background-color: #eee; + clear : both; + display : block; + font-weight : bold; + margin: 1em 0; + padding: .5em; +} +.hold-option select { + width: auto; +} +.copiesrow { + clear : both; +} + +#idreambooksreadometer { + float: right; +} + +a.idreambooksrating { + font-size: 30px; + color: #29ADE4; + padding-left: 85px; + line-height: 30px; + text-decoration: none; +} + +.idreambookslegend { + font-size: small; +} + +a.reviewlink, +a.reviewlink:visited { + text-decoration: none; + color: black; + font-weight: normal; +} + +.idreambookssummary a { + color: #707070; + text-decoration: none; +} + +.idreambookssummary img, +.idbresult img { + vertical-align: middle; +} + +.idbresult { + color: #29ADE4; + text-align: center; + margin: 0.5em; + padding: 0.5em; +} + +.idbresult a, +.idbresult a:visited { + text-decoration: none; + color: #29ADE4; +} + +.idbresult img { + padding-right: 6px; +} + +.js-show { + display: none; +} + +.modal-nojs { + .modal-header, + .modal-footer { + display: none; + } +} + +.contents { + width: 75%; +} + + +.contentblock { + font-size : 95%; + line-height: 135%; + position: relative; + margin-left: 2em; +} + +.contents { + .t:first-child:before { + content: "→ "; + } + .t:before { + content: "\A → "; + white-space: pre; + } + .t { + font-weight: bold; + display: inline; + } + .r { + display: inline; + } +} + +.m880 { + display:block; + text-align:right; + float:right; + width:50%; + padding-left:20px; +} + +#memberentry-form input.error { + border-color: #c00; + box-shadow: 0 1px 1px #c00 inset, 0 0 8px #c00; + color: red; outline: 0 none; +} + +#memberentry-form input.error:focus { + border-color: #c00; + box-shadow: 0 1px 1px #c00 inset, 0 0 8px #c00; + color: red; outline: 0 none; +} + +#memberentry-form label.error { + color: #c00; float: none; + font-size: 90%; +} + +#illrequests { + .illrequest-actions { + .btn, + .cancel { + margin-right: 5px; + } + padding-top: 20px; + margin-bottom: 20px; + } + #illrequests-create-button { + margin-bottom: 20px; + } + .bg-info { + overflow: auto; + position: relative; + } + .bg-info { + #search-summary { + -webkit-transform: translateY(-50%); + -ms-transform: translateY(-50%); + -o-transform: translateY(-50%); + transform: translateY(-50%); + position: absolute; + top: 50%; + } + + } + #freeform-fields .custom-name { + float: left; + width: 8em; + margin-right: 1em; + text-align: right; + } + .dropdown:hover .dropdown-menu.nojs { + display: block; + } +} + +#dc_fieldset { + border: 1px solid #dddddd; + border-width: 1px; + padding: 5px; + border-radius: 10px +} + +.label_dc{ + display: inline; + padding: 0px; + margin: 0px; + cursor: pointer; +} + +.btn-danger { + color: white !important; +} + +.count_label { + @base: #369; + background-color: @base; + border-radius: 5px; + color: #FFF; + display: inline-block; + font-weight: bold; + min-width: 1.5em; + padding: .2em; + text-align: center; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + + &:hover { + background-color: lighten( @base, 20% ); + } +} + +.user_checkouts_count { + +} + +.user_overdues_count, +.user_fines_count { + background-color: #990000; + &:hover { + background-color: lighten( #990000, 10% ); + } +} + +.user_holds_pending_count { + +} + +.user_holds_waiting_count { + background-color: #538200; + &:hover { + background-color: lighten( #538200, 10% ); + } +} + +#user_summary { + border: 1px solid #EAEAE6; + border-radius: 7px; + margin-bottom: 1em; + padding-bottom: .5em; + + h3 { + background-color: #EAEAE6; + border-top-left-radius: 6px; + border-top-right-radius: 6px; + box-shadow: 0 1px 1px 0 rgba(0,0,0,0.2); + margin-top: 0; + padding: .2em 0; + text-align: center; + } + + ul { + list-style-type: none; + margin: 0 0 .2em 0; + + a { + display: block; + font-weight: bold; + padding: .2em 1em; + } + } +} + + + +@import "responsive.less"; diff --git a/opac/opac-reserve.pl b/opac/opac-reserve.pl index 92989a2..649154c 100755 --- a/opac/opac-reserve.pl +++ b/opac/opac-reserve.pl @@ -106,34 +106,19 @@ if ( $reservefee > 0){ my $itemtypes = { map { $_->{itemtype} => $_ } @{ Koha::ItemTypes->search_with_localization->unblessed } }; -# There are two ways of calling this script, with a single biblio num -# or multiple biblio nums. -my $biblionumbers = $query->param('biblionumbers'); -my $reserveMode = $query->param('reserve_mode'); -if ($reserveMode && ($reserveMode eq 'single')) { - my $bib = $query->param('single_bib'); - $biblionumbers = "$bib/"; -} -if (! $biblionumbers) { - $biblionumbers = $query->param('biblionumber'); -} - -if ((! $biblionumbers) && (! $query->param('place_reserve'))) { - $template->param(message=>1, no_biblionumber=>1); - &get_out($query, $cookie, $template->output); +# Coming from opac-search biblionumbers param is a string, coming from +# opac-reserve, it's an array. +my @biblionumbers = ref($query->param('biblionumbers')) eq 'Array' + ? $query->param('biblionumbers') + : split(/\//, $query->param('biblionumbers')); + +unless (@biblionumbers) { + push(@biblionumbers, $query->param('biblionumber')); } # Pass the numbers to the page so they can be fed back # when the hold is confirmed. TODO: Not necessary? -$template->param( biblionumbers => $biblionumbers ); - -# Each biblio number is suffixed with '/', e.g. "1/2/3/" -my @biblionumbers = split /\//, $biblionumbers; -if (($#biblionumbers < 0) && (! $query->param('place_reserve'))) { - # TODO: New message? - $template->param(message=>1, no_biblionumber=>1); - &get_out($query, $cookie, $template->output); -} +$template->param( biblionumbers => @biblionumbers ); # pass the pickup branch along.... @@ -205,39 +190,22 @@ if ( $query->param('place_reserve') ) { $reserve_cnt = $patron->holds->count; } - # List is composed of alternating biblio/item/branch - my $selectedItems = $query->param('selecteditems'); - - if ($query->param('reserve_mode') eq 'single') { - # This indicates non-JavaScript mode, so there was - # only a single biblio number selected. - my $bib = $query->param('single_bib'); - my $item = $query->param("checkitem_$bib"); - if ($item eq 'any') { - $item = ''; - } - my $branch = $query->param('branch'); - $selectedItems = "$bib/$item/$branch/"; - } - - $selectedItems =~ s!/$!!; - my @selectedItems = split /\//, $selectedItems, -1; - - # Make sure there is a biblionum/itemnum/branch triplet for each item. - # The itemnum can be 'any', meaning next available. - my $selectionCount = @selectedItems; - if (($selectionCount == 0) || (($selectionCount % 3) != 0)) { - $template->param(message=>1, bad_data=>1); - &get_out($query, $cookie, $template->output); - } - my $failed_holds = 0; - while (@selectedItems) { - my $biblioNum = shift(@selectedItems); - my $itemNum = shift(@selectedItems); - my $branch = shift(@selectedItems); # i.e., branch code, not name - - my $canreserve = 0; + foreach my $biblioNum (@biblionumbers) { + my $itemNum = $query->param("checkitem_$biblioNum"); + my @itemnumbers = $query->param("checkitem_$biblioNum"); + my $branch = $query->param("branch_$biblioNum"); + my $reqtype = $query->param("reqtype_$biblioNum"); + my $holds_to_place_count = $query->param("holds_to_place_count_$biblioNum") || 1; + my $notes = $query->param('notes_'.$biblioNum) || ''; + my $nbRequested = $reqtype eq 'Specific' ? @itemnumbers : $holds_to_place_count; + + my $canreserve = 1; + if ( $maxreserves + && $reserve_cnt + $nbRequested >= $maxreserves ) + { + $canreserve = 0; + } my $singleBranchMode = Koha::Libraries->search->count == 1; if ( $singleBranchMode || !$OPACChooseBranch ) @@ -245,7 +213,6 @@ if ( $query->param('place_reserve') ) { $branch = $patron->branchcode; } -#item may belong to a host biblio, if yes change biblioNum to hosts bilbionumber if ( $itemNum ne '' ) { my $item = Koha::Items->find( $itemNum ); my $hostbiblioNum = $item->biblio->biblionumber; @@ -267,23 +234,44 @@ if ( $query->param('place_reserve') ) { my $expiration_date = $query->param("expiration_date_$biblioNum"); + # If a specific item was selected and the pickup branch is the same as the + # holdingbranch, force the value $rank and $found. my $rank = $biblioData->{rank}; - if ( $itemNum ne '' ) { - $canreserve = 1 if CanItemBeReserved( $borrowernumber, $itemNum )->{status} eq 'OK'; - } - else { - $canreserve = 1 if CanBookBeReserved( $borrowernumber, $biblioNum )->{status} eq 'OK'; + if ( $reqtype eq 'Specific') { + foreach my $itemnumber (@itemnumbers) { + my $biblionumber = $biblioNum; + + #item may belong to a host biblio, if yes change biblioNum to hosts bilbionumber + my $hostbiblioNum = GetBiblionumberFromItemnumber($itemnumber); + if ( $hostbiblioNum ne $biblioNum ) { + $biblionumber = $hostbiblioNum; + } - # Inserts a null into the 'itemnumber' field of 'reserves' table. - $itemNum = undef; - } - my $notes = $query->param('notes_'.$biblioNum)||''; + $canreserve = 0 unless CanItemBeReserved( $borrowernumber, $itemnumber ) eq 'OK'; + $rank = '0' unless C4::Context->preference('ReservesNeedReturns'); + my $item = GetItem($itemnumber); + if ( $item->{'holdingbranch'} eq $branch ) { + $found = 'W' + unless C4::Context->preference('ReservesNeedReturns'); + } - if ( $maxreserves - && $reserve_cnt >= $maxreserves ) - { - $canreserve = 0; + if ($canreserve) { + my $reserve_id = AddReserve( + $branch, $borrowernumber, + $biblionumber, + [$biblionumber], $rank, + $startdate, $expiration_date, + $notes, $biblioData->{title}, + $itemnumber, $found + ); + $failed_holds++ unless $reserve_id; + ++$reserve_cnt; + } + } + print $query->redirect("/cgi-bin/koha/opac-user.pl?" . ( $failed_holds ? "failed_holds=$failed_holds" : q|| ) . "#opac-user-holds"); + exit; } + $canreserve = 0 unless CanBookBeReserved( $borrowernumber, $biblioNum ) eq 'OK'; unless ( $can_place_hold_if_available_at_pickup ) { my $items_in_this_library = Koha::Items->search({ biblionumber => $biblioNum, holdingbranch => $branch }); @@ -299,14 +287,16 @@ if ( $query->param('place_reserve') ) { # Here we actually do the reserveration. Stage 3. if ($canreserve) { - my $reserve_id = AddReserve( - $branch, $borrowernumber, $biblioNum, - [$biblioNum], $rank, $startdate, - $expiration_date, $notes, $biblioData->{title}, - $itemNum, $found, $itemtype, - ); - $failed_holds++ unless $reserve_id; - ++$reserve_cnt; + for ( my $i = 0 ; $i < $holds_to_place_count ; $i++ ) { + my $reserve_id = AddReserve( + $branch, $borrowernumber, $biblioNum, + [$biblioNum], $rank, $startdate, + $expiration_date, $notes, $biblioData->{title}, + $itemNum, $found, $itemtype, + ); + $failed_holds++ unless $reserve_id; + ++$reserve_cnt; + } } } @@ -366,6 +356,10 @@ if ( $maxreserves && ( $reserves_count >= $maxreserves ) ) { } unless ( $noreserves ) { + $template->param( + maxreserves => $maxreserves, + reserves_count => $reserves_count + ); my $requested_reserves_count = scalar( @biblionumbers ); if ( $maxreserves && ( $reserves_count + $requested_reserves_count > $maxreserves ) ) { $template->param( new_reserves_allowed => $maxreserves - $reserves_count ); @@ -532,7 +526,7 @@ foreach my $biblioNum (@biblionumbers) { if ( $opac_hold_policy ne 'N' ) { # If Y or F $itemLoopIter->{available} = 1; $numCopiesOPACAvailable++; - $biblioLoopIter{force_hold} = 1 if $opac_hold_policy eq 'F'; + $biblioLoopIter{force_hold} = 'item' if $opac_hold_policy eq 'F'; } $numCopiesAvailable++; @@ -592,18 +586,24 @@ foreach my $biblioNum (@biblionumbers) { # patron placed a record level hold, all the holds the patron places must # be record level. If the patron placed an item level hold, all holds # the patron places must be item level - my $forced_hold_level = Koha::Holds->search( + my $holds = Koha::Holds->search( { borrowernumber => $borrowernumber, biblionumber => $biblioNum, found => undef, } - )->forced_hold_level(); + ); + my $forced_hold_level = $holds->forced_hold_level(); if ($forced_hold_level) { - $biblioLoopIter{force_hold} = 1 if $forced_hold_level eq 'item'; - $biblioLoopIter{itemholdable} = 0 if $forced_hold_level eq 'record'; + #$biblioLoopIter{force_hold} = 1 if $forced_hold_level eq 'item'; + #$biblioLoopIter{itemholdable} = 0 if $forced_hold_level eq 'record'; + $biblioLoopIter{force_hold} = $forced_hold_level; } + my $max_holds_for_record = GetMaxPatronHoldsForRecord( $borrowernumber, $biblioNum ); + my $remaining_holds_for_record = $max_holds_for_record - $holds->count(); + $biblioLoopIter{remaining_holds_for_record} = $remaining_holds_for_record; + push @$biblioLoop, \%biblioLoopIter; diff --git a/reserve/placerequest.pl b/reserve/placerequest.pl index 351041b..3b93836 100755 --- a/reserve/placerequest.pl +++ b/reserve/placerequest.pl @@ -47,7 +47,7 @@ my $startdate = $input->param('reserve_date') || ''; my @rank = $input->multi_param('rank-request'); my $type = $input->param('type'); my $title = $input->param('title'); -my $checkitem = $input->param('checkitem'); +my @checkitems = $input->param('checkitem'); my $expirationdate = $input->param('expiration_date'); my $itemtype = $input->param('itemtype') || undef; @@ -58,6 +58,7 @@ my $multi_hold = $input->param('multi_hold'); my $biblionumbers = $multi_hold ? $input->param('biblionumbers') : ($biblionumber . '/'); my $bad_bibs = $input->param('bad_bibs'); my $holds_to_place_count = $input->param('holds_to_place_count') || 1; +$holds_to_place_count = scalar(@checkitems) if scalar(@checkitems); my %bibinfos = (); my @biblionumbers = split '/', $biblionumbers; @@ -68,7 +69,17 @@ foreach my $bibnum (@biblionumbers) { $bibinfos{$bibnum} = \%bibinfo; } -my $found; +my @found; + +foreach my $checkitem (@checkitems) { + # if we have an item selectionned, and the pickup branch is the same as the holdingbranch + # of the document, we force the value $rank and $found . + $rank[0] = '0' unless C4::Context->preference('ReservesNeedReturns'); + my $item = GetItem($checkitem); + if ( $item->{'holdingbranch'} eq $branch ){ + push @found, 'W' unless C4::Context->preference('ReservesNeedReturns'); + } +} if ( $type eq 'str8' && $borrower ) { @@ -86,23 +97,18 @@ if ( $type eq 'str8' && $borrower ) { } } - if ( defined $checkitem && $checkitem ne '' ) { - my $item = GetItem($checkitem); - if ( $item->{'biblionumber'} ne $biblionumber ) { - $biblionumber = $item->{'biblionumber'}; - } - } - if ($multi_hold) { my $bibinfo = $bibinfos{$biblionumber}; - AddReserve($branch,$borrower->{'borrowernumber'},$biblionumber,[$biblionumber], - $bibinfo->{rank},$startdate,$expirationdate,$notes,$bibinfo->{title},$checkitem,$found); + AddReserve( $branch, $borrower->{'borrowernumber'}, + $biblionumber, [$biblionumber], + $bibinfo->{rank}, $startdate, $expirationdate, $notes,$bibinfo->{title}); } else { # place a request on 1st available for ( my $i = 0 ; $i < $holds_to_place_count ; $i++ ) { + my $item = GetItem($checkitems[$i]); AddReserve( $branch, $borrower->{'borrowernumber'}, - $biblionumber, \@realbi, $rank[0], $startdate, $expirationdate, $notes, $title, - $checkitem, $found, $itemtype ); + $item->{biblionumber}, \@realbi, $rank[0], $startdate, $expirationdate, $notes, $title, + $checkitems[$i], $found[$i] ); } } } -- 2.1.4