Tuesday, August 8, 2017

Adding tabbed content to the Koha home page/Circulation home page/Reports home page



When I worked for the VALNet consortium we had a lot of content we needed to store somewhere easy for library staff to access.  There were some reports that were run monthly at various libraries and there were notices about school closures for the summer, and there were other things that seemed important to make available for staff.

The IntranetmainUserblock system preference seemed like a great place to store those things.  The problem was that we had so much content we wanted to share that, especially in the summer when the schools were closed, the Koha home page became about a mile tall.

One day I though, wouldn't it be cool to set that up as tabbed content.  School closures on one tab, reports on another, maybe a blog or calendar on a third.

This led to an investigation of tabbed content and I found a great, pre-built, tabbed content with only Java / CSS page template on GitHub.

The biggest modification I made to this code was to elements that the original author calls merely tab or tabs.  My fear is always that the next release of Koha will have an element with an ID called "tab" or "tabs" and that will screw up the operation of these pages.  Therefore in the IntranetmainUserblock the tabs are called mainxtabs, in IntranetCirculationHomeHTML they are called circxtabs, and in IntranetReportsHomeHTML they are called rptxtabs.

This is an example of this code written for IntranetCirculationHomeHTML with some added comments describing what the different lines are doing.

A second addition in this sample is that I have used inline CSS to hide Tabs 4 and 5.  What I have found is that 5 tabs on the screen for this space is enough.  If you put more tabs than that in a row in these areas, it's too much information, but the flip side of that is that I may not need 5 tabs all the time.  Rather than deleting the code that creates tabs 4 and 5 in this sample, I have them hidden so that all I have to do when I want to re-activate a tab is to remove the CSS.  This is particularly helpful when you want to show or hide a tab called "upcoming school closures" that you only need for a portion of the year.  Rather than deleting the content of that tab in the fall and recreating the tab again in the spring, hiding the tab takes it out of play

<!-- based on "Tabs pure javascript and css" by ShaunD2D at https://gist.github.com/Shaun2D2/6296191 -->

