Archive for the ‘Koha UI’ Category

jQueryUI and Koha

Tuesday, November 8th, 2011

There’s another project I’ve been working on for almost as long as I haven’t posted to this blog: Incorporating the jQueryUI JavaScript library into Koha. This change would replace the YUI Library which currently powers such interface widgets as buttons, menus, and autocomplete.

When I helped develop the new templates for Koha 3.0 I evaluated several different options for creating some application-like interactions in the Koha staff client including YUI , Ext JS, and similar jQuery plugins. The goal was to have options for creating cross-platform, cross-browser interface widgets. After much testing I settled on YUI. Though I found its syntax difficult to work with, the results worked well and seemed robust. The most visible example of YUI is in the staff client interface, where “toolbars” appear on most pages for displaying actions:

 YUI also drives some autocomplete form fields in the staff client and menus in the OPAC.

In addition to YUI, Koha uses the jQuery JavaScript library and some jQuery plugins like Tablesorter and a pre-jQueryUI version of  Tabs. Since the release of Koha 3.0 over three years ago a lot has changed with these projects. The YUI library released version 3 with enough syntax changes to make an upgrade mean totally rewriting our existing YUI code. At the same time the jQueryUI library made great advances, adding a lot of the same functionality for which we depended on the YUI library.

In November 2010 BibLibre founder and CEO Paul Poulain proposed getting rid of YUI in favor of jQueryUI and the response on the Koha developer’s list was positive. Shortly after I filed a bug, Replace YUI JS libraries with Jquery UI and began working on a branch to do just that.

Since then I’ve gotten two major components migrated from YUI to jQueryUI: tabs and autocomplete. Here’s an example of jQueryUI tabs in the OPAC:

Here are the search tabs in the staff client:

And here’s autocomplete in action in the staff client:

As part of this project I have also replaced the calendar widget we have been using with Koha. Since that widget was added to Koha it stopped being open source, so it makes sense to abandon it in favor of functionality built into jQueryUI.

Calendar pop-up on the check-out screen

Also on my list of things to implement is a replacement of the modal window system used in some places in Koha, for which we’re currently using a standalone JS plugin. This can be eliminated in favor of the jQueryUI-native Dialog widget.

Unfortunately we are still waiting for one element for which we depend on YUI which jQueryUI lacks: A menu widget. Their menu widget has been in alpha stage for almost as long as I’ve been working on this jQueryUI branch. Without it we can’t reproduce the toolbars we build now in YUI. For this reason my work has been stalled for a while. I’m keeping my branch up to date and in sync with the master branch, and I’m keeping my eye on the status of the menu widget.

I’m frustrated with the wait, but I’m also excited about the improvements we’ll be able to make to the Koha interface once jQueryUI is our standard go-to library.

An update on Recent Comments

Tuesday, November 8th, 2011

It’s been far too long since my last post. I’m happy to say that my Recent Comments feature didn’t take quite so long to get incorporated into Koha, although it wasn’t until recently that it was obvious it was there. The page itself made it into Koha in a commit in December 2010, and was in Koha 3.2.3. What it lacked was a link in the interface pointing to the page, so you had to know where it was to get to it. This problem was fixed in a commit in October of this year which adds a new system preference, , which controls whether a link to the recent comments view should appear in the OPAC’s search bar. The option will be available to users of Koha 3.6.

A long an roundabout path, but hopefully a useful feature.

Interface test: Placing a quick hold

Monday, July 19th, 2010

I was thinking about ease of use, and what we could to to improve the Koha OPAC from the point of view of the patrons, and the first thing my mind jumped to was the process of placing holds. For many patrons placing a hold is the goal of their visit to the OPAC. They’re looking for something they want, they find it in the catalog, and they want to get it. On Amazon.com the next step would be to buy it. In the OPAC they can place a hold.

What’s the first thing they see when they click one of those “place hold” links? Potentially this:

Place hold interface with all options turned on

I hate it. It’s an ugly table with too many options. True, you can turn off some of those options for a simpler process. Turn off the OPACItemHolds system preference to eliminate the option of choosing a specific copy. Turn off OPACAllowHoldDateInFuture to hide the Hold Starts on Date column. Turn off OPACDisplayRequestPriority to hide the hold request’s rank in the queue. Now it’s a little simpler:

