A better select one or many

April 7, 2008

“Better” is an exaggeration. It may be that occasionally it is more appropriate.

At issue is presenting a control to the user where she can select one of many, or several of many. When the selection is fairly small (arbitrary at 7 items) – radio and checkbox groups are standard. But when the choice number goes over a certain number, there are various mechanisms to be seen, of which the most common are single select <select /> and multiple select <select /> – the problem is how to fit large number of choices into a cramped area.

This came up in the context of the Sakai Course Evaluation tool, where any number of question types need to be constructed and presented to the user. One of these questions, used in a Cambridge course evaluation, involved a really long list of choices.

Occasionally you might want a control that is a bit friendlier and stylable than a <select />. A colleague alerted me to: http://c82.net/posts.php?id=25

Here is an example from C82:

Nice! The clickable area indicated by the dark green hover is created by the <label /> element, wrapping the <input /> and the text and set to display:block. The height and width of the top container (a <ul />) are fixed and the overflow:auto for the scroll.

There are three possible improvements to the excellent widget.

  1. Having the overflow and height attributes set only if the height goes over a certain number (template or system set) – so scrollbars appear after a certain height, and groups of less than that height size automatically.
  2. Having the “checked” attribute of the input reflected in the style of the parent label
  3. Having a message display of the “you have made x selections” or something like that.

Setting the scroll and height dynamically

The markup looks like this:

<ol class="multchoiceholder">
<li>
<label for="1">
<input value="1" name="1" id="1" type="checkbox">
</label>
</li>
<li>
<label for="2">
<input value="2" name="2" id="2" type="checkbox">
</label>
</li>
(etc)
</ol>

And the CSS is pretty much what the C82 article above is using, except no height is set for the container, allowing it to grow to fit the contents. To get the “intelligence” about the height I added jquery.js to the <head />

<script src="jquery.js" language="JavaScript" type="text/javascript">

And the following at the end of the document:

<script type="text/javascript">
$(".multchoiceholder").each(function(){
if ($(this).height() > 180) {
// if ($(this).children("li").size()  >  9) {
$(this).addClass("oversize")
}
})
</script>

This essentially adds the “oversize” class to the parent container if the parent container contents go over 180 pixels in height. This class, below, sets the height and the overflow that we need. I played around with counting the <li /> child nodes (commented above), but since a given list item could span multiple lines the pixel height seemed best.

ol.oversize{
border: 1px solid #ccc !important;
height: 12em !important;
overflow: auto !important
}
Advertisements

Setting up a Sakai toolbar and styling it

March 13, 2008

See Previous post: Marking Up the Sakai ToolBar.

Setting up a toolbar will depend on the templating technology. Velocity based tools will be using the #menu macro. JSF tools will be using either the ToolBar and ToolBarItem tags, or just the ToolBar + valid JSF tag children. Hand crafted markup should follow the same pattern:

<ul role=”menu” class=”navIntraTool actionToolBar”>
 <li role=”menuitem” class=”firstToolBarItem”>
  <span>
   <a href=”#”>A link</a>
  </span>
 <li role=”menuitem”>
  <span aria-disabled=”true” class=”inactive”>A string</span>
 </li>

 <li role=”menuitem”>
  <span>
   <a href=”#”>A link</a>
  </span>
 </li>
</ul>

Styling this markup offers many possibilities since it is sstandard markup for toolbars and navigation lists. See the absurdly rich Listamatic for options.

The default Sakai (as of today) rendering uses the following CSS:

/*toolbar - turn into a list for 2.6 - default list render here, style in tool.css*/
.navIntraTool li{
     list-style: none;
     display: inline;
     margin:0 !important;
     padding:0 !important;
}
.navIntraTool li span a{
     margin:0 !important;
     padding:0 !important;
}
.navIntraTool li span a img{
     vertical-align: bottom;
}
.navIntraTool li span,
  .navIntraTool li span.current,
  .navIntraTool li span.inactive{
     border-left:1px solid #ccc;
     margin:0;
     padding:0 5px 0 8px
}
/*special style for the first item, namely no border-left*/
.navIntraTool li.firstToolBarItem span{
     border:none;
     margin:0;
     padding: 0 5px 0 8px;
}
/*some toolbars have input type=text, and the next
   item (fieldSibling) is a submit link*/
.navIntraTool li span.formItem,
   .navIntraTool li span.fieldSibling  {
     margin:0;
     border:none;
     padding:0;
}
.navIntraTool li span.fieldSibling {
     padding: 0 5px 0 0;
}

/*style for item that would be a link
   if you were not at the page already*/
.navIntraTool li span.current{
     color:#777;
}
.navIntraTool li span.inactive{
     color:#777;
}

And this is what it looks like in th e Chat tool:

Default Sakai Style

Not much to note, is so simple. The “pipe” is actually the left border of the <span>. The first element does not get one. The end.

For something a bit more different here is the CSS (am just including the selectors that have changed from above).

ul.navIntraTool{
     background:#eee;
     padding: 5px !important
}.navIntraTool li span a, .navIntraTool li span a:visited,
   .navIntraTool li span a, .navIntraTool li span a:hover{
     color:#000;
     margin:0 !important;
     padding:0 !important;
     text-decoration: none !important
}

.navIntraTool li span, .navIntraTool li span.current,
   .navIntraTool li span.inactive,
   .navIntraTool li.firstToolBarItem span{
     border-top:1px solid #aaa;
     border-right:1px solid #333;
     border-bottom:1px solid #333;
     border-left:1px solid #aaa;
     margin:0;
     padding:3px 5px 3px 5px;
     background: #ddd
}
/*style for item that would be a link if you were
    not at the page already, and for inactive links*/

.navIntraTool li span.current, .navIntraTool li span.inactive{
     color:#777;
     border:1px solid #ddd;
     background: transparent;
}

toolbar-redmond.jpg

You can use a background image:

.navIntraTool li span, .navIntraTool li span.current,
    .navIntraTool li span.inactive, .navIntraTool li.firstToolBarItem span{
       border-top:1px solid #aaa;
       border-right:1px solid #333;
       border-bottom:1px solid #333;
       border-left:1px solid #aaa;
       margin:0;
       padding:3px 5px 3px 5px;
       background: #ddd url(default/images/tb-bk1.gif) top left repeat-x
}

toolbar-redmond2.jpg

Etc…… I think the markup now is fairly adaptable style wise. The examples above have just used one of the available canvases – the <span>, a lot more rich possibilities offer themselves if you want to style the four that are available to you (ul > li > span > a)….