<style>

  ul#cirxtabs { list-style-type: none; margin: 30px 0 0 0; padding: 0 0 0.3em 0; }
    /*the above line controls the position of the tabs relative to the lines above them*/
  ul#cirxtabs li { display: inline; }
    /*the above line arranges the tabs horizontally across the top of the tabbed content*/
  ul#cirxtabs li a { color: #42454a; background-color: #dedbde; border: 1px solid #c9c3ba; border-bottom: none; padding: 0.3em; text-decoration: none; }
     /*the above line arranges controls the color of the tabs*/
  ul#cirxtabs li a:hover { background-color: #f1f0ee; }
    /*the above line changes the color of the selected tab and positions text on the tab*/
  ul#cirxtabs li a.selected { color: #000; background-color: #f1f0ee; font-weight: bold; padding: 0.7em 0.3em 0.38em 0.3em; }
    /*the above line controls the way that the content is positioned on the tab as well as the color of the tab*/
  div.cirxtabContent { border: 1px solid #c9c3ba; padding: 0.5em; background-color: #f1f0ee; }
  div.cirxtabContent.hide { display: none; }
    /*the above line hides the contents of the non-selected tabs*/

</style>

<script>

  var cirxtabLinks = new Array();
  var contentDivs = new Array();

  function init() {

    // Takes the content from the divs and puts them in the tabs
    var cirxtabListItems = document.getElementById('cirxtabs').childNodes;
    for ( var i = 0; i < cirxtabListItems.length; i++ ) {
      if ( cirxtabListItems[i].nodeName == "LI" ) {
        var cirxtabLink = getFirstChildWithTagName( cirxtabListItems[i], 'A' );
        var id = getHash( cirxtabLink.getAttribute('href') );
        cirxtabLinks[id] = cirxtabLink;
        contentDivs[id] = document.getElementById( id );
      }
    }

    // Tells the content what to do when the tabs are clicked
    // selects tab 1
    var i = 0;

    for ( var id in cirxtabLinks ) {
      cirxtabLinks[id].onclick = showcirxtab;
      cirxtabLinks[id].onfocus = function() { this.blur() };
      if ( i == 0 ) cirxtabLinks[id].className = 'selected';
      i++;
    }

    // Hide tabbed content except on tab 1
    var i = 0;

    for ( var id in contentDivs ) {
      if ( i != 0 ) contentDivs[id].className = 'cirxtabContent hide';
      i++;
    }
  }

  function showcirxtab() {
    var selectedId = getHash( this.getAttribute('href') );

    // Highlight the selected cirxtab, and dim all others.
    // Also show the selected content div, and hide all others.
    for ( var id in contentDivs ) {
      if ( id == selectedId ) {
        cirxtabLinks[id].className = 'selected';
        contentDivs[id].className = 'cirxtabContent';
      } else {
        cirxtabLinks[id].className = '';
        contentDivs[id].className = 'cirxtabContent hide';
      }
    }

    // Stop the browser following the link
    return false;
  }

  function getFirstChildWithTagName( element, tagName ) {
    for ( var i = 0; i < element.childNodes.length; i++ ) {
      if ( element.childNodes[i].nodeName == tagName ) return element.childNodes[i];
    }
  }

  function getHash( url ) {
    var hashPos = url.lastIndexOf ( '#' );
    return url.substring( hashPos + 1 );
  }

</script>

<body onload="init()">

<ul id="cirxtabs">
  <li><a href="#cirxtab01">Tab 01</a></li>
  <li><a href="#cirxtab02">Tab 02</a></li>
  <li><a href="#cirxtab03">Tab 03</a></li>
  <li style="display: none;"><a href="#cirxtab04">Tab 04</a></li>
  <li style="display: none;"><a href="#cirxtab05">Tab 05</a></li>
</ul>

<div class="cirxtabContent" id="cirxtab01">
  <h2>This is tab 01</h2>
  <div>
    <p>Tab 01 content goes here.</p>
  </div>
</div>

<div class="cirxtabContent" id="cirxtab02">
  <h2>This is tab 02</h2>
  <div>
    <p>Tab 02 content goes here.</p>
  </div>
</div>

<div class="cirxtabContent" id="cirxtab03">
  <h2>This is tab 03</h2>
  <div>
    <p>Tab 03 content goes here.</p>
  </div>
</div>

<div class="cirxtabContent" id="cirxtab04">
  <h2>This is tab 04</h2>
  <div>
    <p>Tab 04 content goes here.</p>
  </div>
</div>

<div class="cirxtabContent" id="cirxtab05">
  <h2>This is tab 05</h2>
  <div>
    <p>Tab 05 content goes here.</p>
  </div>
</div>

Monday, August 7, 2017

Using autorised values tables and wildcards in Koha reports

ByWater solutions did an example of what I'm about to demonstrate on their website while I was in the process of preparing this.  You can see their description of this same process at http://bywatersolutions.com/2017/06/08/koha-tutorial-branch-reporting/.

In the reporting module in Koha you can use runtime parameters when creating SQL reports.  Taking a simple query like:

SELECT
  branches.branchcode,
  branches.branchname
FROM
  branches
WHERE
  branches.branchcode = "DIGITAL"

And replacing

  branches.branchcode = "DIGITAL"

with

  branches.branchcode = <<Enter a branchcode>>

allows you to limit the results of the query to a different branch each time you run it.

You can go a step further though and, instead of using <<Enter a branchcode>> you can use <<Choose a branch from the drop-down|branches>>.  The text that comes after the pipe, "branches," tells Koha to give you that selection.  Currently the options you can use after a pipe include:


branches
itemtypes
date
categorycode

and the name of any authorised values table in your installation of Koha.

In my situation at my old job in VALNet and in my new job at NExpress, I have often had the need to re-write existing reports for libraries because the existing report worked fine for most libraries, but needed just one slight change in flexibility in order for it to work at other libraries.  One good example would be a simple circulation statistics report like:

SELECT
  statistics.branch,
  count(*) AS CIRC_PLUS_RENEW
FROM
  statistics
WHERE
  (statistics.type = 'issue' OR
  statistics.type = 'renew') AND
  statistics.datetime BETWEEN "2017-07-01" AND "2017-08-01"
GROUP BY
  statistics.branch

There are many times I will introduce a report like this into our consortium and someone will ask "Isn't there a way you could make that report so it only shows the results for my library?"  At that point it could be easily written as so:

SELECT
  statistics.branch,
  count(*) AS CIRC_PLUS_RENEW
FROM
  statistics
WHERE
  (statistics.type = 'issue' OR
  statistics.type = 'renew') AND
  statistics.datetime BETWEEN "2017-07-01" AND "2017-08-01" AND
  statistics.branch = <<Enter branch code>>
GROUP BY
  statistics.branch

My guess would be the immediate reaction to this report would be someone asking "Why do I have to type my library's code?" or "I put my library's name in there, but it didn't give me any results.  What happened?"  No one is going to be happy with having to type something in.  The simple solution there is to change <<Enter branch code>> to <<Choose your branch|branches>> so that the user gets a drop down menu to allow them to choose their branch.  Something like this:

SELECT
  statistics.branch,
  count(*) AS CIRC_PLUS_RENEW
FROM
  statistics
WHERE
  (statistics.type = 'issue' OR
  statistics.type = 'renew') AND
  statistics.datetime BETWEEN "2017-07-01" AND "2017-08-01" AND
  statistics.branch = <<Choose your branch|branches>>
GROUP BY
  statistics.branch

But this won't solve the problem because now some other librarian is going to ask "How can I run this report so that I see everyone's circulation statistics?  It used to show that.  Why doesn't it do that any more?"  Similarly I have two library districts in the NExpress consortium.  One school district and one public library district with four branches.  They often want results that encompass all of their libraries in one report and the "branches" parameter can't cover those circumstances.

My solution to this problem was to stop using the "branches" parameter after the pipe when I wanted a report with more flexibility.  I went ahead and created a new set of authorised values called "LBRANCH" that recreates all of the branch informaiton with a couple of changes.

First of all, the first value I created was "%" with a description called "All libraries."  Then, since all of the Doniphan county library district branches have a branchcode that starts with "DONI" and all of the school districts start with "PH," I created a value called "DON%" and a value called "PH%".

The second step was to re-write the SQL so that WHERE statistics.branch = <<Choose your branch|branches>> used the term "LIKE" instead of an equals sign.  The equals sign requires an exact match with no wildcards, but "LIKE" is a little more flexible because it can use wildcards.

The final step was to change "|branches" to "|LBRANCH".  The final result looks like this:

SELECT
  statistics.branch,
  count(*) AS CIRC_PLUS_RENEW
FROM
  statistics
WHERE
  (statistics.type = 'issue' OR
  statistics.type = 'renew') AND
  statistics.datetime BETWEEN "2017-07-01" AND "2017-08-01" AND
  statistics.branch LIKE <<Choose your branch|LBRANCH>>
GROUP BY
  statistics.branch

By doing this, I can select an individual branch, or I can select all branches.  I can also select the Doniphan county libraries one at a time, or I can select all of them at once.  I can also look at one of the schools in the district at a time, or I can see all of the school district libraries together.

I did discover a drawback, though.  If I used "|LBRANCH" on certain reports and chose "All branches," the report might shut down the system.  We have about 400,000 biblios, over 1,000,000 items, and about 125,000 patrons.  In some cases, asking Koha to deliver results for "All branches" could potentially slow down or crash the system.

So, I created a second alternative authorised values table called ZBRANCH that does the same things for Doniphan and the school district but omits the "All branches" option.  It looks like this in this sample query:

SELECT
  statistics.branch,
  count(*) AS CIRC_PLUS_RENEW
FROM
  statistics
WHERE
  (statistics.type = 'issue' OR
  statistics.type = 'renew') AND
  statistics.datetime BETWEEN "2017-07-01" AND "2017-08-01" AND
  statistics.branch LIKE <<Choose your branch|ZBRAN>>
GROUP BY
  statistics.branch

And I haven't stopped with branchcodes.  I have authorised values tables that cover collection codes, item types, patron categories and other variables that allow me to create flexible reports that can focus on one category of item or all categories of items.

The work-horse of these queries is the one called "Flexible weeding report."  It looks like this:

SELECT
  CONCAT( '<a href=\"/cgi-bin/koha/catalogue/detail.pl?biblionumber=', biblio.biblionumber,'\" target="_blank">', biblio.biblionumber, '</a>' ) AS LINK_TO_TITLE,
  items.itemnumber,
  items.homebranch,
  Concat("-",Coalesce(items.barcode, "-"),"-") AS BARCODE,
  items.location,
  items.itype,
  items.ccode,
  items.itemcallnumber,
  biblio.author,
  CONCAT_WS(' ', biblio.title, ExtractValue(biblioitems.marcxml, '//datafield[@tag="245"]/subfield[@code="b"]'), ExtractValue(biblioitems.marcxml, '//datafield[@tag="245"]/subfield[@code="p"]'), ExtractValue(biblioitems.marcxml, '//datafield[@tag="245"]/subfield[@code="n"]') ) AS FULL_TITLE,
  items.dateaccessioned,
  items.datelastborrowed,
  items.datelastseen,
  Sum((Coalesce(items.issues, 0)) + Coalesce(items.renewals, 0)) AS CHECKOUTS_PLUS_RENEWALS,
  IF(items.onloan IS NULL,'No','Yes') AS CHECKED_OUT,
  IF(SUM(coalesce(items.damaged,0) + coalesce(items.itemlost,0) + coalesce(items.withdrawn,0))=0,'No','Yes') AS STATUS_PROBLEMS,
  items.itemnotes,
  items.itemnotes_nonpublic
FROM
  items JOIN
  biblio
    ON items.biblionumber = biblio.biblionumber INNER JOIN
  biblioitems
    ON biblioitems.biblionumber = biblio.biblionumber AND
    items.biblioitemnumber = biblioitems.biblioitemnumber
WHERE
  items.homebranch LIKE <<Item home library|ZBRAN>> AND
  items.location LIKE <<Item shelving location|LLOC>> AND
  items.itype LIKE <<Item type|LITYPES>> AND
  items.ccode LIKE <<Item collection code|LCCODE>> AND
  items.dateaccessioned <= <<Item was added before|date>> AND
  Coalesce(items.datelastborrowed, "0") <= <<Date last borrowed was before|date>> AND
  items.datelastseen <= <<Date last seen was before|date>>
GROUP BY
  items.homebranch,
  BARCODE,
  items.location,
  items.itype,
  items.ccode,
  items.itemcallnumber,
  items.enumchron,
  biblio.author,
  biblio.title
HAVING CHECKOUTS_PLUS_RENEWALS <= <<With X or fewer checkouts|ZNUMBERS>> AND
  CHECKED_OUT LIKE <<Display checked out items|ZYES_NO>> AND
  STATUS_PROBLEMS LIKE <<Display lost, missing, and withdrawn items|ZYES_NO>>


A screenshot of it's parameter screen looks like this:


The creation of this report was, ultimately, a byproduct of laziness.  Within a month of arriving in Kansas I had people calling me saying "We normally use weeding report X, that Liz wrote in 2010, and I want that same report, I just want to be able to run it by collection code instead of by item type" or "I like weeding report Y but I want to limit it to items we added more than a year ago but will only let me limit based on the last seen date.  Can you make a copy that does that?" followed by Doniphan County staff asking if there could be a separate report for them that included all of their libraries and limited to things that had checked out fewer than 5 times.

This report was really a way for me to stop re-writing the same report every month for 4 different libraries.

Learning how to add new authorised values tables to Koha has the potential to give you a lot of flexibility in the reports you write.

Modifying the HOLD_SLIP receipt in Koha

When I first started working with the reciepts in Koha, I was particularly disappointed with the hold slip and the hold-transfer slip. I don't say this often, but this is one of two areas where I felt like the last proprietary ILS I used did a better job than Koha - at least "right out of the box," so to speak.

In the last proprietary ILS I used, if an item with a request on it was supposed to be held at our library, when it got to our library, it printed out a slip that said "Hold this for PATRON'S NAME" and if we checked in an item that had a request to be picked up somewhere else, the slip said "Send this somewhere else." They were actually two separate slips. The transit slip didn't print out any patron information (which we couldn't send through the courier system) and the "Hold at this library" slip didn't say "Transfer to/Hold in _____." It just said, "In transit to _____." In that respect, when I first started using Koha, I felt like the Hold/Transfer slip was a step backwards because it tries to use one slip to do two things.

Early on (and that was back in 2012) I had hoped I could create some Java or jQuery in Koha's IntranetSlipPrinterJS system preferences that could control what appears on an individual receipt. That turned out to be a big can of worms. I ended up fighting with the IntranetSlipPrinterJS settings and the JS Print plugin but I realized that using JS Print was going to be incredibly complicated.  At that time I worked for a library district that had 7 branches but our shared catalog consortium had 52 members so implementing JS Print at all of those libraries was going to be complicated, so I gave up on the receipts for a while and focused on other, more pressing things. Later on, though, I realized that since each receipt is 100% customizable, I could use HTML, CSS, Java, and jQuery to make any receipt for any library do whatever I wanted it to do.  I would actually have more flexibility than I would get from a one size fits all batch of jQuery that would be plugged into every receipt by a system preference if I sat down and wrote a new receipt for each library that I needed to write one for.