With optional settings turned off

I’m still not crazy about it, and that’s why holds came to mind when I thought about what we could do to improve interactions in Koha. How can we make that interaction simpler? How about [almost] one-click “ordering?”

Click the "Place hold" link in the right sidebar

When you click the “Place hold” link you can see my idea demonstrated. Clicking the link would use JavaScript to display a simple form: Place hold? Yes/No. Embedded in the HTML would be all the required form fields, hidden, for placing a single hold with no options set, using the patron’s home library as the destination for the hold. If the patron wanted to set additional options they could click the “more options” link and be taken to the standard form.

How hard would this be to implement? It depends how far you want to take it. I could see  this being a JavaScript-only enhancement, assuming all the information we need is found on this page. In this version clicking the “Yes” button would submit the form to the same script the standard form does, but bypass the hold confirmation screen. The user would be redirected to their summary page showing current holds.

A fancier version would submit the form in the background. Clicking the “Yes” button would triggers a sequence of events:

  1. The hold would be submitted in the background.
  2. The interface would display some kind of “Working” indicator.
  3. Upon completion of the background submission, the interface would indicate success.

This is more complicated because the reserve script would have to be modified to work in new way. Error-handling would have to be incorporated so that if for some reason the hold couldn’t be processed the user could be warned. The advantage to this interaction is that the user never leaves the page, making it easier for them to find their way back to their original search–something which, incidentally, is also on our to-do list of ways to make things easier for the user.

Enlittling the OPAC’s login form

Tuesday, October 6th, 2009

Seems like lots of people hate the login form on Koha’s OPAC.  I understand many have a problem with it because their users look at and think they must log in to use the catalog. There’s no switch to flip to turn off display of the login form on the main page, but you can use a little custom CSS to hide it.

Add this to your OpacUserCSS system preference:

#login {
display: none;
}

One disadvantage to this technique is that it doesn’t allow your main page content to take up the whole width of the front page. The right-hand column of the OPAC’s main page remains pretty much inflexible in terms of content.

What if you don’t want to eliminate the option of logging in from the home page but you don’t like the big login form? Recently someone posed this question on the Koha mailing list.

Any thoughts on where to look to move the “Login to Your Account” and the Username and Password blanks to the top and replace the link there for “Login to Your Account” with Username and Password?

I started jumping in with some JavaScript when I realized this could be accomplished using just CSS. Here’s the result:

Click to enlarge image

Click to enlarge image

Here’s a rundown of what’s going on in the custom CSS:

  • Styling the form container with position: absolute and placing it in the top right corner. The form overlaps and hides the default login link in the top right corner.
  • Styling all the form contents as inline instead of block.
  • Adjusting margins, padding, font-size, and width.
  • Hiding the login form’s title (“legend”).

Why did I hide the form’s title? It wasn’t for aesthetic reasons. I found that Internet Explorer 6 refused to display the title (which is a <legend> inside a <fieldset>) in line with the rest of the form. IE6 wanted to give the <legend> its own line. Some conditional comments could alleviate the problem if you wanted to deliver the title to browsers that can display it correctly.

To give the form some room there at the top of the page I added a little bit of margin to the top of the main search bar. If your OPAC design includes custom header content you might have to adjust that margin.

I’ve tested this in these browsers on Windows XP: Internet Explorer 6, Firefox 3.5, Safari 4, Opera 10, and Chrome 3. Below is the CSS in its entirety. Add it to your custom stylesheet or to your OpacUserCSS system preference.

#login {
background-color : #FFF;
position : absolute;
top : 0;
right : 0;
padding-top : 5px;
width : 22em;
}
#auth fieldset,
#auth fieldset.brief {
border : none;
display : inline;
margin : 0;
padding : 0;
}
#auth input {
font-size : 75%;
}
#auth legend {
display : none;
}
#auth label {
display : inline;
font-size : 85%;
}
#auth li,
#auth ol {
display : inline;
}
#login #userid, #login #password {
width:auto;
}
#auth fieldset.action input {
margin: 0;
padding : 0;
}
#auth fieldset.action {
margin-bottom : -5px;
}
#opac-main-search {
margin-top : 1.5em;
}
Any thoughts on
where to look to move the “Login to Your Account” and the Username and
Password blanks to the top and replace the link there for “Login to
Your Account” with Username and Password?

