Sunday, January 6, 2013

A sample Dual Listbox Selector SAS Server Page

In my Section 5.3.4 of my ebook (SAS® Server Pages: Generating Dynamic Content) which describes the generateOptionTag utility macro, I reference this blog entry as an example of using  a dual listbox selector to allow for multiple selections.  See the example screen shot (at right) that uses the sashelp.class data set.

This sample SAS Server Page makes use of a number of features of PROC STREAM, some JavaScript code, and two utility macros. Before I describe the details of this sample, please feel free to give it a try on my demo server using the Stored Process Server (the example also works for the SAS/InterNet Application Dispatcher):

http://demos.hcsbi.com:8080/SASStoredProcess/guest?_program=/sspebook/sasServerPage&page=dualListBox

To move items you can either:
  • double click them
  • single click and then use the arrows to move the selected items
  • move them all use the double arrows
  • you can also move a selected up or down in the list
Then click the Review Name/Value Pairs button to see a list of the items in each box.

Now lets take a quick look at this sample SAS Server Page. Note that this is just a sample. It might make sense to create a template (or a macro) that can have parameters passed to it. For now, I wanted to keep it simple, thus this sample.

The readfile option of the &streamDelim facility of PROC STREAM is used to define the JavaScript routines that are used to move the items. We use readfile here so the text is included in the page rather than assuming it is available on the web server.





Next we set up the form. Note the following:
  • Two macro variables are defined since we will need to refer to the names of the left (i.e., Available in this case) and right (i.e., Selected in this case) select tags numerous times.
  • The onSubmit JavaScript hander is used to make sure all the items in both select tags are selected.
  • The _debug value of 1 generates the display of the name value pairs passed to the stored process.







Use an HTML table to control the layout of the two select tags and the icons/images that are used to move items.







Use the getImage utility macro (discussed in a previous blog, The getImage macro: embedded images using text strings) to generate the images for the up and down arrows in the first table column.








The generateOptionTag macro is used to create the left hand select tag in the second table column. It is populated from the students in the SASHELP.CLASS data set who are 13 years old or younger. Note that the otherOptions parameter of the macro is used to pass in extra paramaters to be included on the select tag:
  • The size option to specify that the select tag should be 20 rows long
  • The mulitple option to specify that multiple selections are allowed (part of the point of a dual list list box selector)
  • A style attribute to define the width
  • the onDblClick JavaScript handler so that when a user double clicks on an item it is moved from the left select tag to the righ select tag.





The getImage macro is used to generate the images/icons (in the third table column) used to move items:
  • Move all the items from the left to the right select tag
  • Move only the selected items from the left to the right select tag
  • Move only the selected items from the right to the left select tag
  • Move all the items from the right to the left select tag








Just as for the left select tag, the generateOptionTag macro is used to create the right hand select tag in the second table column. It is populated from the students in the SASHELP.CLASS data set who are older tha 13.





The last column is similar to the first one - except the the Move Up and Move Down images are for the right hand select tag







The final bit of HTML closes the table, generates the submit button, closes the form and the HMTL page.







I plan to write a future blog posting to generalize/parameterize this functionality and will include a link to a zip file of the components. In the meantime, please feel free to comment and ask questions about this example.