This is a walk-through of the steps I took to modify what is now called the "HOLD_SLIP" in Koha (used to be called "RESERVESLIP"). And I'm going to say at this stage that I am writing this explanation at a very basic level. If know HTML or work with CSS or Java or jQuery, I'm going to be going through things really slowly and that's because I'm absolutely sure that there are people in the audience who are reading this and even if I go slow, they will still have trouble with this -- not because they're not smart -- but because this work is outside of their primary area of experience. If you think I'm going slowly, it's because I don't want to lose the people that think I'm going too fast.

Also, in this post I'm going to be manipulating a receipt for the Digital Library branch in the NExpress consortium. There are things going on in NExpress that are going to be different than in your library. If you want to repeat this process at your library, you will need to know the branchcodes for the library whose slips you are manipulating and you're going to have to know which database fields are going to be important for your staff.

*************************************************

When first installed, the HOLD_SLIP data is:


<h5>Date: <<today>></h5>

<h3> Transfer to/Hold in <<branches.branchname>></h3>


<h3><<borrowers.surname>>, <<borrowers.firstname>></h3>


<ul>

    <li><<borrowers.cardnumber>></li>
    <li><<borrowers.phone>></li>
    <li> <<borrowers.address>><br />
         <<borrowers.address2>><br />
         <<borrowers.city>>  <<borrowers.zipcode>>
    </li>
    <li><<borrowers.email>></li>
</ul>
<br />
<h3>ITEM ON HOLD</h3>
<h4><<biblio.title>></h4>
<h5><<biblio.author>></h5>
<ul>
   <li><<items.barcode>></li>
   <li><<items.itemcallnumber>></li>
   <li><<reserves.waitingdate>></li>
</ul>
<p>Notes:
<<reserves.reservenotes>>



As a print-out this looks like:



*************************************************

This is the default slip that prints if the item needs to be shipped or if the item needs to go on the hold shelf at the location where you just checked it in.

As a transfer slip, this is not a good print-out because you can't stick it in the item for shipping because it has confidential patron contact information on it and this thing is going to be passing through the hands of a third party courier service.  As a slip to stick in a book on the hold shelf I found it inadequate because staff kept putting books that should have been shipped onto the hold shelf at our library because this hold and transfer slips were the same no matter if the item had reached its destination or not.

When I finally started working on modifying these slips, I started off by deleting the old slip altogether and putting all the tags for a web page into the slip:



<!DOCTYPE html>
<html>

  <head>



  </head>

  <body>



  </body>

</html>




*************************************************

Everything that is in the original receipt is important, but the borrower information is confidential and only really necessary when the item gets to its pickup location and the pickup location information is only really necessary if you're shipping the item to a different library.  So the next thing we're going to do is add some DIV tags to the body and create a space for the borrower information and the pickup location information to be stored in separate parts of the slip.  We'll give the first DIV an ID called "borrower" and the second one we'll call "loc_<<branches.branchcode>>".  The <<branches.branchcode>> portion of this is in double angle brackets because that part of this DIV ID is going to come from Koha.  Anything in double angles in the receipts is going to be something that Koha pulls out of the database, so, for NExpress, for example, if the pickup location is Paola Free Library, Koha is going to read this DIV ID as loc_PAOLA, but if the pickup location is the NEKLS office, the DIV ID will be loc_NEKLS.  In our example, the eventual result will be a DIV with the ID "loc_DIGITAL"


<!DOCTYPE html>
<html>

  <head>



  </head>

  <body>

    <div id="borrower">



    </div>

    <div id="loc_<<branches.branchcode>>">



    </div>

  </body>

</html>


*************************************************

And inside of the DIV for the borrower information we're going to add a second DIV and we're going to give this one an ID called "bor_<<branches.branchcode>>".  Having two DIVs may seem superflous, but it will become important when we add the code that controls what prints and when it prints.


<!DOCTYPE html>
<html>

  <head>



  </head>

  <body>

    <div id="borrower">
 
      <div id="bor_<<branches.branchcode>>">



      </div>
 
    </div>
 
    <div id="loc_<<branches.branchcode>>">
 
 
 
    </div>

  </body>

</html>


*************************************************

Next, we'll actually add the borrower's data to the "bor_<<branches.branchcode>>" DIV.  Here we'll be using some inline CSS to get the borrower's name on the left side of the page.  There is some code we'll add later to insert a pick-up date on the right hand side of the page at the top, so we'll need the CSS here to make sure the patron's name is at the top on the left.  You also may notice that there is a borrower attribute called "HOLD." That's a NExpress patron attribute we use to help libraries identify a patron's preferred contact method, so you probably won't see that attribute on your system.


<!DOCTYPE html>
<html>

  <head>



  </head>

  <body>

    <div id="borrower">
 
      <div id="bor_<<branches.branchcode>>">
   
        <h2 style="text-align: left"><<borrowers.surname>>,<br>
        <<borrowers.firstname>></h2><br>
        <br>
        <br>
        <h3>Hold at <<branches.branchname>></h3>
        <ul>
          <li><<borrowers.cardnumber>></li>
          <li><<borrowers.phone>></li>
          <li><<borrowers.email>></li>
          <li><<borrower-attribute:HOLD>></li>
        </ul><br>
        <h3>ITEM ON HOLD</h3>
        <ul>
          <li><<items.itemcallnumber>> // <<biblio.title>> // <<biblio.author>></li>
          <li><<items.barcode>></li>
          <li>Available since: <<reserves.waitingdate>></li>
        </ul>
        <p>Notes:<br>
        <<reserves.reservenotes>></p><br>
       
      </div>
 
    </div>
 
    <div id="loc_<<branches.branchcode>>">
 
 
 
    </div>

  </body>

</html>


*************************************************

Now we'll add the pickup location information to the "loc_<<branches.branchcode>>" DIV.  And here I'll point out that NExpress uses the "Notes" field in a library's name to indicate their library's code for the Kansas Library Express courier system.  That note does get prominence because it's a major part of how we ship things.  In another library system, you'd obviously want to figure out what order and what emphasis you'd want to give to various elements of the final receipt.


<!DOCTYPE html>
<html>

  <head>



  </head>

  <body>

    <div id="borrower">
 
      <div id="bor_<<branches.branchcode>>">
   
        <h2 style="text-align:left"><<borrowers.surname>>,<br>
        <<borrowers.firstname>></h2><br>
        <br>
        <br>
        <h3>Hold at <<branches.branchname>></h3>
        <ul>
          <li><<borrowers.cardnumber>></li>
          <li><<borrowers.phone>></li>
          <li><<borrowers.email>></li>
          <li><<borrower-attribute:HOLD>></li>
        </ul><br>
        <h3>ITEM ON HOLD</h3>
        <ul>
          <li><<items.itemcallnumber>> // <<biblio.title>> // <<biblio.author>></li>
          <li><<items.barcode>></li>
          <li>Available since: <<reserves.waitingdate>></li>
        </ul>
        <p>Notes:<br>
        <<reserves.reservenotes>></p><br>
       
      </div>
 
    </div>
 
    <div id="loc_<<branches.branchcode>>">
 
      <h1 style="font-size: 48px;"><<branches.branchnotes>></h1><br>
      <br>
      <br>
      <p>Ship to:</p>
      <h1><<branches.branchname>></h1>
      <h1><<branches.branchaddress1>></h1>
      <h1><<branches.branchcity>>, <<branches.branchstate>> <<branches.branchzip>></h1>
      <p> </p>
      <p><<items.itemcallnumber>></p>
      <p><<biblio.title>></p>
      <p><<biblio.author>></p>
      <p><<items.barcode>></p>
      <p> </p>
      <p>Shipped on: <<today>></p>
      <p> </p>
      <p>Shipped to: <<branches.branchcode>></p>
      <p> </p>
      <p>This slip generated at DIGITAL</p>
      <p> </p>
 
    </div>

  </body>

</html>


*************************************************

When we're this far along, the receipt starts to look like this:



It still has the patron information and the pickup location on one slip, but they're broken up really well into two distinct areas.


*************************************************

Next we start to add some code so we can decide what appears on the final receipt and what stays hidden and when.  First we'll some inline CSS to make the borrower DIV invisible - style="display: none;"

This code hides everything in the borrower DIV but in just a few minutes we'll add some jQuery to unhide it if the item is at its destination library.