Quick patron add?

Monday, August 17th, 2009

Someone posted an enhancement request today requesting a change to the way the patron entry form is arranged in the Koha staff client. By default the patron entry form is pretty long, and the request asks that required fields be grouped at the top.

It seems like a reasonable request, but there’s a big disadvantage to trying to solve this problem with a template-only change: Libraries can customize which fields are mandatory when entering patrons. The system preference for that is  BorrowerMandatoryField (“borrower” being the term used in place of “patron” at the time of the preference’s creation).

What alternatives might there be to a template-only solution?

  1. Alter the script which generates the patron entry form so that any required fields (no matter which ones they are) are displayed at the top.
  2. Create a “quick-add” form which shows only required fields.
  3. Add a filter to the full patron entry form to toggle display of non-mandatory fields.

I like option two as a long-term solution, but option three could be implemented now with some custom JavaScript. Here’s a proof-of-concept script to show that using the markup which exists in the form now we can pull only required fields:


$(document).ready(function(){
var list = "<fieldset class=\"rows\"><legend>Quick Add<ol>";
$("label.required").each(function(){
item = $(this).parent().html()
item = "<li>"+item+"</li>";
list += item;
});
list += "</ol></fieldset><fieldset class=\"action\"><input type=\"submit\" value=\"Save\" onclick=\"return check_form_borrowers();\" name=\"save\"/><a href=\"/cgi-bin/koha/members/member.pl\" class=\"cancel\">Cancel</a></fieldset>";
$("#entryform").prepend(list);
});

Paste that into your intranetuserjs system preference or into Firebug’s command line to give it a try. Note that this solution assumes two things:

  1. You’ve already specified a patron category (by choosing one from the “new” menu).
  2. You’re adding patrons to the default branch for your logged-in user.

Of course the form could be customized to include these choices, but they’re probably safe assumptions for quick adds. A better implementation of this would probably allow you to toggle between either view: quick or standard.

Interface Test: Editing from the additem table

Thursday, July 16th, 2009

One of the custom reports I’ve been using recently is one that shows me the most expensive items in the catalog. I’m not trying to figure out which book to sneak out under my coat, I’m trying to find data-entry errors which might cause problems for the patrons.

You lost that paperback? That’ll be $4399.00.

The trouble is, once I’m cruising through this report making corrections I’m quickly frustrated by the interface for adding items.additem-interface

The list of items is in its own container with the css property “overflow:auto” so that if it exceeds the constraints of the container it’s in it will display scrollbars. It always displays scrollbars. You have to scroll to the right to see the item’s replacement price, then back to the left to find the Edit link. And it’s hard to be sure you clicked the Edit link in the correct row, because once you’re at the Edit link you can’t see the price anymore!

What if we could access the Edit and Delete functions from anywhere in the row? Inspired by WordPress’s inline edit menu I worked up this example:

additem-inline-edit

Try navigating anywhere in the table of item details and clicking a table cell. You’ll see Edit/Delete links appear for that row. Implementing this change would allow the user to jump to the Edit or Delete functionality from anywhere in the table eliminating the need to scroll back and forth for the static links.

The advantage to the method used in this example is that it’s simple: no generating tooltips or modal dialogs, just a simple append of the Edit|Delete links to the table cell which gets clicked.


$("td").click(function(event){
var $tgt = $(event.target);
if($tgt.is("a")||$tgt.is(":first-child")||$tgt.is(":nth-child(2)")){ return true; } else {
var rowid = $(this).parent().attr("id");
num_rowid = rowid.replace("row","");
$(".linktools").remove();
$(this).append("<span class=\"linktools\"><a href=\"/path/to/additem/script.pl?op=edititem&amp;amp;biblionumber="+biblionumber+"&itemnumber="+num_rowid+"\">Edit</a> | <a href=\"/path/to/additem/script.pl?op=delitem&amp;amp;biblionumber="+biblionumber+"&itemnumber="+num_rowid+"\" onclick=\"confirm_deletion("+biblionumber+","+num_rowid+"); return false;\">Delete</a></span>");
}
});

