Koha/koha-tmpl/opac-tmpl/prog/en/modules/opac-reserve.tmpl
Kyle M Hall 3502810346 (bug 1532) Reserves Updates Ported From Dev_Week
This is a much improved re-implementation of the reserves updates from dev_week.
Less new code has been added, and more existing functions are used instead of adding new ones.

The 'Lock Hold' function has been removed due to it not working as intended.

[RM note for documentation: this adds the following features:

* ability to specify an expiration date for a hold request
  when placing it via the staff interface or OPAC
* daily batch job to cancel expired holds
* nice interface to change the priority of hold
  requests for a bib in the staff interface]

Signed-off-by: Galen Charlton <gmcharlt@gmail.com>
2010-02-18 22:49:47 -05:00

539 lines
26 KiB
Cheetah

<!-- TMPL_INCLUDE NAME="doc-head-open.inc" --><!-- TMPL_VAR NAME="LibraryNameTitle" DEFAULT="Koha Online" --> Catalog &rsaquo; Placing hold <!-- TMPL_VAR NAME="title" escape="html" --> for <!-- TMPL_LOOP NAME="USER_INFO" --><!-- TMPL_VAR NAME="firstname" --> <!-- TMPL_VAR NAME="surname" --><!-- /TMPL_LOOP -->
<!-- TMPL_INCLUDE NAME="doc-head-close.inc" -->
<!-- TMPL_INCLUDE NAME="calendar.inc" -->
<script type="text/javascript">
// <![CDATA[
var MSG_NO_COPY_SELECTED = _("Expecting a specific copy selection.");
function prefixOf (s, tok) {
var index = s.indexOf(tok);
return s.substring(0, index);
}
function suffixOf (s, tok) {
var index = s.indexOf(tok);
return s.substring(index + 1);
}
$(document).ready(function() {
var copiesRowId = null;
var wasSpecific = false;
var lastCopiesRowId = null;
$(".checkitem").parent().click(function(e){
if(e.target.tagName.toLowerCase() == 'td'){
$(this).find("input.checkitem").each( function() {
$(this).attr('checked', !$(this).attr('checked'));
});
}
});
// Hides all 'specific copy' table rows on load.
$(".copiesrow").hide();
$("#place_on_hdr").show();
$(".place_on_type").show();
// 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 = "<input type =\"checkbox\" class=\"confirmjs\" checked=\"checked\"";
html += "value=\"" + bib + "\"/>";
$(this).html(html);
});
$(".confirmjs_nohold").each(function(){
var bib = $(this).attr("title");
var html = "<input type =\"checkbox\" class=\"confirmjs\" disabled=\"disabled\"";
html += "value=\"" + bib + "\"/>";
$(this).html(html);
});
// Make sure a specific item was selected where specified
// before moving on to a new item.
function changeSelection (newCopiesRowId, isSpecific) {
if (copiesRowId && ((copiesRowId != newCopiesRowId) || (wasSpecific != isSpecific))) {
var biblioNum = suffixOf(copiesRowId, "_");
// If the 'specific copy' radio button was checked
if (wasSpecific && (copiesRowId != newCopiesRowId)) {
// Find the selected copy
var item = $(".checkitem_" + biblioNum + ":checked");
if ($(item).size() == 0) {
alert(MSG_NO_COPY_SELECTED);
return false;
}
}
}
copiesRowId = newCopiesRowId;
wasSpecific = isSpecific;
return true;
}
// When 'specific copy' radio button is clicked
$(".selectspecific").click(function() {
// Make sure all other specific copy table rows are hidden
biblioNum = suffixOf($(this).attr("id"), "_");
newCopiesRowId = "#copiesrow_" + biblioNum;
if (!changeSelection(newCopiesRowId, true)) {
return false;
}
$(".copiesrow:not(" + newCopiesRowId + ")").hide();
// Show the specific copy table for this radio button.
$(newCopiesRowId).show();
});
// When 'first available' radion button is clicked
$(".selectany").click(function() {
// Make sure all other specific copy table rows are hidden
biblioNum = suffixOf($(this).attr("id"), "_");
newCopiesRowId = "#copiesrow_" + biblioNum;
if (!changeSelection(newCopiesRowId, false)) {
return false;
}
// Hide the copies table row
$(".copiesrow").hide();
});
// When 'Place Hold' button is clicked
$(".placehold").click(function(){
var biblionumbers = "";
var selections = "";
if ($(".confirmjs: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() {
var biblioNum = $(this).val();
biblionumbers += biblioNum + "/";
selections += biblioNum + "/";
// If the 'specific copy' radio button is checked
if ($("#reqspecific_" + biblioNum + ":checked").size() > 0) {
// Find the selected copy
var item = $(".checkitem_" + biblioNum + ":checked");
if ($(item).size() == 0) {
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;
});
if (badBib) {
alert(MSG_NO_COPY_SELECTED);
return false;
}
$("#selections").val(selections);
$("#biblionumbers").val(biblionumbers);
return true;
});
});
// ]]>
</script>
</head>
<body id="opac-holds">
<div id="doc3" class="yui-t7">
<!--TMPL_INCLUDE NAME="masthead.inc" -->
<div id="bd">
<div id="yui-g">
<div id="holds" class="container">
<!-- TMPL_IF NAME="message" -->
<!-- TMPL_IF NAME="GNA" -->
<div class="dialog alert">
<strong>Sorry</strong>, you cannot place holds because the library doesn't have up-to-date <a href="/cgi-bin/koha/opac-userdetails.pl">contact information</a> on file.
</div>
<div class="dialog alert">Please contact your librarian, or use the <a href="/cgi-bin/koha/opac-userupdate.pl">online update form</a> to submit current information (<em>Please note:</em> there may be a delay in restoring your account if you submit online)
</div>
<!-- /TMPL_IF -->
<!-- TMPL_IF NAME="lost" -->
<div class="dialog alert">
<strong>Sorry</strong>, you cannot place holds because your library card has been marked as lost or stolen.
</div>
<div class="dialog alert">If this is an error, please take your card to the circulation desk at your local library and the error will be corrected.
</div>
<!-- /TMPL_IF -->
<!-- TMPL_IF NAME="debarred" -->
<div class="dialog alert">
<strong>Sorry</strong>, you cannot place holds because your account has been frozen.
</div>
<div class="dialog alert">Usually the reason for freezing an account is old overdues or damage fees. If <a href="/cgi-bin/koha/opac-user.pl">your account page</a> shows your account to be clear, please consult a librarian.
</div>
<!-- /TMPL_IF -->
<!-- TMPL_IF NAME="too_much_oweing" -->
<div class="dialog alert">
Sorry, you cannot place holds because you owe <!-- TMPL_VAR NAME="too_much_oweing" -->.
</div>
<!-- /TMPL_IF -->
<!-- TMPL_IF NAME="too_many_reserves" -->
<div class="dialog alert">Sorry, you cannot place more than <!-- TMPL_VAR NAME="too_many_reserves" --> holds.
</div>
<!-- /TMPL_IF -->
<!-- TMPL_IF NAME="bad_biblionumber" -->
<div class="dialog alert">ERROR: No biblio record found for biblionumber <!-- TMPL_VAR NAME="bad_biblionumber" -->.</div>
<!-- /TMPL_IF -->
<!-- TMPL_IF NAME="no_items_selected" -->
<div class="dialog alert">
You must select at least one item.
</div>
<!-- /TMPL_IF -->
<!-- TMPL_IF NAME="no_branch_selected" -->
<div class="dialog alert">
You must select a library for pickup.
</div>
<!-- /TMPL_IF -->
<!-- TMPL_IF NAME="no_biblionumber" -->
<div class="dialog alert">ERROR: No biblionumber received.</div>
<!-- /TMPL_IF -->
<!-- TMPL_IF NAME="bad_data" -->
<div class="dialog alert">ERROR: Internal error: incomplete hold request.</div>
<!-- /TMPL_IF -->
<!-- TMPL_IF NAME="none_available" -->
<div class="dialog alert"><strong>Sorry</strong>, none of these items can be placed on hold.
</div>
<!-- /TMPL_IF -->
<!-- /TMPL_IF --><!-- NAME="message" -->
<!-- TMPL_UNLESS NAME="message" -->
<h3>Confirm holds for:
<!-- TMPL_LOOP NAME="USER_INFO" -->
<!-- TMPL_VAR NAME="firstname" --> <!-- TMPL_VAR NAME="surname" --> (<!-- TMPL_VAR NAME="cardnumber" -->)
<!-- /TMPL_LOOP -->
</h3>
<form action="/cgi-bin/koha/opac-reserve.pl" method="post">
<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">
<table id="bibitemloop">
<tr>
<th colspan="2">Hold</th>
<th>Title</th>
<!-- TMPL_UNLESS NAME="item-level_itypes" -->
<th>Item Type</th>
<!-- /TMPL_UNLESS -->
<!-- TMPL_IF NAME="showpriority" -->
<th>Priority</th>
<!-- /TMPL_IF -->
<!-- TMPL_IF NAME="reserve_in_future" -->
<th>Hold Starts on Date</th>
<!-- /TMPL_IF -->
<th>Hold Not Needed After</th>
<!-- TMPL_IF NAME="OPACItemHolds" -->
<th id="place_on_hdr" style="display:none">Place On</th>
<!-- /TMPL_IF -->
<!-- TMPL_UNLESS NAME="singleBranchMode" -->
<th>Pickup Location</th>
<!-- /TMPL_UNLESS -->
</tr>
<!-- TMPL_LOOP name="bibitemloop" -->
<tr>
<!-- TMPL_IF NAME="holdable" -->
<td colspan="2">
<input class="reserve_mode" name="reserve_mode" type="hidden" value="single"/>
<input class="single_bib" name="single_bib" type="hidden" value="<!-- TMPL_VAR NAME="biblionumber" -->"/>
<span class="confirmjs_hold" title="<!-- TMPL_VAR NAME="biblionumber" -->"></span>
<span class="confirm_nonjs">
<input type="radio" class="confirmbox checkitem <!-- TMPL_VAR NAME="checkitem_bib" -->"
name="<!-- TMPL_VAR NAME="checkitem_bib" -->" checked="checked"
id="<!-- TMPL_VAR NAME="checkitem_bib" -->"
value="any" />
<label class="confirm_label" for="<!-- TMPL_VAR NAME="checkitem_bib" -->">Next available copy</label>
</span>
</td>
<!-- TMPL_ELSE -->
<td>
<input class="reserve_mode" name="reserve_mode" type="hidden" value="single"/>
<input class="single_bib" name="single_bib" type="hidden" value="<!-- TMPL_VAR NAME="biblionumber" -->"/>
<span class="confirmjs_nohold" title="<!-- TMPL_VAR NAME="biblionumber" -->"></span>
<span class="confirm_nonjs">
<input type="radio" class="confirmbox checkitem <!-- TMPL_VAR NAME="checkitem_bib" -->"
name="<!-- TMPL_VAR NAME="checkitem_bib" -->" disabled="disabled"
id="<!-- TMPL_VAR NAME="checkitem_bib" -->"
value="any" />
</span>
</td><td>
<!-- TMPL_IF NAME="already_reserved" -->
<div class="bibmessage">You have already requested this title.</div>
<!-- /TMPL_IF -->
<!-- TMPL_UNLESS NAME="bib_available" -->
<div class="bibmessage">No available items.</div>
<!-- TMPL_ELSE -->
<div class="bibmessage">This title cannot be requested.</div>
<!-- /TMPL_UNLESS -->
</td>
<!-- /TMPL_IF -->
<td>
<a href="/cgi-bin/koha/opac-detail.pl?biblionumber=<!-- TMPL_VAR NAME="biblionumber" -->"><!-- TMPL_VAR NAME="title" escape="html" --><!-- TMPL_IF NAME="subtitle" --> <!-- TMPL_LOOP NAME="subtitle" --><!--TMPL VAR Name="subfield"--><!--/TMPL_LOOP--><!-- /TMPL_IF --></a>
<!-- TMPL_IF NAME="author" -->, by <!-- TMPL_VAR NAME="author" --><!-- /TMPL_IF -->
</td>
<!-- TMPL_UNLESS NAME="item-level_itypes" -->
<td>
<!-- TMPL_IF NAME="imageurl" --><img src="<!-- TMPL_VAR NAME="imageurl" -->" alt="" /><!-- /TMPL_IF -->
<!-- TMPL_VAR NAME="description" -->
</td>
<!-- /TMPL_UNLESS -->
<!-- TMPL_IF NAME="showpriority" --><td><!-- TMPL_VAR name="rank" --> out of <!-- TMPL_VAR NAME="reservecount" --></td><!-- /TMPL_IF -->
<!-- TMPL_IF NAME="reserve_in_future" -->
<td>
<input name="reserve_date_<!-- TMPL_VAR NAME="biblionumber" -->" id="reserve_date_<!-- TMPL_VAR NAME="biblionumber" -->" size="10">
<!-- <img src="<!-- TMPL_VAR NAME="themelang" -->/lib/calendar/cal.gif" alt="Show Calendar" border="0" id="CalendarReserveDate<!-- TMPL_VAR NAME="biblionumber" -->" style="cursor: pointer;" /> -->
<script language="JavaScript" type="text/javascript">
//<![CDATA[
$("#reserve_date_<!-- TMPL_VAR NAME="biblionumber" -->").attr( 'readonly', 'readonly' );
var cal_img = document.createElement('img');
cal_img.src = "<!-- TMPL_VAR NAME="themelang" -->/lib/calendar/cal.gif";
cal_img.alt = "Show Calendar";
cal_img.border = "0";
cal_img.id = "CalendarReserveDate<!-- TMPL_VAR NAME="biblionumber" -->";
cal_img.style.cursor = "pointer";
document.getElementById("reserve_date_<!-- TMPL_VAR NAME="biblionumber" -->").parentNode.appendChild( cal_img );
function validate<!-- TMPL_VAR NAME="biblionumber" -->(date) {
var today = new Date();
if ( (date > today) ||
( date.getDate() == today.getDate() &&
date.getMonth() == today.getMonth() &&
date.getFullYear() == today.getFullYear() ) ) {
return false;
} else {
return true;
}
};
Calendar.setup(
{
inputField : "reserve_date_<!-- TMPL_VAR NAME="biblionumber" -->",
ifFormat : "<!-- TMPL_VAR NAME="DHTMLcalendar_dateformat" -->",
button : "CalendarReserveDate<!-- TMPL_VAR NAME="biblionumber" -->",
disableFunc : validate<!-- TMPL_VAR NAME="biblionumber" -->,
dateStatusFunc : validate<!-- TMPL_VAR NAME="biblionumber" -->,
}
);
//]]>
</script>
</td>
<!-- /TMPL_IF -->
<td>
<input name="expiration_date_<!-- TMPL_VAR NAME="biblionumber" -->" id="expiration_date_<!-- TMPL_VAR NAME="biblionumber" -->" size="10" readonly="readonly">
<img src="<!-- TMPL_VAR NAME="themelang" -->/lib/calendar/cal.gif" alt="Show Calendar" border="0" id="CalendarExpirationDate" style="cursor: pointer;" />
<script language="JavaScript" type="text/javascript">
//<![CDATA[
function validate1(date) {
var today = new Date();
if ( (date > today) ||
( date.getDate() == today.getDate() &&
date.getMonth() == today.getMonth() &&
date.getFullYear() == today.getFullYear() ) ) {
return false;
} else {
return true;
}
};
Calendar.setup(
{
inputField : "expiration_date_<!-- TMPL_VAR NAME="biblionumber" -->",
ifFormat : "<!-- TMPL_VAR NAME="DHTMLcalendar_dateformat" -->",
button : "CalendarExpirationDate",
disableFunc : validate1,
dateStatusFunc : validate1,
}
);
//]]>
</script>
<br/>
<a href='#' onClick="document.getElementById('expiration_date_<!-- TMPL_VAR NAME="biblionumber" -->').value='';">Clear Date</a>
</td>
<!-- TMPL_IF NAME="OPACItemHolds" -->
<td class="place_on_type" style="display:none">
<table>
<tr>
<td>
<!-- TMPL_UNLESS NAME="holdable" -->
<input type="radio" name="reqtype_<!-- TMPL_VAR NAME="biblionumber" -->"
id="reqany_<!-- TMPL_VAR NAME="biblionumber" -->"
class="selectany"
value="Any"
disabled="disabled"
/>
<!-- TMPL_ELSE -->
<input type="radio" name="reqtype_<!-- TMPL_VAR NAME="biblionumber" -->"
id="reqany_<!-- TMPL_VAR NAME="biblionumber" -->"
class="selectany"
value="Any"
checked="checked"
/>
<!-- /TMPL_UNLESS -->
<label for="reqany_<!-- TMPL_VAR NAME="biblionumber" -->">Next available copy</label>
</td>
</tr>
<tr>
<td>
<!-- TMPL_UNLESS NAME="holdable" -->
<input type="radio" name="reqtype_<!-- TMPL_VAR NAME="biblionumber" -->"
id="reqspecific_<!-- TMPL_VAR NAME="biblionumber" -->"
class="selectspecific"
disabled="disabled"
value="Specific"
/>
<!-- TMPL_ELSE -->
<input type="radio" name="reqtype_<!-- TMPL_VAR NAME="biblionumber" -->"
id="reqspecific_<!-- TMPL_VAR NAME="biblionumber" -->"
class="selectspecific"
value="Specific"
/>
<!-- /TMPL_UNLESS -->
<label for="reqspecific_<!-- TMPL_VAR NAME="biblionumber"-->">A specific copy</label>
</td>
</tr>
</table>
</td>
<!-- /TMPL_IF -->
<!-- TMPL_UNLESS NAME="singleBranchMode" -->
<td>
<select name="branch" id="branch_<!-- TMPL_VAR NAME="biblionumber" -->"
<!-- TMPL_UNLESS NAME="holdable" -->disabled="disabled"<!-- /TMPL_UNLESS --> >
<!-- TMPL_LOOP NAME="branchChoicesLoop" -->
<!-- TMPL_IF name="selected" -->
<option value="<!-- TMPL_VAR NAME="value" -->" selected="selected"><!-- TMPL_VAR NAME="branchname" --></option>
<!-- TMPL_ELSE -->
<option value="<!-- TMPL_VAR NAME="value" -->"><!-- TMPL_VAR NAME="branchname" --></option>
<!-- /TMPL_IF -->
<!-- /TMPL_LOOP -->
</select>
</td>
<!-- /TMPL_UNLESS -->
</tr>
<!-- TMPL_IF NAME="OPACItemHolds" -->
<!-- TMPL_IF NAME="bib_available" -->
<tr class="copiesrow" id="copiesrow_<!-- TMPL_VAR NAME="biblionumber"-->">
<td colspan="1">
</td>
<td colspan="<!-- TMPL_VAR NAME="itemtable_colspan" -->">
<table>
<caption>Select a specific copy:</caption>
<tr>
<th>Copy</th>
<!-- TMPL_IF NAME="item-level_itypes" -->
<th>Item Type</th>
<!-- /TMPL_IF -->
<th>Barcode</th>
<!-- TMPL_UNLESS NAME="singleBranchMode" -->
<th>Home Library</th>
<th>Last Location</th>
<!-- /TMPL_UNLESS -->
<th>Call Number</th>
<!-- TMPL_IF NAME="itemdata_enumchron" -->
<th>Vol Info</th>
<!-- /TMPL_IF -->
<th>Information</th>
</tr>
<!-- TMPL_LOOP name="itemLoop" -->
<tr class="<!-- TMPL_VAR NAME="backgroundcolor" -->">
<td>
<!-- TMPL_IF NAME="available" -->
<input type="radio" class="checkitem checkitem_<!-- TMPL_VAR NAME="biblionumber" -->" name="checkitem_<!-- TMPL_VAR NAME="biblionumber" -->"
value="<!-- TMPL_VAR NAME="itemnumber" -->" />
<!-- TMPL_ELSE -->
<input disabled="disabled" type="radio" class="checkitem" name="checkitem" value="<!-- TMPL_VAR NAME="itemnumber" -->" />
<img src="/opac-tmpl/<!-- TMPL_VAR NAME="theme" -->/famfamfam/silk/cross.png" alt="Cannot be put on hold" title="Cannot be put on hold" />
<!-- /TMPL_IF --> <!-- TMPL_IF NAME="copynumber" --><!-- TMPL_VAR NAME="copynumber" --><!-- /TMPL_IF -->
</td>
<!-- TMPL_IF NAME="item-level_itypes" -->
<td>
<!-- TMPL_IF NAME="imageurl" --><img src="<!-- TMPL_VAR NAME="imageurl" -->" alt="" /><!-- /TMPL_IF -->
<!-- TMPL_VAR NAME="description" -->
</td>
<!-- /TMPL_IF -->
<td><!-- TMPL_VAR NAME="barcode" --></td>
<!-- TMPL_UNLESS NAME="singleBranchMode" -->
<td><!-- TMPL_VAR NAME="homeBranchName" --></td>
<td><!-- TMPL_VAR NAME="holdingBranchName" --></td>
<!-- /TMPL_UNLESS -->
<td><!-- TMPL_VAR NAME="callNumber" --></td>
<!-- TMPL_IF NAME="itemdata_enumchron" --><!-- test -->
<td><!-- TMPL_VAR NAME="enumchron" --></td>
<!-- /TMPL_IF -->
<td>
<!-- TMPL_IF NAME="date_due" -->
<span class="checkedout">Due <!-- TMPL_VAR NAME="date_due" --></span>
<!-- TMPL_ELSIF NAME="transfertwhen" -->
<span class="intransit">In transit from <!-- TMPL_VAR NAME="transfertfrom" -->,
to <!-- TMPL_VAR NAME="transfertto" -->, since <!-- TMPL_VAR NAME="transfertwhen" --></span>
<!-- /TMPL_IF -->
<!-- TMPL_IF Name="message" -->
<span class="lost">Unavailable (lost or missing)</span>
<!-- /TMPL_IF -->
<!-- TMPL_IF Name="notforloan" -->
<span class="notforloan">Not for loan (<!-- TMPL_VAR NAME="notforloanvalue" -->)</span>
<!-- /TMPL_IF -->
<!-- TMPL_IF NAME="reservedate"-->
<span class="waiting"><!-- TMPL_IF NAME="waitingdate" -->Waiting<!-- TMPL_ELSE -->On hold<!-- /TMPL_IF --> for patron
<!-- TMPL_IF NAME="waitingdate" -->at<!-- TMPL_ELSE -->expected at<!-- /TMPL_IF --> <!-- TMPL_VAR NAME="ExpectedAtLibrary" -->
since
<!-- TMPL_IF NAME="waitingdate" --><!-- TMPL_VAR NAME="waitingdate" --><!-- TMPL_ELSE --><!-- TMPL_IF name="reservedate" --><!-- TMPL_VAR NAME="reservedate" --><!-- /TMPL_IF --><!-- /TMPL_IF -->.
</span>
<!-- TMPL_ELSE -->
<span class="notonhold">Not on hold</span>
<!-- /TMPL_IF -->&nbsp;
</td>
</tr>
<!-- /TMPL_LOOP -->
</table>
</td>
</tr>
<!-- /TMPL_IF --><!-- bib_available -->
<!-- /TMPL_IF --><!-- OPACItemHolds -->
<!-- /TMPL_LOOP -->
</table><!-- bibitemloop -->
</div><!-- bigloop -->
<!-- TMPL_IF NAME="none_available" -->
<input type="submit" disabled="disabled" value="Place Hold" />
<!-- TMPL_ELSE -->
<input type="submit" value="Place Hold" class="placehold" />
<!-- /TMPL_IF -->
</form>
<!-- /TMPL_UNLESS --><!-- message -->
</div><!-- holds -->
</div><!-- yui-g -->
</div><!-- bd -->
</div><!-- doc3 -->
<div><!-- The following include seems to have an extra "/div" in it... -->
<!-- TMPL_INCLUDE NAME="opac-bottom.inc"-->