<!DOCTYPE html>
<html>

  <head>



  </head>

  <body>

    <div id="borrower" style="display: none;">
 
      <div id="bor_<<branches.branchcode>>">
   
        <h2 style="text-align:left"><<borrowers.surname>>,<br>
        <<borrowers.firstname>></h2><br>
        <br>
        <br>
        <h3>Hold at <<branches.branchname>></h3>
        <ul>
          <li><<borrowers.cardnumber>></li>
          <li><<borrowers.phone>></li>
          <li><<borrowers.email>></li>
          <li><<borrower-attribute:HOLD>></li>
        </ul><br>
        <h3>ITEM ON HOLD</h3>
        <ul>
          <li><<items.itemcallnumber>> // <<biblio.title>> // <<biblio.author>></li>
          <li><<items.barcode>></li>
          <li>Available since: <<reserves.waitingdate>></li>
        </ul>
        <p>Notes:<br>
        <<reserves.reservenotes>></p><br>
       
      </div>
 
    </div>
 
    <div id="loc_<<branches.branchcode>>">
 
      <h1 style="font-size: 48px;"><<branches.branchnotes>></h1><br>
      <br>
      <br>
      <p>Ship to:</p>
      <h1><<branches.branchname>></h1>
      <h1><<branches.branchaddress1>></h1>
      <h1><<branches.branchcity>>, <<branches.branchstate>> <<branches.branchzip>></h1>
      <p> </p>
      <p><<items.itemcallnumber>></p>
      <p><<biblio.title>></p>
      <p><<biblio.author>></p>
      <p><<items.barcode>></p>
      <p> </p>
      <p>Shipped on: <<today>></p>
      <p> </p>
      <p>Shipped to: <<branches.branchcode>></p>
      <p> </p>
      <p>This slip generated at DIGITAL</p>
      <p> </p>
 
    </div>

  </body>

</html>


*************************************************

Then we'll add some script tags and the jQuery "document ready function" to the header.  This will allow us to add some jQuery that will control what stays invisible and what gets hidden.


<!DOCTYPE html>
<html>

  <head>

    <script type="text/javascript">

      $(document).ready(function(){




      });


    </script>




  </head>

  <body>

    <div id="borrower" style="display: none;">
 
      <div id="bor_<<branches.branchcode>>">
   
        <h2 style="text-align:left"><<borrowers.surname>>,<br>
        <<borrowers.firstname>></h2><br>
        <br>
        <br>
        <h3>Hold at <<branches.branchname>></h3>
        <ul>
          <li><<borrowers.cardnumber>></li>
          <li><<borrowers.phone>></li>
          <li><<borrowers.email>></li>
          <li><<borrower-attribute:HOLD>></li>
        </ul><br>
        <h3>ITEM ON HOLD</h3>
        <ul>
          <li><<items.itemcallnumber>> // <<biblio.title>> // <<biblio.author>></li>
          <li><<items.barcode>></li>
          <li>Available since: <<reserves.waitingdate>></li>
        </ul>
        <p>Notes:<br>
        <<reserves.reservenotes>></p><br>
       
      </div>
 
    </div>
 
    <div id="loc_<<branches.branchcode>>">
 
      <h1 style="font-size: 48px;"><<branches.branchnotes>></h1><br>
      <br>
      <br>
      <p>Ship to:</p>
      <h1><<branches.branchname>></h1>
      <h1><<branches.branchaddress1>></h1>
      <h1><<branches.branchcity>>, <<branches.branchstate>> <<branches.branchzip>></h1>
      <p> </p>
      <p><<items.itemcallnumber>></p>
      <p><<biblio.title>></p>
      <p><<biblio.author>></p>
      <p><<items.barcode>></p>
      <p> </p>
      <p>Shipped on: <<today>></p>
      <p> </p>
      <p>Shipped to: <<branches.branchcode>></p>
      <p> </p>
      <p>This slip generated at DIGITAL</p>
      <p> </p>
 
    </div>

  </body>

</html>


*************************************************

Then we'll add jQuery that unhides the borrower information if the library where we are checking the item in at equals the library where the item is supposed to be picked up at.

This code is going to include #bor_THISSLIP'SBRANCHCODE as the selector.  The actual jQuery being used in this example will be |$("#bor_DIGITAL").parent().removeAttr('style');| and what this piece of code is saying is that "If <div id="bor_<<branches.branchcode>>"> has an ID equal to 'bor_DIGITAL' (because remember that <<branches.branchcode>> is going to change based on the request's pickup location), then remove the 'style="display: none;"' CSS from this section of the receipt."  So, if the pick-up library the patron has chosen is DIGITAL, then their borrower information will print on the final slip.


<!DOCTYPE html>
<html>

  <head>

    <script type="text/javascript">

      $(document).ready(function(){

          $("#bor_DIGITAL").parent().removeAttr('style');
   
      });

  </script>


  </head>

  <body>

    <div id="borrower" style="display: none;">
 
      <div id="bor_<<branches.branchcode>>">
   
        <h2 style="text-align:left"><<borrowers.surname>>,<br>
        <<borrowers.firstname>></h2><br>
        <br>
        <br>
        <h3>Hold at <<branches.branchname>></h3>
        <ul>
          <li><<borrowers.cardnumber>></li>
          <li><<borrowers.phone>></li>
          <li><<borrowers.email>></li>
          <li><<borrower-attribute:HOLD>></li>
        </ul><br>
        <h3>ITEM ON HOLD</h3>
        <ul>
          <li><<items.itemcallnumber>> // <<biblio.title>> // <<biblio.author>></li>
          <li><<items.barcode>></li>
          <li>Available since: <<reserves.waitingdate>></li>
        </ul>
        <p>Notes:<br>
        <<reserves.reservenotes>></p><br>
       
      </div>
 
    </div>
 
    <div id="loc_<<branches.branchcode>>">
 
      <h1 style="font-size: 48px;"><<branches.branchnotes>></h1><br>
      <br>
      <br>
      <p>Ship to:</p>
      <h1><<branches.branchname>></h1>
      <h1><<branches.branchaddress1>></h1>
      <h1><<branches.branchcity>>, <<branches.branchstate>> <<branches.branchzip>></h1>
      <p> </p>
      <p><<items.itemcallnumber>></p>
      <p><<biblio.title>></p>
      <p><<biblio.author>></p>
      <p><<items.barcode>></p>
      <p> </p>
      <p>Shipped on: <<today>></p>
      <p> </p>
      <p>Shipped to: <<branches.branchcode>></p>
      <p> </p>
      <p>This slip generated at DIGITAL</p>
      <p> </p>
 
    </div>

  </body>

</html>


*************************************************

Then we'll add jQuery that hides the destination library section


<!DOCTYPE html>
<html>

  <head>

    <script type="text/javascript">

      $(document).ready(function(){

          $("#bor_DIGITAL").parent().removeAttr('style');
          $("#loc_DIGITAL").hide();

      });


  </script>

  <style>



  </style>
 
  </head>

  <body>

    <div id="borrower" style="display: none;">
 
      <div id="bor_<<branches.branchcode>>">
   
        <h2 style="text-align:left"><<borrowers.surname>>,<br>
        <<borrowers.firstname>></h2><br>
        <br>
        <br>
        <h3>Hold at <<branches.branchname>></h3>
        <ul>
          <li><<borrowers.cardnumber>></li>
          <li><<borrowers.phone>></li>
          <li><<borrowers.email>></li>
          <li><<borrower-attribute:HOLD>></li>
        </ul><br>
        <h3>ITEM ON HOLD</h3>
        <ul>
          <li><<items.itemcallnumber>> // <<biblio.title>> // <<biblio.author>></li>
          <li><<items.barcode>></li>
          <li>Available since: <<reserves.waitingdate>></li>
        </ul>
        <p>Notes:<br>
        <<reserves.reservenotes>></p><br>
       
      </div>
 
    </div>
 
    <div id="loc_<<branches.branchcode>>">
 
      <h1 style="font-size: 48px;"><<branches.branchnotes>></h1><br>
      <br>
      <br>
      <p>Ship to:</p>
      <h1><<branches.branchname>></h1>
      <h1><<branches.branchaddress1>></h1>
      <h1><<branches.branchcity>>, <<branches.branchstate>> <<branches.branchzip>></h1>
      <p> </p>
      <p><<items.itemcallnumber>></p>
      <p><<biblio.title>></p>
      <p><<biblio.author>></p>
      <p><<items.barcode>></p>
      <p> </p>
      <p>Shipped on: <<today>></p>
      <p> </p>
      <p>Shipped to: <<branches.branchcode>></p>
      <p> </p>
      <p>This slip generated at DIGITAL</p>
      <p> </p>
 
    </div>

  </body>

</html>


*************************************************

The end result of all of this is a receipt that looks like this when the item needs to go on the hold shelf



and this when it needs to be shipped



*************************************************

The next thing I did when I first set this up was to add some CSS to control the location of the hold expiration date.  Later on I also learned how to use this to force the size of the page to certain parameters.  To do both of these things, we need to add a style tag into the head of the document.