The disadvantage to the resulting UI is that it could suggest to the user that clicking Edit or Delete will edit or delete just the contents of that cell, which is of course incorrect. It wouldn’t be good for a librarian to expect a click on “Delete” to delete, for instance, only the value contained in the replacementprice field and find that the entire item had been deleted.

I’m not sure how to mitigate that confusion while retaining the script’s simplicity.

Update: Here’s an alternate, slightly more verbose version.

Interface test: Collection code groups

Thursday, July 16th, 2009

Does your library have too many choices on the OPAC’s advanced search page? From the point of view of our librarians we don’t, but I think from the point of view of the patrons we do. 43 choices? And many of those categories encompass the same materials or genres. You could easily group our categories using format, audience, or other criteria:

  • DVDs: DVD, DVDJ, DVJN, DVDN
  • Videos: AV, AVJ, AVJN, AVNF
  • Movies: DVD, DVDJ, DVJN, DVDN, AV, AVJ, AVJN, AVNF
  • Books for adults: AF, MYS, SCI, WES, LP, LPNF, PB, BIO, NF
  • Large Print: LP, LPNF

It’d be great if you could define “category groups” in Koha to allow patrons to easily search multiple categories at once. Until that comes about, how can we approach the problem from the front end?

Selecting Multiple Categories with JavaScript

Here’s a little experiment I worked up. This is just a static example page to demonstrate the selections.  Some parts of the OPAC omitted for simplicity.

opac-cccode-groups

Try clicking the links at the top of the category table. Clicking “Books” will select all collection codes which I’ve defined as a book for adults. Clicking “Audio Books” will select any category which could be defined as an audio book, whether it be on CD, cassette, or Playaway.

All the functionality of this example could be layered on top of the OPAC using existing avenues for customization like the opacuserjs system preference. It’s not very efficient to set up, however, because you have to hard-code all your collection codes within the JavaScript. That means that you have to update your script any time you add a category.

var books = "#ccode-1,#ccode-5,#ccode-12,#ccode-13,#ccode-14,#ccode-15,#ccode-16,#ccode-17,#ccode-18,#ccode-19,#ccode-27";
var movies = "#ccode-2,#ccode-3,#ccode-4,#ccode-6,#ccode-23,#ccode-39,#ccode-40,#ccode-41";
var lp = "#ccode-13,#ccode-14";

Defining your “supercategories” could be as difficult as defining your original categories in Koha. What criteria do you use? Audience? Format? Content? In my example I mix all three. Would that be confusing to patrons? I may yet add this to our OPAC, but I’ll have to ponder these issues a little more.

Colorizing the Cart and Lists buttons

Tuesday, July 7th, 2009

The OPAC’s Cart and Lists buttons are an unusual construction. Their appearance is the result of a rather convoluted combination of CSS and HTML designed to give nice anti-aliased, rounded corners and flexibility when the text is resized.  Try increasing the font size in your browser (Ctrl +).

koha3-opac-button-resize

The technique to create these buttons was adapted from Scalable CSS Buttons Using PNG and Background Colors.  If you’re interested in understanding the real nuts and bolts of the technique I suggest you read through that article. I’m going to cover just the details we need to look at for customizing the default appearance in Koha. [Edit: The link no longer works, sorry.]

There are several options we need to cover when changing the buttons’ appearance:

  1. The link and link hover color
  2. The button background-color (default and hover)
  3. The button border

The Cart and Lists buttons each have their own ID in the HTML for reference in the CSS: #cartmenulink and #listsmenulink. Let’s look at the Lists button for simplicity’s sake.

1. The link color

The link color is the most straightforward one: Target the A element with the #listsmenulink ID:

a#listsmenulink { color: #E5CCE6; }
a#listsmenulink:hover { color: #FF99FF; }

2. The button background-color (default and hover)

The buttons have both a default background color and a hover background color. Set them by targeting the #listsmenulink ID:


#listsmenulink { background-color : #6600CC; }
#listsmenulink:hover { background-color : #9900CC; }