<!DOCTYPE html>
<html>

  <head>

    <script type="text/javascript">

      $(document).ready(function(){

          $("#bor_DIGITAL").parent().removeAttr('style');
          $("#loc_DIGITAL").hide();
   
      });

  </script>

  <style>



  </style>

 
  </head>

  <body>

    <div id="borrower" style="display: none;">
 
      <div id="bor_<<branches.branchcode>>">
   
        <h2 style="text-align:left"><<borrowers.surname>>,<br>
        <<borrowers.firstname>></h2><br>
        <br>
        <br>
        <h3>Hold at <<branches.branchname>></h3>
        <ul>
          <li><<borrowers.cardnumber>></li>
          <li><<borrowers.phone>></li>
          <li><<borrowers.email>></li>
          <li><<borrower-attribute:HOLD>></li>
        </ul><br>
        <h3>ITEM ON HOLD</h3>
        <ul>
          <li><<items.itemcallnumber>> // <<biblio.title>> // <<biblio.author>></li>
          <li><<items.barcode>></li>
          <li>Available since: <<reserves.waitingdate>></li>
        </ul>
        <p>Notes:<br>
        <<reserves.reservenotes>></p><br>
       
      </div>
 
    </div>
 
    <div id="loc_<<branches.branchcode>>">
 
      <h1 style="font-size: 48px;"><<branches.branchnotes>></h1><br>
      <br>
      <br>
      <p>Ship to:</p>
      <h1><<branches.branchname>></h1>
      <h1><<branches.branchaddress1>></h1>
      <h1><<branches.branchcity>>, <<branches.branchstate>> <<branches.branchzip>></h1>
      <p> </p>
      <p><<items.itemcallnumber>></p>
      <p><<biblio.title>></p>
      <p><<biblio.author>></p>
      <p><<items.barcode>></p>
      <p> </p>
      <p>Shipped on: <<today>></p>
      <p> </p>
      <p>Shipped to: <<branches.branchcode>></p>
      <p> </p>
      <p>This slip generated at DIGITAL</p>
      <p> </p>
 
    </div>

  </body>

</html>


*************************************************

The first piece of CSS we add will control the margins and the size of the printable area on the page.

This code also sets the left margin just a little inside of the left side of the page which I find helps the receipts come out better when you have the margins of Firefox or Chrome set to 0 all the way around.


<!DOCTYPE html>
<html>

  <head>

    <script type="text/javascript">

      $(document).ready(function(){

          $("#bor_DIGITAL").parent().removeAttr('style');
          $("#loc_DIGITAL").hide();
   
      });

  </script>

  <style>

    body {width: 245px; margin-top: 0; margin-bottom: 0; margin-right: 0; margin-left: 20px}

  </style>
 
  </head>

  <body>

    <div id="borrower" style="display: none;">
 
      <div id="bor_<<branches.branchcode>>">
   
        <h2 style="text-align:left"><<borrowers.surname>>,<br>
        <<borrowers.firstname>></h2><br>
        <br>
        <br>
        <h3>Hold at <<branches.branchname>></h3>
        <ul>
          <li><<borrowers.cardnumber>></li>
          <li><<borrowers.phone>></li>
          <li><<borrowers.email>></li>
          <li><<borrower-attribute:HOLD>></li>
        </ul><br>
        <h3>ITEM ON HOLD</h3>
        <ul>
          <li><<items.itemcallnumber>> // <<biblio.title>> // <<biblio.author>></li>
          <li><<items.barcode>></li>
          <li>Available since: <<reserves.waitingdate>></li>
        </ul>
        <p>Notes:<br>
        <<reserves.reservenotes>></p><br>
       
      </div>
 
    </div>
 
    <div id="loc_<<branches.branchcode>>">
 
      <h1 style="font-size: 48px;"><<branches.branchnotes>></h1><br>
      <br>
      <br>
      <p>Ship to:</p>
      <h1><<branches.branchname>></h1>
      <h1><<branches.branchaddress1>></h1>
      <h1><<branches.branchcity>>, <<branches.branchstate>> <<branches.branchzip>></h1>
      <p> </p>
      <p><<items.itemcallnumber>></p>
      <p><<biblio.title>></p>
      <p><<biblio.author>></p>
      <p><<items.barcode>></p>
      <p> </p>
      <p>Shipped on: <<today>></p>
      <p> </p>
      <p>Shipped to: <<branches.branchcode>></p>
      <p> </p>
      <p>This slip generated at DIGITAL</p>
      <p> </p>
 
    </div>

  </body>

</html>


*************************************************

The second piece of CSS gives us way of right-justifying a "Hold till" date on the right hand side of the page opposite the patron's name.  To do this we'll use the HTML "article" tag and a class we'll call "right."


<!DOCTYPE html>
<html>

  <head>

    <script type="text/javascript">

      $(document).ready(function(){

          $("#bor_DIGITAL").parent().removeAttr('style');
          $("#loc_DIGITAL").hide();
       
      });

  </script>

  <style>

    body {width: 245px; margin-top: 0; margin-bottom: 0; margin-right: 0; margin-left: 20px}
    article{display:inline-block}
    .right{float:right}

  </style>
 
  </head>

  <body>

    <div id="borrower" style="display: none;">
 
      <div id="bor_<<branches.branchcode>>">
   
        <h2 style="text-align:left"><<borrowers.surname>>,<br>
        <<borrowers.firstname>></h2><br>
        <br>
        <br>
        <h3>Hold at <<branches.branchname>></h3>
        <ul>
          <li><<borrowers.cardnumber>></li>
          <li><<borrowers.phone>></li>
          <li><<borrowers.email>></li>
          <li><<borrower-attribute:HOLD>></li>
        </ul><br>
        <h3>ITEM ON HOLD</h3>
        <ul>
          <li><<items.itemcallnumber>> // <<biblio.title>> // <<biblio.author>></li>
          <li><<items.barcode>></li>
          <li>Available since: <<reserves.waitingdate>></li>
        </ul>
        <p>Notes:<br>
        <<reserves.reservenotes>></p><br>
       
      </div>
 
    </div>
 
    <div id="loc_<<branches.branchcode>>">
 
      <h1 style="font-size: 48px;"><<branches.branchnotes>></h1><br>
      <br>
      <br>
      <p>Ship to:</p>
      <h1><<branches.branchname>></h1>
      <h1><<branches.branchaddress1>></h1>
      <h1><<branches.branchcity>>, <<branches.branchstate>> <<branches.branchzip>></h1>
      <p> </p>
      <p><<items.itemcallnumber>></p>
      <p><<biblio.title>></p>
      <p><<biblio.author>></p>
      <p><<items.barcode>></p>
      <p> </p>
      <p>Shipped on: <<today>></p>
      <p> </p>
      <p>Shipped to: <<branches.branchcode>></p>
      <p> </p>
      <p>This slip generated at DIGITAL</p>
      <p> </p>
 
    </div>

  </body>

</html>


*************************************************

Finally, we'll add the hold expiration date to the borrower information wrapped inside the article tag and I'll give the article tag a "right" class.  This will add the "Hold till" date information to the top of the receipt.


<!DOCTYPE html>
<html>

  <head>

    <script type="text/javascript">

      $(document).ready(function(){

          $("#bor_DIGITAL").parent().removeAttr('style');
          $("#loc_DIGITAL").hide();
       
      });

  </script>

  <style>

    body {width: 245px; margin-top: 0; margin-bottom: 0; margin-right: 0; margin-left: 20px}
    article{display:inline-block}
    .right{float:right}

  </style>
 
  </head>

  <body>

    <div id="borrower" style="display: none;">
 
      <div id="bor_<<branches.branchcode>>">
   
        <article class="right">
          <h2>Hold till: <<reserves.expirationdate>></h2>
        </article>    
   
        <h2 style="text-align:left"><<borrowers.surname>>,<br>
        <<borrowers.firstname>></h2><br>
        <br>
        <br>
        <h3>Hold at <<branches.branchname>></h3>
        <ul>
          <li><<borrowers.cardnumber>></li>
          <li><<borrowers.phone>></li>
          <li><<borrowers.email>></li>
          <li><<borrower-attribute:HOLD>></li>
        </ul><br>
        <h3>ITEM ON HOLD</h3>
        <ul>
          <li><<items.itemcallnumber>> // <<biblio.title>> // <<biblio.author>></li>
          <li><<items.barcode>></li>
          <li>Available since: <<reserves.waitingdate>></li>
        </ul>
        <p>Notes:<br>
        <<reserves.reservenotes>></p><br>
       
      </div>
 
    </div>
 
    <div id="loc_<<branches.branchcode>>">
 
      <h1 style="font-size: 48px;"><<branches.branchnotes>></h1><br>
      <br>
      <br>
      <p>Ship to:</p>
      <h1><<branches.branchname>></h1>
      <h1><<branches.branchaddress1>></h1>
      <h1><<branches.branchcity>>, <<branches.branchstate>> <<branches.branchzip>></h1>
      <p> </p>
      <p><<items.itemcallnumber>></p>
      <p><<biblio.title>></p>
      <p><<biblio.author>></p>
      <p><<items.barcode>></p>
      <p> </p>
      <p>Shipped on: <<today>></p>
      <p> </p>
      <p>Shipped to: <<branches.branchcode>></p>
      <p> </p>
      <p>This slip generated at DIGITAL</p>
      <p> </p>
 
    </div>

  </body>

</html>


*************************************************

When I was at Latah County Library District, I also added a checklist for phone calls to the bottom of the receipt.

If the patron had an e-mail address in their account, we did not phone the patron when their requests came in.  The volume, particularly at the Moscow branch of LCLD was often over 150 items added to the hold shelf each day, so it was impractical to phone patrons if they had an e-mail address, but we did phone every patron who didn't have an e-mail address attached to their account.

During my time there, staff at the Moscow branch had an elaborate shorthand for marking the hold slips to indicate whether or not the patron had been phoned, whether staff had talked to a real live person, or left a message on their voice mail, or if we were unable to contact the patron because of a disconnected number, etc.

Because the shorthand was confusing and inconsistently applied, I added some more parameters to the LCLD HOLD_SLIP html in order to add a checklist to the bottom of the receipt if the patron did not have an e-mail address.

This requires a new "checklist" DIV down at the bottom of the page that we will call "check_<<branches.branchcode>>" and which we will hide by default.  We'll also add a horizontal line to delineate this section from the other sections.


<!DOCTYPE html>
<html>

  <head>

    <script type="text/javascript">

      $(document).ready(function(){

          $("#bor_DIGITAL").parent().removeAttr('style');
          $("#loc_DIGITAL").hide();
       
      });

  </script>

  <style>

    body {width: 245px; margin-top: 0; margin-bottom: 0; margin-right: 0; margin-left: 20px}
    article{display:inline-block}
    .right{float:right}

  </style>
 
  </head>

  <body>

    <div id="borrower" style="display: none;">
 
      <div id="bor_<<branches.branchcode>>">
   
        <article class="right">
          <h2>Hold till: <<reserves.expirationdate>></h2>
        </article>    
   
        <h2 style="text-align:left"><<borrowers.surname>>,<br>
        <<borrowers.firstname>></h2><br>
        <br>
        <br>
        <h3>Hold at <<branches.branchname>></h3>
        <ul>
          <li><<borrowers.cardnumber>></li>
          <li><<borrowers.phone>></li>
          <li><<borrowers.email>></li>
          <li><<borrower-attribute:HOLD>></li>
        </ul><br>
        <h3>ITEM ON HOLD</h3>
        <ul>
          <li><<items.itemcallnumber>> // <<biblio.title>> // <<biblio.author>></li>
          <li><<items.barcode>></li>
          <li>Available since: <<reserves.waitingdate>></li>
        </ul>
        <p>Notes:<br>
        <<reserves.reservenotes>></p><br>
       
      </div>
 
    </div>
 
    <div id="loc_<<branches.branchcode>>">
 
      <h1 style="font-size: 48px;"><<branches.branchnotes>></h1><br>
      <br>
      <br>
      <p>Ship to:</p>
      <h1><<branches.branchname>></h1>
      <h1><<branches.branchaddress1>></h1>
      <h1><<branches.branchcity>>, <<branches.branchstate>> <<branches.branchzip>></h1>
      <p> </p>
      <p><<items.itemcallnumber>></p>
      <p><<biblio.title>></p>
      <p><<biblio.author>></p>
      <p><<items.barcode>></p>
      <p> </p>
      <p>Shipped on: <<today>></p>
      <p> </p>
      <p>Shipped to: <<branches.branchcode>></p>
      <p> </p>
      <p>This slip generated at DIGITAL</p>
      <p> </p>
 
    </div>

    <div id="check_<<branches.branchcode>>" style="display:none">

      <hr />




    </div>


  </body>

</html>


*************************************************

Then we're going to add another DIV to the checklist DIV we just created called "list" and we're going to hide it too.


<!DOCTYPE html>
<html>

  <head>

    <script type="text/javascript">

      $(document).ready(function(){

          $("#bor_DIGITAL").parent().removeAttr('style');
          $("#loc_DIGITAL").hide();
       
      });

  </script>

  <style>

    body {width: 245px; margin-top: 0; margin-bottom: 0; margin-right: 0; margin-left: 20px}
    article{display:inline-block}
    .right{float:right}

  </style>
 
  </head>

  <body>

    <div id="borrower" style="display: none;">
 
      <div id="bor_<<branches.branchcode>>">
   
        <article class="right">
          <h2>Hold till: <<reserves.expirationdate>></h2>
        </article>    
   
        <h2 style="text-align:left"><<borrowers.surname>>,<br>
        <<borrowers.firstname>></h2><br>
        <br>
        <br>
        <h3>Hold at <<branches.branchname>></h3>
        <ul>
          <li><<borrowers.cardnumber>></li>
          <li><<borrowers.phone>></li>
          <li><<borrowers.email>></li>
          <li><<borrower-attribute:HOLD>></li>
        </ul><br>
        <h3>ITEM ON HOLD</h3>
        <ul>
          <li><<items.itemcallnumber>> // <<biblio.title>> // <<biblio.author>></li>
          <li><<items.barcode>></li>
          <li>Available since: <<reserves.waitingdate>></li>
        </ul>
        <p>Notes:<br>
        <<reserves.reservenotes>></p><br>
       
      </div>
 
    </div>
 
    <div id="loc_<<branches.branchcode>>">
 
      <h1 style="font-size: 48px;"><<branches.branchnotes>></h1><br>
      <br>
      <br>
      <p>Ship to:</p>
      <h1><<branches.branchname>></h1>
      <h1><<branches.branchaddress1>></h1>
      <h1><<branches.branchcity>>, <<branches.branchstate>> <<branches.branchzip>></h1>
      <p> </p>
      <p><<items.itemcallnumber>></p>
      <p><<biblio.title>></p>
      <p><<biblio.author>></p>
      <p><<items.barcode>></p>
      <p> </p>
      <p>Shipped on: <<today>></p>
      <p> </p>
      <p>Shipped to: <<branches.branchcode>></p>
      <p> </p>
      <p>This slip generated at DIGITAL</p>
      <p> </p>
 
    </div>

    <div id="check_<<branches.branchcode>>" style="display:none">

      <hr />

        <div id="list" style="display:none">



        </div>

    </div>

  </body>

</html>


*************************************************

Then we're going to hide the patron's e-mail address inside this DIV.  This gives us something we can use later in the code as part of a logical operation.


<!DOCTYPE html>
<html>

  <head>

    <script type="text/javascript">

      $(document).ready(function(){

          $("#bor_DIGITAL").parent().removeAttr('style');
          $("#loc_DIGITAL").hide();
       
      });

  </script>

  <style>

    body {width: 245px; margin-top: 0; margin-bottom: 0; margin-right: 0; margin-left: 20px}
    article{display:inline-block}
    .right{float:right}

  </style>
 
  </head>

  <body>

    <div id="borrower" style="display: none;">
 
      <div id="bor_<<branches.branchcode>>">
   
        <article class="right">
          <h2>Hold till: <<reserves.expirationdate>></h2>
        </article>    
   
        <h2 style="text-align:left"><<borrowers.surname>>,<br>
        <<borrowers.firstname>></h2><br>
        <br>
        <br>
        <h3>Hold at <<branches.branchname>></h3>
        <ul>
          <li><<borrowers.cardnumber>></li>
          <li><<borrowers.phone>></li>
          <li><<borrowers.email>></li>
          <li><<borrower-attribute:HOLD>></li>
        </ul><br>
        <h3>ITEM ON HOLD</h3>
        <ul>
          <li><<items.itemcallnumber>> // <<biblio.title>> // <<biblio.author>></li>
          <li><<items.barcode>></li>
          <li>Available since: <<reserves.waitingdate>></li>
        </ul>
        <p>Notes:<br>
        <<reserves.reservenotes>></p><br>
       
      </div>
 
    </div>
 
    <div id="loc_<<branches.branchcode>>">
 
      <h1 style="font-size: 48px;"><<branches.branchnotes>></h1><br>
      <br>
      <br>
      <p>Ship to:</p>
      <h1><<branches.branchname>></h1>
      <h1><<branches.branchaddress1>></h1>
      <h1><<branches.branchcity>>, <<branches.branchstate>> <<branches.branchzip>></h1>
      <p> </p>
      <p><<items.itemcallnumber>></p>
      <p><<biblio.title>></p>
      <p><<biblio.author>></p>
      <p><<items.barcode>></p>
      <p> </p>
      <p>Shipped on: <<today>></p>
      <p> </p>
      <p>Shipped to: <<branches.branchcode>></p>
      <p> </p>
      <p>This slip generated at DIGITAL</p>
      <p> </p>
 
    </div>

    <div id="check_<<branches.branchcode>>" style="display:none">

      <hr />

        <div id="list" style="display:none">
     
          <h5 style="display:none"><<borrowers.email>></h5>
     
        </div>

    </div>

  </body>

</html>


*************************************************

Then we will throw in the rest of this checklist.


<!DOCTYPE html>
<html>

  <head>

    <script type="text/javascript">

      $(document).ready(function(){

          $("#bor_DIGITAL").parent().removeAttr('style');
          $("#loc_DIGITAL").hide();
       
      });

  </script>

  <style>

    body {width: 245px; margin-top: 0; margin-bottom: 0; margin-right: 0; margin-left: 20px}
    article{display:inline-block}
    .right{float:right}

  </style>
 
  </head>

  <body>

    <div id="borrower" style="display: none;">
 
      <div id="bor_<<branches.branchcode>>">
   
        <article class="right">
          <h2>Hold till: <<reserves.expirationdate>></h2>
        </article>    
   
        <h2 style="text-align:left"><<borrowers.surname>>,<br>
        <<borrowers.firstname>></h2><br>
        <br>
        <br>
        <h3>Hold at <<branches.branchname>></h3>
        <ul>
          <li><<borrowers.cardnumber>></li>
          <li><<borrowers.phone>></li>
          <li><<borrowers.email>></li>
          <li><<borrower-attribute:HOLD>></li>
        </ul><br>
        <h3>ITEM ON HOLD</h3>
        <ul>
          <li><<items.itemcallnumber>> // <<biblio.title>> // <<biblio.author>></li>
          <li><<items.barcode>></li>
          <li>Available since: <<reserves.waitingdate>></li>
        </ul>
        <p>Notes:<br>
        <<reserves.reservenotes>></p><br>
       
      </div>
 
    </div>
 
    <div id="loc_<<branches.branchcode>>">
 
      <h1 style="font-size: 48px;"><<branches.branchnotes>></h1><br>
      <br>
      <br>
      <p>Ship to:</p>
      <h1><<branches.branchname>></h1>
      <h1><<branches.branchaddress1>></h1>
      <h1><<branches.branchcity>>, <<branches.branchstate>> <<branches.branchzip>></h1>
      <p> </p>
      <p><<items.itemcallnumber>></p>
      <p><<biblio.title>></p>
      <p><<biblio.author>></p>
      <p><<items.barcode>></p>
      <p> </p>
      <p>Shipped on: <<today>></p>
      <p> </p>
      <p>Shipped to: <<branches.branchcode>></p>
      <p> </p>
      <p>This slip generated at DIGITAL</p>
      <p> </p>
 
    </div>

    <div id="check_<<branches.branchcode>>" style="display:none">

      <hr />

      <div id="list" style="display:none">

        <h5 style="display:none"><<borrowers.email>></h5>

        <h2>Phone call checklist</h2>

        <h3>Circle one:</h3>


        <p>Spoke directly with the patron.</p>


        <p>Left message with person who answered the phone.</p>


        <p>Left message on answering machine / voice mail.</p>


        <p>Please send a postcard to the patron if you cannot contact them by other means within 24 hours of the requested item's arrival.</p>


        <br />


        <hr />


      </div>

    </div>

  </body>

</html>


*************************************************

Next we're going to go back and add an ID to the "Hold till" date.  We're going to give it the ID "pudate" so that we can use jQuery to modify the text that appears if the patron needs to be phoned.  And then we'll hide a span inside that h2 tag that includes the patron's e-mail address.


<!DOCTYPE html>
<html>

  <head>

    <script type="text/javascript">

      $(document).ready(function(){

          $("#bor_DIGITAL").parent().removeAttr('style');
          $("#loc_DIGITAL").hide();
       
      });

  </script>

  <style>

    body {width: 245px; margin-top: 0; margin-bottom: 0; margin-right: 0; margin-left: 20px}
    article{display:inline-block}
    .right{float:right}

  </style>
 
  </head>

  <body>

    <div id="borrower" style="display: none;">
 
      <div id="bor_<<branches.branchcode>>">
   
        <article class="right">
          <h2 id="pudate">Hold till: <<reserves.expirationdate>> <span style="display: none;"><<borrowers.email>></span></h2>
        </article>    
   
        <h2 style="text-align:left"><<borrowers.surname>>,<br>
        <<borrowers.firstname>></h2><br>
        <br>
        <br>
        <h3>Hold at <<branches.branchname>></h3>
        <ul>
          <li><<borrowers.cardnumber>></li>
          <li><<borrowers.phone>></li>
          <li><<borrowers.email>></li>
          <li><<borrower-attribute:HOLD>></li>
        </ul><br>
        <h3>ITEM ON HOLD</h3>
        <ul>
          <li><<items.itemcallnumber>> // <<biblio.title>> // <<biblio.author>></li>
          <li><<items.barcode>></li>
          <li>Available since: <<reserves.waitingdate>></li>
        </ul>
        <p>Notes:<br>
        <<reserves.reservenotes>></p><br>
       
      </div>
 
    </div>
 
    <div id="loc_<<branches.branchcode>>">
 
      <h1 style="font-size: 48px;"><<branches.branchnotes>></h1><br>
      <br>
      <br>
      <p>Ship to:</p>
      <h1><<branches.branchname>></h1>
      <h1><<branches.branchaddress1>></h1>
      <h1><<branches.branchcity>>, <<branches.branchstate>> <<branches.branchzip>></h1>
      <p> </p>
      <p><<items.itemcallnumber>></p>
      <p><<biblio.title>></p>
      <p><<biblio.author>></p>
      <p><<items.barcode>></p>
      <p> </p>
      <p>Shipped on: <<today>></p>
      <p> </p>
      <p>Shipped to: <<branches.branchcode>></p>
      <p> </p>
      <p>This slip generated at DIGITAL</p>
      <p> </p>
 
    </div>

    <div id="check_<<branches.branchcode>>" style="display:none">

      <hr />

      <div id="list" style="display:none">

        <h5 style="display:none"><<borrowers.email>></h5>

        <h2>Phone call checklist</h2>

        <h3>Circle one:</h3>

        <p>Spoke directly with the patron.</p>

        <p>Left message with person who answered the phone.</p>

        <p>Left message on answering machine / voice mail.</p>

        <p>Please send a postcard to the patron if you cannot contact them by other means within 24 hours of the requested item's arrival.</p>

        <br />

        <hr />

      </div>

    </div>

  </body>

</html>


*************************************************

Now we're going to start adding the additional jQuery.

First we'll add the jQuery to work with the ID we just added to the pickup date.  When I was at Latah County Library District we held the items for patrons we phoned for 7 days from the date we called them rather than 7 days from the day that the item arrived.  So this jQuery takes the "Hold till MM/YY/DD" text and replaces it with the phrase "Phone the patron."  The idea was that staff would see this and put the item in a pile next to the phone so the patron could be called.