If we’re just changing background colors, and not images, on the button, how is it possible that we get a nice gradient? The answer is in this part of the default CSS:


#listsmenulink[class] {
background-image : url(../../images/button-background-gradient.png);
background-position : left top;
}

That’s a PNG file with alpha transparency. It overlays the solid background color and softens it with a gradient. If you like the gradient you can leave this part of the CSS without overriding it in your custom stylesheet. It will work with whatever background color you specify. If you want to turn it off to have a solid-color button, use this:


#listsmenulink[class] {
background-image: none;
}

3. The button border

Changing the button border is the trickiest step because it requires an image editor. The button border consists of a single background-image:

button-background

How the button would appear if the border image had transparent corners

How the button would appear if the border image had transparent corners

The image gives the button its border color. The center of the image is transparent. The corners are opaque, colored to match the blue of the default background of the search bar. The corners have to be opaque because they have to mask the square corners of the HTML element behind them.

Changing the background color means the corners no longer match what is behind them

Changing the background color means the corners no longer match what is behind them

The fact that the corners are colored to match the default background means that if you try to change that background color your buttons will no longer match.

At the moment the only solution for those wishing to make changes to the button background is to recreate it from scratch. I’d like to share the source files I’m using so that in the future it’s easier for Koha users to make this change themselves. I use Photoshop 7 much of the time (yes I know it’s old), so I’m offering that version. I also recreated the graphic in Fireworks MX (again, old) and Inkscape .046 (yay, up to date!).

Photoshop 7 koha3-opac-button-background.psd 29.4K
Fireworks MX koha3-opac-button-background.png 39.5K
Inkscape 0.46 koha3-opac-button-background.svg 5.2K

Whatever program you use to edit these files, there are two basic steps to achieve the right look:

  1. Edit the stroke of the button shape (the border color).
  2. Change the color of the opaque corners.
lists-button-matched-corners

Our edited button background image gives us corners that blend perfectly with our custom background color.

After your file is edited to your satisfaction the next step is to export it in a web-friendly format:

  • If you’re using Photoshop use File > Save for Web and choose PNG-24 with the Transparency option checked.
  • In Fireworks, your Optimize setting should be PNG32 with the transparent matte option chosen.
  • In Inkscape, use the Export Bitmap option to export the Drawing only. In my tests Inkscape exported the 32-bit version (the version with alpha transparency) by default.

What About Internet Explorer 6?

Users of Internet Explorer 6 will see a solid-color button with square corners.

Users of Internet Explorer 6 will see a solid-color button with square corners.

One major downside of this method of styling the buttons is that it doesn’t work properly in Internet Explorer 6. IE6 doesn’t support PNG files with alpha transparency. The good news is that users of IE6 will still get a usable button. The bad news is that it won’t be very pretty.

Options Going Forward

If we’re already excluding users of Internet Explorer from the rounded button experience, why not use pure-CSS rounded corners? We could eliminate all the time and effort demonstrated in this article with some simple [if proprietary] CSS. Something like this:

#cartmenulink,#listsmenulink {
color: #336600;
padding: .7em .9em .7em .8em;
margin: .5em .5em .5em 1.5em;
text-decoration:none;
-moz-border-radius: 7px;
-webkit-border-radius: 7px;

}
#cartmenulink {
border:1px solid #336699;
background: #93d869 url("../../images/cart-button-background.png") top left repeat-x;
}
#listsmenulink {
border:1px solid #006699;
background: #9FBFFF url("../../images/lists-button-background.png") top left repeat-x;
}

This works fairly well in Firefox, Safari, and Chrome. Unfortunately, it fails not only in Internet Explorer 6, 7, and 8, but all versions of Opera too. For the time being, our more-complex process gives the desired result to a wider audience.

Using *-border-radius to style rounded corners

Using *-border-radius to style rounded corners. Click to view full-size.

Grabbing eyes with styled messages boxes

Wednesday, July 1st, 2009

I got a question yesterday on the Koha IRC channel about changing the background of message which appear onscreen during check-in operations. Aparently librarians were not noticing the messages, and the questioner wondered if those messages could be styled in a different way.

Koha prompts the user to return an item to its home library with a message box

Koha prompts the user to return an item to its home library with a message box