<!DOCTYPE html>
<html>

  <head>

    <script type="text/javascript">

      $(document).ready(function(){

          $("#bor_DIGITAL").parent().removeAttr('style');
          $("#loc_DIGITAL").hide();
          $('#pudate').not(':contains("@")').html("Phone<br />the<br />Patron");
       
      });

  </script>

  <style>

    body {width: 245px; margin-top: 0; margin-bottom: 0; margin-right: 0; margin-left: 20px}
    article{display:inline-block}
    .right{float:right}

  </style>
 
  </head>

  <body>

    <div id="borrower" style="display: none;">
 
      <div id="bor_<<branches.branchcode>>">
   
        <article class="right">
          <h2 id="pudate">Hold till: <<reserves.expirationdate>> <span style="display: none;"><<borrowers.email>></h2>
        </article>    
   
        <h2 style="text-align:left"><<borrowers.surname>>,<br>
        <<borrowers.firstname>></h2><br>
        <br>
        <br>
        <h3>Hold at <<branches.branchname>></h3>
        <ul>
          <li><<borrowers.cardnumber>></li>
          <li><<borrowers.phone>></li>
          <li><<borrowers.email>></li>
          <li><<borrower-attribute:HOLD>></li>
        </ul><br>
        <h3>ITEM ON HOLD</h3>
        <ul>
          <li><<items.itemcallnumber>> // <<biblio.title>> // <<biblio.author>></li>
          <li><<items.barcode>></li>
          <li>Available since: <<reserves.waitingdate>></li>
        </ul>
        <p>Notes:<br>
        <<reserves.reservenotes>></p><br>
       
      </div>
 
    </div>
 
    <div id="loc_<<branches.branchcode>>">
 
      <h1 style="font-size: 48px;"><<branches.branchnotes>></h1><br>
      <br>
      <br>
      <p>Ship to:</p>
      <h1><<branches.branchname>></h1>
      <h1><<branches.branchaddress1>></h1>
      <h1><<branches.branchcity>>, <<branches.branchstate>> <<branches.branchzip>></h1>
      <p> </p>
      <p><<items.itemcallnumber>></p>
      <p><<biblio.title>></p>
      <p><<biblio.author>></p>
      <p><<items.barcode>></p>
      <p> </p>
      <p>Shipped on: <<today>></p>
      <p> </p>
      <p>Shipped to: <<branches.branchcode>></p>
      <p> </p>
      <p>This slip generated at DIGITAL</p>
      <p> </p>
 
    </div>

    <div id="check_<<branches.branchcode>>" style="display:none">

      <hr />

      <div id="list" style="display:none">

        <h5 style="display:none"><<borrowers.email>></h5>

        <h2>Phone call checklist</h2>

        <h3>Circle one:</h3>

        <p>Spoke directly with the patron.</p>

        <p>Left message with person who answered the phone.</p>

        <p>Left message on answering machine / voice mail.</p>

        <p>Please send a postcard to the patron if you cannot contact them by other means within 24 hours of the requested item's arrival.</p>

        <br />

        <hr />

      </div>

    </div>

  </body>

</html>

*************************************************

Then we'll add the jQuery that un-hides the checklist DIV if the item is supposed to be picked up at this location.  There's no point in printing the checklist if the patron is going to pick up the item somewhere else.

<!DOCTYPE html>
<html>

  <head>

    <script type="text/javascript">

      $(document).ready(function(){

          $("#bor_DIGITAL").parent().removeAttr('style');
          $("#loc_DIGITAL").hide();
          $('#pudate').not(':contains("@")').html("Phone<br />the<br />Patron");
          $('#check_DIGITAL').removeAttr("style");
       
      });

  </script>

  <style>

    body {width: 245px; margin-top: 0; margin-bottom: 0; margin-right: 0; margin-left: 20px}
    article{display:inline-block}
    .right{float:right}

  </style>
 
  </head>

  <body>

    <div id="borrower" style="display: none;">
 
      <div id="bor_<<branches.branchcode>>">
   
        <article class="right">
          <h2 id="pudate">Hold till: <<reserves.expirationdate>> <span style="display: none;"><<borrowers.email>></h2>
        </article>    
   
        <h2 style="text-align:left"><<borrowers.surname>>,<br>
        <<borrowers.firstname>></h2><br>
        <br>
        <br>
        <h3>Hold at <<branches.branchname>></h3>
        <ul>
          <li><<borrowers.cardnumber>></li>
          <li><<borrowers.phone>></li>
          <li><<borrowers.email>></li>
          <li><<borrower-attribute:HOLD>></li>
        </ul><br>
        <h3>ITEM ON HOLD</h3>
        <ul>
          <li><<items.itemcallnumber>> // <<biblio.title>> // <<biblio.author>></li>
          <li><<items.barcode>></li>
          <li>Available since: <<reserves.waitingdate>></li>
        </ul>
        <p>Notes:<br>
        <<reserves.reservenotes>></p><br>
       
      </div>
 
    </div>
 
    <div id="loc_<<branches.branchcode>>">
 
      <h1 style="font-size: 48px;"><<branches.branchnotes>></h1><br>
      <br>
      <br>
      <p>Ship to:</p>
      <h1><<branches.branchname>></h1>
      <h1><<branches.branchaddress1>></h1>
      <h1><<branches.branchcity>>, <<branches.branchstate>> <<branches.branchzip>></h1>
      <p> </p>
      <p><<items.itemcallnumber>></p>
      <p><<biblio.title>></p>
      <p><<biblio.author>></p>
      <p><<items.barcode>></p>
      <p> </p>
      <p>Shipped on: <<today>></p>
      <p> </p>
      <p>Shipped to: <<branches.branchcode>></p>
      <p> </p>
      <p>This slip generated at DIGITAL</p>
      <p> </p>
 
    </div>

    <div id="check_<<branches.branchcode>>" style="display:none">

      <hr />

      <div id="list" style="display:none">

        <h5 style="display:none"><<borrowers.email>></h5>

        <h2>Phone call checklist</h2>

        <h3>Circle one:</h3>

        <p>Spoke directly with the patron.</p>

        <p>Left message with person who answered the phone.</p>

        <p>Left message on answering machine / voice mail.</p>

        <p>Please send a postcard to the patron if you cannot contact them by other means within 24 hours of the requested item's arrival.</p>

        <br />

        <hr />

      </div>

    </div>

  </body>

</html>


*************************************************

Finally we'll add the jQuery that un-hides the actual checklist if the patron does not have an e-mail address.


<!DOCTYPE html>
<html>

  <head>

    <script type="text/javascript">

      $(document).ready(function(){

          $("#bor_DIGITAL").parent().removeAttr('style');
          $("#loc_DIGITAL").hide();
          $('#pudate').not(':contains("@")').html("Phone<br />the<br />Patron");
          $('#check_DIGITAL').removeAttr("style");
          $('#list').not(':contains("@")').removeAttr("style");
       
      });

  </script>

  <style>

    body {width: 245px; margin-top: 0; margin-bottom: 0; margin-right: 0; margin-left: 20px}
    article{display:inline-block}
    .right{float:right}

  </style>
 
  </head>

  <body>

    <div id="borrower" style="display: none;">
 
      <div id="bor_<<branches.branchcode>>">
   
        <article class="right">
          <h2 id="pudate">Hold till: <<reserves.expirationdate>> <span style="display: none;"><<borrowers.email>></h2>
        </article>    
   
        <h2 style="text-align:left"><<borrowers.surname>>,<br>
        <<borrowers.firstname>></h2><br>
        <br>
        <br>
        <h3>Hold at <<branches.branchname>></h3>
        <ul>
          <li><<borrowers.cardnumber>></li>
          <li><<borrowers.phone>></li>
          <li><<borrowers.email>></li>
          <li><<borrower-attribute:HOLD>></li>
        </ul><br>
        <h3>ITEM ON HOLD</h3>
        <ul>
          <li><<items.itemcallnumber>> // <<biblio.title>> // <<biblio.author>></li>
          <li><<items.barcode>></li>
          <li>Available since: <<reserves.waitingdate>></li>
        </ul>
        <p>Notes:<br>
        <<reserves.reservenotes>></p><br>
       
      </div>
 
    </div>
 
    <div id="loc_<<branches.branchcode>>">
 
      <h1 style="font-size: 48px;"><<branches.branchnotes>></h1><br>
      <br>
      <br>
      <p>Ship to:</p>
      <h1><<branches.branchname>></h1>
      <h1><<branches.branchaddress1>></h1>
      <h1><<branches.branchcity>>, <<branches.branchstate>> <<branches.branchzip>></h1>
      <p> </p>
      <p><<items.itemcallnumber>></p>
      <p><<biblio.title>></p>
      <p><<biblio.author>></p>
      <p><<items.barcode>></p>
      <p> </p>
      <p>Shipped on: <<today>></p>
      <p> </p>
      <p>Shipped to: <<branches.branchcode>></p>
      <p> </p>
      <p>This slip generated at DIGITAL</p>
      <p> </p>
 
    </div>

    <div id="check_<<branches.branchcode>>" style="display:none">

      <hr />

      <div id="list" style="display:none">

        <h5 style="display:none"><<borrowers.email>></h5>

        <h2>Phone call checklist</h2>

        <h3>Circle one:</h3>

        <p>Spoke directly with the patron.</p>

        <p>Left message with person who answered the phone.</p>

        <p>Left message on answering machine / voice mail.</p>

        <p>Please send a postcard to the patron if you cannot contact them by other means within 24 hours of the requested item's arrival.</p>

        <br />

        <hr />

      </div>

    </div>

  </body>

</html>


**************************************************

The end result is a receipt that looks like this if the requesting patron does not have an e-mail address:



**************************************************

These are just some of the things I've done with receipts so far.

It is also possible to modify the HOLD_SLIP receipts to include scannable barcodes for patrons and items.  It is also possible to modify the receipts to print sideways.  It is also possible to modify the receipts to only display portions of a patron's name or barcode number in order to protect their privacy when items are stored on a self-service hold shelf, for example.

There are many possibilities.