It’s possible to customize Koha’s staff client just like it’s possible to customize the OPAC. At the moment, though, the staff client lacks one useful option: a means of injecting custom inline CSS as we can with OpacUserCSS. The staff client does have intranetuserjs, and that gives us an opportunity to get around the shortcoming.

PLEASE NOTE: As the manual says, “IMPORTANT: This system preference is an advanced option. If you enter a value with incorrect syntax you can make it very difficult to access the staff interface.”

Here’s how intranetuserjs gets added to the markup. From the template:


<!-- TMPL_IF NAME="intranetuserjs" --><script type="text/javascript">
//<![CDATA[
<!-- TMPL_VAR NAME="intranetuserjs" -->
//]]>
</script><!-- /TMPL_IF -->

IF the intranetuserjs system preference has anything in it, the template will include it, wrapped in the appropriate <script> tags. Here’s how we’ll bend the rules to get our custom CSS in: Add this to the intranetuserjs pref:

//]]>
</script>
<style type="text/css">
/* Insert custom styles here */
</style>
<script type="text/javascript">
//<![CDATA[

When we add that to the intranetuserjs preference, Koha generates this markup in the template:

&lt;script type="text/javascript" &gt;
//&lt; ![CDATA[
//]]>
</script>
<style type="text/css">
/* Insert custom styles here */
</style>
<script type="text/javascript">
//<![CDATA[
//]]&gt;
&lt;/script&gt;

The first thing we do is close the <script> tag which was automatically opened by the template, which expected us to add JavaScript content. We add our custom <style> tag, then re-open the <script> tag. The template is going automatically add a closing <script> tag, so we’ve got to add an opening one or risk breaking things.

With that in place we can add our custom CSS. The message box gets its background from an image. The simplest way to customize its appearance is to remove the image and add a custom color:

div.message { background: #CCFF00 none; }
Remove the background image and add a custom color

Remove the background image and add a custom color

Or use your own background image:

div.message { background:white url(http://www.myacpl.org/koha/wp-content/uploads/2009/07/squidfingers-pattern_141.gif) scroll left 0;
}
Eye-catching but not very readable!

Eye-catching but not very readable!

If you’re going for really eye-catching, you’ll have to go for an animated background image!

Please return Understanding interpersonal communication / to RPL

If you find a background image you like, remember: copy the image to your own server. Don’t hot-link it from someone else’s. Nefarious webmasters are likely to swap out the image for something you don’t want to see!

Of course I don’t really recommend that you use an animated background. As you’re approaching this kind of change, please remember: changing the style of Koha’s default message box will change all instances of that style box. Koha re-uses that style for displaying informational messages throughout the interface. The staff at the circulation desk may like it, but the cataloger doing MARC imports may not!

Moving around your book covers

Wednesday, April 29th, 2009

I often hear people ask if they can have their book covers on the left-hand side of the search results list. This is one of the aspects of Koha 2.x that some people miss. Because the search results are in a table, you can’t simply change something in the CSS to move the images to the other side of the screen. Without changing the template itself, what can we do?

Usually my response is live with it, but it occurred to me yesterday that jQuery could handle this:

$(document).ready(function(){
$(".searchresults tr td:last-child").each(function () {
$(this).prependTo($(this).parent());
});
});

After the standard leading “(document).ready” stuff, the script starts by looking for elements inside anything with a class “searchresults.” That’s a <div> that surrounds the search results table. We’re looking for any <td> which is the “last child” of a <tr>. That is, the last table cell in each table row. jQuery’s each() function lets us loop over each instance of those last-child <td>’s that we find and perform some action on it.


$(this).prependTo($(this).parent());

This is the action we’re performing for each <td> our script matches. “$(this)” is how we identify the matched <td>. Then we use the prependTo() function to “cut” that <td> and “paste” it at the beginning of the row. Notice the element we’re prepending to is “$(this).parent().” parent() selects the element which “contains” $(this): <tr> contains <td>, so we’re moving our <td> to the beginning of the row.

Paste the script into your opacuserjs system preference and try a search. It works in my test, but don’t take my word for it. Test carefully and let me know if you see any problems with it.


Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported
This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported.