PEAR is archived and read-only

This mirror preserves historical PEAR package releases and metadata so existing references remain available.

Home » HTML » HTML_QuickForm_advmultiselect » Manual

Element for HTML_QuickForm that emulate a multi-select.

Summary

Why use HTML_QuickForm_advmultiselect ?

I am sure we have all been there, dealing with HTML_QuickForm because we need to allow users to select multiple options. With a standard html select box, you can select multiple options if the multiple attribute is set, but you have to hold down the appropriate modifier key (ctrl on windows) in order to do so. It is not a problem for end-user experts, but it is not true for all of us.

A quick list of great features

Features

System Requirements

Mandatory resources :

Optional resources :

About

FAQ

FAQ – Answers to most Frequently Asked Questions

HTML_QuickForm_advmultiselect FAQ
  1. What does it cost ?
  2. Do you offer support ?
  3. I found a bug, what shall i do ?
  4. What is HTML_QuickForm ?
  5. What is PEAR ?
  6. May i use HTML_QuickForm_advmultiselect if my browser is no javascript compliant or if javascript is disabled ?
  7. How to validate a HTML_QuickForm_advmultiselect element ?
  8. How to optimize javascript code usage on html generated page ?
  9. My Quickform advmultiselect element is not displayed on my browser window.
  10. My live counter is not updated with a single select list, when I click on checkboxes ?
  11. The selected list has one blank entry that you can move to available list
General questions
What does it cost ?

You can download and use it for free. But don't delete the copyright notice. You can read terms of the license.

Do you offer support ?

YES if there is no answer in this Guide and if you are ready to share some informations such as : your configuration (platform Win *nix mac, PHP version, PEAR packages installed) and perharps your script.

I found a bug, what shall i do ?

You can report it with the bug tracker at PEAR.

What is HTML_QuickForm ?

HTML_QuickForm is a PEAR package that provides methods for creating, validating and processing HTML forms.

The purpose of Keith Edmunds tutorial is to give the new users of QuickForm an overview of its features and usage patterns. It describes a small subset of available functionality.

Don't forget to read also the PEAR Manual, HTML_QuickForm related part.

What is PEAR ?

PEAR (an acronym for PHP Extension and Application Repository) is a framework and distribution system for reusable PHP components.

Don't forget to read also the PEAR Manual and PEAR FAQ.

How to
May i use HTML_QuickForm_advmultiselect if my browser is no javascript compliant or if javascript is disabled ?

The dual multi-select won't work, but you can display a single multi select box witch checkboxes. To do so, you have to remove {unselected} placeholder in the advmultiselect template element.

How to validate a HTML_QuickForm_advmultiselect element ?

You must use the HTML_QuickForm addGroupRule() method rather than HTML_QuickForm addRule() method.

How to optimize javascript code usage on html generated page ?

Following answers can be applied only for HTML_QuickForm_advmultiselect version 1.3.0 or better.

Use only once reference of javascript source code. If you have more than one advmultiselect element on your html page, then keep only one call and remove others.

<script type="text/javascript">
<?php
echo $ams1->getElementJs();    // keep one

//echo $ams2->getElementJs();  // remove others
?>
</script>

Better solution is to use link to external resource and then reduce amount of javascript source code embedded. Add line of code below between <head> tags of your generated page.

<script type="text/javascript" src="qfamsHandler.js"></script>

Fix path to javascript resource if necessary. qfamsHandler.js file can be found in PEAR/data/HTML_QuickForm_advmultiselect directory.

At least remove {javascript} placeholder if you use default template. You have to set this new one $deftpl, with code something like :

<?php
require_once 'HTML/QuickForm.php';
require_once 'HTML/QuickForm/advmultiselect.php';

$form = new HTML_QuickForm('ams130');
// ....
$ams =& $form->addElement('advmultiselect', 'cars', null, $car_array);

$deftpl = '
<table{class}>
<!-- BEGIN label_2 --><tr><th>{label_2}</th><!-- END label_2 -->
<!-- BEGIN label_3 --><th>&nbsp;</th><th>{label_3}</th></tr><!-- END label_3 -->
<tr>
  <td valign="top">{unselected}</td>
  <td align="center">{add}{remove}</td>
  <td valign="top">{selected}</td>
</tr>
</table>
';

$ams->setElementTemplate($deftpl);
//...
?>
Troubleshooting guide
My Quickform advmultiselect element is not displayed on my browser window.

You should have forgotten to add package ressource itself. This operation is mandatory for all external Quickform elements and not necessary for internal elements such as "radio", "checkbox", "text", "button" ...

<?php
require_once 'HTML/QuickForm.php';
require_once 'HTML/QuickForm/advmultiselect.php';  // <-- DO NOT forget it
?>
My live counter is not updated with a single select list, when I click on checkboxes ?

With HTML_QuickForm_advmultiselect version 1.3.0 or better you need to add a chunk of javascript code to initialize onclick event handler of each checkboxes.

<script type="text/javascript" src="qfamsHandler.js"></script>
<script type="text/javascript">
window.qfamsName = new Array();
window.qfamsName[0] = 'cars';
window.qfamsName[1] = 'fruit';
window.addEventListener('load', qfamsInit, false);
</script>

window.qfamsName is an array what identify each advmultiselect element used on your html page.

The selected list has one blank entry that you can move to available list

This problem comes when you set the selected list (see HTML_QuickForm::setDefaults method) with a wrong data array.

Remember that the available list contains all datas (selected and unselected values). This list is an associative array of "key-code" => "display-value". While selected list is only an array of "key-code".

Suppose we have to retrieve information from a database (with PEAR::DB), and have a simple table for holding user info. This SQL statement creates a table usable under the default database scheme using MySQL:

CREATE TABLE user (
   userid VARCHAR(5) NOT NULL,
   gid INT NOT NULL,
   affect INT NOT NULL,
   lastname VARCHAR(50)NOT NULL,
   firstname VARCHAR(50) NOT NULL,
   PRIMARY KEY (userid)
);

with values :

INSERT INTO user VALUES ('MJ001', 1, 0, 'Martin', 'Jansen');
INSERT INTO user VALUES ('BG001', 1, 1, 'Greg', 'Beaver');
INSERT INTO user VALUES ('CD001', 1, 0, 'Daniel', 'Convissor');
INSERT INTO user VALUES ('LL001', 2, 1, 'Laurent', 'Laville');

Column gid identify a user group, while userid identify a single and unique user.

We will initialize AVAILABLE list (on left side if default template) by a db query something like that:

<?php
$queryAll = 'SELECT userid, CONCAT(lastname, " ", firstname) AS useridentity '
          . 'FROM user WHERE gid = 1';
?>

and get this array:

Array
(
    [MJ001] => Jansen Martin
    [BG001] => Beaver Greg
    [CD001] => Convissor Daniel
)

We will initialize SELECTED list (on right side if default template) by a db query something like that:

<?php
// Once you have a valid DataBase object named $db ...

$querySel = 'SELECT userid FROM user WHERE gid = 1 AND affect = 1';
$affected_user =& $db->getCol($querySel);
?>

and get this array:

Array
(
    [0] => BG001
)

Remember that only a key-code array is necessary, other data will make blank line into select box.

Remains stuff is basic, create the QFAMS element, and load options (available and selected) with the load() method.

<?php
require_once 'HTML/QuickForm.php';
require_once 'HTML/QuickForm/advmultiselect.php';

$form = new HTML_QuickForm('amsDB');

// Once you have a valid QuickForm advmultiselect object named $ams in a QuickForm named $form ...

$ams =& $form->addElement('advmultiselect', 'user',
    array('Users:', 'Available', 'Affected'),       // labels
    null,                                           // datas: "key-code" => "display-value"
    array('style' => 'width:200px;')                // custom layout
);
$ams->load($db, $queryAll, 'useridentity', 'userid', $affected_user);

// ...
?>

You may use the load() method to set options from :

<?php
// ...

// 1. a php array
$all_user = array('MJ001' => 'Martin Jansen',
                  'BG001' => 'Greg Beaver',
                  'CD001' => 'Daniel Convissor'
);
$affected_user = array('BG001');
$ams->load($all_user, $affected_user);

// queries to get data
$queryAll = 'SELECT userid, CONCAT(lastname, " ", firstname) AS useridentity '
          . 'FROM user WHERE gid = 1';

$querySel = 'SELECT userid FROM user WHERE gid = 1 AND affect = 1';
$affected_user =& $db->getCol($querySel);

// 2. a db result
$all_user =& $db->query($queryAll);
$ams->load($all_user, 'useridentity', 'userid', $affected_user);

// 3. a db query
$ams->load($db, $queryAll, 'useridentity', 'userid', $affected_user);

// ...
?>
This example is available in bundle (see examples/qfams_basic_2.php)

News

News – What is New in version ?

Version 0.5.x
Version 1.0.x
Version 1.1.x
Version 1.2.x
Version 1.3.x
Version 1.4.x
Version 1.5.x

Getting started

Basic features

Overview

Overview – features and usage patterns

In brief

The purpose of this tutorial is to give the new users of HTML_QuickForm_advmultiselect an overview of its features and usage patterns. It describes a small subset of available functionality, but points to the parts of the documentation that give a more in-depth overview.

Basic concepts

In a usability test with non-information workers in an intranet application, we could be surprised that none (or few) of the users successfully selected multiple responses when presented in a HTML select element with multiple selection enabled. They simply did not know that control click exist.

To solve this problem, the QuickForm advmultiselect element provides an interface that allow user-end to do their selection very easily. In this interface, there are:

For each new item to add to your selection, select it from the unselected list (source), then clic on the add button to move it to the selection list (destination). It does not exists in the source list after transfer.

For each item to remove from your selection, select it in the selected list (source), then clic on the remove button to move it to the unselected list (destination). It does not exists in the source list after transfer.

Your first form

Your first form – basic usage

Basic features

We will start by creating a very simple form. Our goals are :

Copy the following code to a file, give it a .php extension, and display it in your browser:

<?php
/**
 * Custom advMultiSelect HTML_QuickForm element
 * using stylesheet rules selectors and a template.
 *
 * The template allows to add label as headers of dual select box
 * and moves the button to another location (below each select box).
 *
 * @version    $Id: firstform.xml,v 1.2 2009-02-09 17:10:32 farell Exp $
 * @author     Laurent Laville <pear@laurent-laville.org>
 * @package    HTML_QuickForm_advmultiselect
 * @subpackage Examples
 * @access     public
 * @example    examples/qfams_custom_1.php
 *             qfams_custom_1 source code
 * @link       http://www.laurent-laville.org/img/qfams/screenshot/custom1.png
 *             screenshot (Image PNG, 677x197 pixels) 4.80 Kb
 */

require_once 'HTML/QuickForm.php';
require_once 'HTML/QuickForm/advmultiselect.php';

$form = new HTML_QuickForm('amsCustom1');
$form->removeAttribute('name');        // XHTML compliance

$fruit_array = array(
    'apple'     =>  'Apple',
    'orange'    =>  'Orange',
    'pear'      =>  'Pear',
    'banana'    =>  'Banana',
    'cherry'    =>  'Cherry',
    'kiwi'      =>  'Kiwi',
    'lemon'     =>  'Lemon',
    'lime'      =>  'Lime',
    'tangerine' =>  'Tangerine',
);

// rendering with QF renderer engine and template system
$form->addElement('header', null, 'Advanced Multiple Select: custom layout ');

$ams =& $form->addElement('advmultiselect', 'fruit', null, $fruit_array,
                           array('size' => 5,
                                 'class' => 'pool', 'style' => 'width:300px;'
                                )
);
$ams->setLabel(array('Fruit:', 'Available', 'Selected'));
$ams->setButtonAttributes('add',    array('value' => 'Add >>',
                                           'class' => 'inputCommand'
));
$ams->setButtonAttributes('remove', array('value' => '<< Remove',
                                           'class' => 'inputCommand'
));
$template = '
<table{class}>
<!-- BEGIN label_2 --><tr><th align="center">{label_2}</th><!-- END label_2 -->
<!-- BEGIN label_3 --><th align="center">{label_3}</th></tr><!-- END label_3 -->
<tr>
  <td>{unselected}</td>
  <td>{selected}</td>
</tr>
<tr>
  <td align="center">{add}</td>
  <td align="center">{remove}</td>
</tr>
</table>';
$ams->setElementTemplate($template);

if (isset($_POST['fruit'])) {
    $form->setDefaults(array('fruit' => $_POST['fruit']));
}

$form->addElement('submit', 'send', 'Send');

?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3c.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>HTML_QuickForm::advMultiSelect custom example 1</title>
<style type="text/css">
<!--
body {
  background-color: #FFF;
  font-family: Verdana, Arial, helvetica;
  font-size: 10pt;
}

table.pool {
  border: 0;
  background-color: lightyellow;
}
table.pool th {
  font-size: 80%;
  font-style: italic;
  text-align: center;
}
table.pool select {
  background-color: lightblue;
}

.inputCommand {
    background-color: #d0d0d0;
    border: 1px solid #7B7B88;
    width: 7em;
    margin-bottom: 2px;
}
 -->
</style>
<?php echo $ams->getElementJs(false); ?>
</head>
<body>
<?php
if ($form->validate()) {
    $clean = $form->getSubmitValues();

    echo '<pre>';
    print_r($clean);
    echo '</pre>';
}
$form->display();
?>
</body>
</html>

Lets review this example step by step :

Line 23 :

At the beginning we creates a HTML_Quickform object that will contain the objects representing elements and all the other necessary information. We only pass the form's name to the constructor, which means that default values will be used for other parameters.

Lines 39, 41, 72 :
Our form will consist of three elements:

The first one is not the "real" element, it is just a heading to improve presentation. The second one is our advmultiselect element. Note that parameters for HTML_Quickform::addElement method have different meanings for different elements. That is so because they are actually passed to these elements' constructors.

Lines 26-36 :

The $fruit_array variable sets the default values (code, label) for the fruit advmultiselect element.

Lines 42-44 :

It's time to define the fruit element attributes:

size
Give count of visible item in each list. Default is 10.
style
The select boxes width in pixel. Default is 100.
class
A CSS class identifier to override the look and feel. There is no default.
Lines 46, 55, 56 :

To put headers on each list (wherever you want: at top, or bottom), you need first to set these values. Then second, defines the placeholder in the template (as any other multi-label element).

Placeholders {label_2}, {label_3} are used, in the same way, for all HTML_Quickform renderers , and defines: unselected list (label_2), and selected list (label_3).

Lines 47, 62 and 50, 63 :

Last step to complete definition of a advmultiselect element is to set the add and remove buttons.

Here we gave names Add >> and << Remove, with a skin handled by the inputCommand CSS class.

Placeholders {add}, {remove} must exists into the template. Without them you won't see the move buttons.

Line 69 :

User's input overrides default values of the fruit advmultiselect element.

Line 110 :

Before to validate and process the form, the building form step need one more thing. Don't forget, that to manage swaps between both list, we need some javascript code. It's now time to include into our HTML stream/template.

By given the false value as argument to the getElementJs method, we have choosen to build javascript code with its script tags. Default behavior is to get only raw code without surrounding script tags. May be usefull with template integration and existing js code.

Line 114 :
We have now the form built and need to decide whether to process it or display.
Line 115 :

This is a simple display example. In your scripts you'll usually want to store the values somewhere or do whatever else. The HTML_Quickform::process method may be of interest here.

Line 121 :
The last line is pretty easy. If the form is not valid, which means that it either was not yet submitted or that there were errors, it will be displayed.

Advanced features

You should now have an understanding of basic HTML_QuickForm_advmultiselect functionality, but there are many more features in the package, each of them deserving a separate tutorial. This section will give a short overview of them and point you to the complete documentation.

The advmultiselect element offers a lot of possibilities to customize its layout and appearance. Remember that form output is done via renderers - special classes containing necessary logic. There are QuickForm renderers that directly output HTML and those that use template engines for this.

Headers allow to give caption (label) to one or both list as any other QuickForm element that support multi-labels system.

Buttons allow to swap items from one list to the other, or arrange order of your selection.

Sorts allow to re-arrange order of the selection, by the end-user. Its also allow to set (by programming) a pre-set order (alphabetic or reverse) to each list.

Headers

Headers – how to customize labels

Introduction

A label is a description text that will be displayed near the element. Some renderers can handle multiple labels for the element. Placeholders used by these renderers are different in naming convention. Nevermind, HTML_QuickForm_advmultiselect used only one standard coding that is equivalent to the QuickForm default renderer.

As {label_2} is the placeholder for the second label (unselected list), {label_3} is the placeholder for the third label (selected list), in the hash setting. See HTML_Quickform::setLabel method.

The first label is always for the advmultiselect element group itself. Its name depend of the QuickForm renderer used. See examples that follow to notice the difference.

Naming with QuickForm Default Renderer
<?php
require_once 'HTML/QuickForm.php';
require_once 'HTML/QuickForm/advmultiselect.php';

$template =
'<tr>
    <td align="right" valign="top">
        <b>{label}</b>
    </td>
    <td valign="top" align="left">
        {element}
        <!-- BEGIN error --><br/><font color="red">{error}</font><br/><!-- END error -->
    </td>
</tr>';

// Create the form, and add a header to it.
$form = new HTML_QuickForm('qfamsLabels');
$form->addElement('header', null, 'QuickForm Labels Example: default renderer');

$cars = array(
    'dodge'     =>  'Dodge',
    'chevy'     =>  'Chevy',
    'bmw'       =>  'BMW',
    'audi'      =>  'Audi',
    'porsche'   =>  'Porsche',
    'kia'       =>  'Kia',
    'subaru'    =>  'Subaru',
    'mazda'     =>  'Mazda',
    'isuzu'     =>  'Isuzu',
);

$labels = array('Cars:', 'Models', 'Your selection');

// Do the magic! Just pass your label to the element as an array!
$form->addElement('advmultiselect', 'cars', $labels, $cars);

// customize the element template
$renderer =&amp; $form->defaultRenderer();
$renderer->setElementTemplate($template);

// output the form
$form->display();
?>
Line 8 :

The first label with default renderer, is always named {label}.

Line 32 :

In this example, its value will be Cars:

Naming with QuickForm ITDynamic Renderer
<?php
require_once 'HTML/Template/Sigma.php';
require_once 'HTML/QuickForm.php';
require_once 'HTML/QuickForm/Renderer/ITDynamic.php';
require_once 'HTML/QuickForm/advmultiselect.php';

$template = '
<form {qf_attributes}>
<table class="maintable">

<!-- BEGIN qf_hidden_block -->
<div style="display: none;">
  <!-- BEGIN qf_hidden_loop -->{qf_hidden}<!-- END qf_hidden_loop -->
</div>
<!-- END qf_hidden_block -->

<!-- BEGIN qf_main_loop -->

  <!-- BEGIN qf_header -->
  <tr><th class="maintable" colspan="2">{qf_header}</th></tr>
  <!-- END qf_header -->

  <!-- BEGIN qf_element -->
  <tr>
    <td align="right" width="30%"><span class="qfLabel">{qf_label}&amp;nbsp;</span></td>
    <td>{qf_element}
      <!-- BEGIN qf_element_error --><br /><span style="color: #FF0000;">{qf_error}</span><!-- END qf_element_error -->
    </td>
  </tr>
  <!-- END qf_element -->

<!-- END qf_main_loop -->
</table>
</form>
';

// Create the form, and add a header to it.
$form = new HTML_QuickForm('qfamsLabels');
$form->addElement('header', null, 'QuickForm Labels Example: itdynamic renderer');

$cars = array(
    'dodge'     =>  'Dodge',
    'chevy'     =>  'Chevy',
    'bmw'       =>  'BMW',
    'audi'      =>  'Audi',
    'porsche'   =>  'Porsche',
    'kia'       =>  'Kia',
    'subaru'    =>  'Subaru',
    'mazda'     =>  'Mazda',
    'isuzu'     =>  'Isuzu',
);

$labels = array('Cars:', 'Models', 'Your selection');

// Do the magic! Just pass your label to the element as an array!
$form->addElement('advmultiselect', 'cars', $labels, $cars);

// set the form template
$tpl = new HTML_Template_Sigma('.');
$tpl->setTemplate($template);

$renderer = new HTML_QuickForm_Renderer_ITDynamic($tpl);

$form->accept($renderer);

// output the form
$tpl->show();
?>
Line 25 :

The first label with ITDynamic renderer, is always named {qf_label}.

Line 53 :

In this example, its value is still Cars:

In practice

Lets review in details how to set the appearance of headers in one of examples included in the package.

After the labels are set:

<?php
$ams->setLabel(array('Fruit:', 'Available', 'Selected'));
?>

Have a special look on the advmultiselect template element. Here is it:

<?php
$template = '
<table{class}>
<!-- BEGIN label_2 --><tr><th align="center">{label_2}</th><!-- END label_2 -->
<!-- BEGIN label_3 --><th align="center">{label_3}</th></tr><!-- END label_3 -->
<tr>
  <td>{unselected}</td>
  <td>{selected}</td>
</tr>
<tr>
  <td align="center">{add}</td>
  <td align="center">{remove}</td>
</tr>
</table>';
?>
Line 4 :

Header for the unselected list (named Available) is center aligned in bold with the TH tag.

Line 5 :

Header for the selected list (named Selected), is also center aligned in bold with another TH tag.

To give only a header to the selection list, either you set values as:

<?php
$ams->setLabel(array('Fruit:', null, 'Your selection'));
?>

or you remove line beginning by <!-- BEGIN label_2 --> into the advmultiselect template element.

Buttons

Buttons – how to customize action buttons

Introduction

There is two categories of button: sort and swap.

The swap buttons are included since origin, while the sort buttons were included in the 0.5.0 version.

With swap buttons, you will do your selection easily. Select item(s) (one or more), from unselected or selected list, then clic on the add or remove button to move your selection from one list to the other.

You can also double-clic on one item to move it, immediately, to the other list without to clic on the add or remove button.

Since version 1.1.0 you have ability to select or unselect all items in one stroke. You may also toggle a previous selection. This new feature is available through buttons all, none and toggle.

Since version 1.2.0 toggle selection feature is available for both single and dual multi-select boxes.

  • with one multi-select list, buttons available are only: all, none and toggle.
  • with two multi-select list, buttons available are only: add, remove, moveup, movedown, all, none and toggle. Since version 1.5.0, you may add to buttons list : movetop and movebottom.

A full example is given in appendices. See the advanced selection

With sort buttons, you have ability to reorder your selection easily. Select one item then clic on the up or down button to move it to the top or the bottom of your selection.

Order is keep in the $_POST super global array, when the form is submit; Even if you've activated the auto-arrange feature (see $sort parameter of the HTML_QuickForm_advmultiselect class constructor )

Appearance

There is two kinds of button: text and image. These are the standard html buttons we can find in a form. Default appearance is text but you can also easily use image layout. Here is how to do :

<?php
$ams->setButtonAttributes('add',    array('type' => 'image', 'src' => '/img/add.png'));
$ams->setButtonAttributes('remove', array('type' => 'image', 'src' => '/img/remove.png'));
?>

Of course, all images are supported: PNG, GIF ...

If the image file does not exist, you will get the internal text value as output without nothing else.

Remember that defaults are: " >> " for add button, and " << " for remove button.

Attributes

In version 0.4.0, there were only the basic add and remove buttons. In version 0.5.0, two new buttons were added: moveup and movedown. In version 1.1.0, three new buttons were added: all, none, and toggle. In version 1.5.0, two new buttons were added: movetop and movebottom.

Any other button identifier than add, remove, all, none, toggle, moveup, movedown, movetop, movebottom will throws a PEAR_Error.

Only five attributes may be set, with these four button identifiers; they are:

name

The form input button name. Default are: 'add', or 'remove', or 'all, or 'none', or 'toggle', or 'up', or 'down', or 'top', or 'bottom'.

Default values of the name attribute are not equivalent to button identifiers.

value

The form input button text. Default are : ' >> ', or ' << ', or ' Select All ', or ' Select None ', or ' Toggle Selection ', or ' Up ', or ' Down ', or ' Top ', or ' Bottom '.

type

The form input button kind. Default is 'button' (Can be either 'button' or 'image').

class

A CSS class identifier in one of your stylesheets.

src

URL of the image file used.

Sorts

Sorts – how to sort results

Introduction

There are two kind of sort with the advmultiselect element: The first one is only available by programming and allow an auto-arrange (alphabetic or reverse order) of each select list. The second is for end-user and allow them to sort their selection as they want.

These features required HTML_QuickForm_advmultiselect package version 0.5.0 or better.

Auto-arrange

In some case, it could be interresting to have items lists sort alphabetically when elements are moved between them, rather than gets added to the bottom (default behavior).

To get both list sort alphabetically, you have to set the $sort parameter of the HTML_QuickForm_advmultiselect class constructor with the PHP SORT_ASC constant.

To get both list sort in reverse order, you have to set the $sort parameter of the HTML_QuickForm_advmultiselect class constructor with the PHP SORT_DESC constant.

A full example is given in appendices. See the sort usage

With buttons

The other way to have your selection sorted is with help of two buttons: moveup to move an item to the top of the list, and movedown to move an item to the bottom of the list.

These buttons works only with the selection list

A full example is given in appendices. See the sort usage

Live counters

Live counters – get number of item in results

Introduction

When selection lists have lot of item, we don't expect to count each item one by one.

When it's so easy to count selections on server side, once the form is submitted, there is no ability to do the same in live, until new feature "Live counter".

This feature require HTML_QuickForm_advmultiselect package version 1.3.0 or better.

A full example is given in appendices. See live counter combines with multiple elements

Identification and localisation

Implements display of live counters (selected, unselected items) is fully independant. Its requires for each counter to add new placeholders.

For item unselected list, these placehodlers are :

For item selected list, these placehodlers are :

<?php
require_once 'HTML/QuickForm.php';
require_once 'HTML/QuickForm/advmultiselect.php';
// ...
$form = new HTML_QuickForm('amsLC');
$ams =& $form->addElement('advmultiselect', 'cars', null, $car_array);
// ...
?>

Counters identifiers (attribut ID) used by DOM API are identified by string : advmultiselect element name concat with "_selected" or "_unselected" suffix (depending of lists).

Result for example (previous code) : cars_selected or cars_unselected

advmultiselect element with single list (with checkboxes) are identified by string : "qfams_" prefix concat with advmultiselect element name

Result for example (previous code) : qfams_cars

advmultiselect element with double list are identified with string : prefix "__" (two underscores) concat with advmultiselect element name for unselected list. While selection list (selected item) is identified with string : prefix "_" (one underscore) concat with advmultiselect element name.

Result for example (previous code) : __cars and _cars

advmultiselect elements with single list (with checkboxes) are identified by DOM API with only {selected_count} and {selected_count_id} placeholders. No need to add {unselected_count} and {unselected_count_id} placeholders.

See example in appendix Live counter combines with multiple elements, and template definition $template1 lines 49-57.

Reference guide

This reference describes every method in the HTML_QuickForm_advmultiselect class.

In a two multi-select boxes default shape, there are :

In a single multi-select box default shape, there are :

Buttons (up, down) to sort item are unavailable in a single multi-select box shape.

In a two multi-select boxes custom shape, you may also have :

There are no order between setting button (up, down) attributes and setting placeholders {moveup}, {movedown} into the template.

Creating the form element

With the class constructor, you have ability to set the auto-arrange feature. This feature is an option to sort alphabetically (or reverse) when elements are moved between lists. Default behaviour is no sort (add to the bottom).

This feature is only available since version 0.5.0

You may either load options from the class constructor or with the load or loadArray functions.

load and loadArray functions with fancy attributes (disabled, style:color, ...) support are only available since version 1.5.0

constructor HTML_QuickForm_advmultiselect::HTML_QuickForm_advmultiselect

constructor HTML_QuickForm_advmultiselect::HTML_QuickForm_advmultiselect() – Class constructor

Synopsis
require_once 'HTML/QuickForm/advmultiselect.php';

void constructor HTML_QuickForm_advmultiselect::HTML_QuickForm_advmultiselect ( string $elementName = NULL , mixed $elementLabel = NULL , mixed $options = NULL , mixed $attributes = NULL , integer $sort = NULL )

Description

This package is not documented yet.

Parameter
string $elementName

Dual Select name attribute

mixed $elementLabel

Label(s) for the select boxes

mixed $options

Data to be used to populate options

mixed $attributes

Either a typical HTML attribute string or an associative array

integer $sort

Either SORT_ASC for auto ascending arrange, SORT_DESC for auto descending arrange, or NULL for no sort (append at end: default)

Throws

throws no exceptions thrown

Note

since version 0.4.0 (2005-06-25)

This function can not be called statically.

HTML_QuickForm_advmultiselect::load

HTML_QuickForm_advmultiselect::load() – Loads options from different types of data sources

Synopsis
require_once 'HTML/QuickForm/advmultiselect.php';

PEAR_Error HTML_QuickForm_advmultiselect::load ( mixed &$options , mixed $param1 = null , mixed $param2 = null , mixed $param3 = null , mixed $param4 = null )

Description

This method overloaded parent method of select element, to allow loading options with fancy attributes.

Parameter
mixed &$options

Options source currently supports assoc array or DB_result

mixed $param1

(optional) See function detail

mixed $param2

(optional) See function detail

mixed $param3

(optional) See function detail

mixed $param4

(optional) See function detail

Return value

returns TRUE on success

Throws

throws PEAR_Error

See

see HTML_QuickForm_advmultiselect::loadArray() .

Note

since version 1.5.0 (2009-02-15)

This function can not be called statically.

Example
<?php
/**
 * Custom advMultiSelect HTML_QuickForm element
 * loading values with fancy attributes (disabled, ...)
 *
 * @version    $Id: load.xml,v 1.1 2009-02-01 15:12:40 farell Exp $
 * @author     Laurent Laville <pear@laurent-laville.org>
 * @package    HTML_QuickForm_advmultiselect
 * @subpackage Examples
 * @access     public
 * @example    examples/qfams_custom_3.php
 *             qfams_custom_3 source code
 * @link       http://www.laurent-laville.org/img/qfams/screenshot/custom3.png
 *             screenshot (Image PNG, 374x275 pixels) 4.96 Kb
 */

require_once 'HTML/QuickForm.php';
require_once 'HTML/QuickForm/advmultiselect.php';

$form = new HTML_QuickForm('amsCustom3');
$form->removeAttribute('name');        // XHTML compliance

// same as default element template but wihtout the label (in first td cell)
$withoutLabel = <<<_HTML
<tr valign="top">
    <td align="right">
        &nbsp;
    </td>
    <td align="left">
        <!-- BEGIN error --><span style="color: #ff0000;">{error}</span><br /><!-- END error -->{element}
    </td>
</tr>
_HTML;

// more XHTML compliant
// replace default element template with label, because submit button have no label
$renderer =& $form->defaultRenderer();
$renderer->setElementTemplate($withoutLabel, 'send');

$fruit_array = array(
    'apple'     =>  'Apple',
    'orange'    =>  'Orange',
    'pear'      =>  array('Pear', array('disabled' => 'disabled')),
    'banana'    =>  'Banana',
    'cherry'    =>  'Cherry',
    'kiwi'      =>  'Kiwi',
    'lemon'     =>  'Lemon',
    'lime'      =>  'Lime',
    'tangerine' =>  'Tangerine',
);

// rendering with QF renderer engine and template system
$form->addElement('header', null, 'Advanced Multiple Select: custom layout ');

$ams =& $form->createElement('advmultiselect', 'fruit', null, null,
                             array('class' => 'pool')
);

$ams->setLabel(array('Fruit:', 'Available', 'Selected'));
$ams->setButtonAttributes('add',    array('value' => 'Add >>',
                                           'class' => 'inputCommand'
));
$ams->setButtonAttributes('remove', array('value' => '<< Remove',
                                           'class' => 'inputCommand'
));
$template = '
<table{class}>
<!-- BEGIN label_2 --><tr><th align="center">{label_2}</th><!-- END label_2 -->
<!-- BEGIN label_3 --><th align="center">{label_3}</th></tr><!-- END label_3 -->
<tr>
  <td>{unselected}</td>
  <td>{selected}</td>
</tr>
<tr>
  <td>{add}</td>
  <td>{remove}</td>
</tr>
</table>';
$ams->setElementTemplate($template);

$ams->load($fruit_array, 'apple,pear');

$form->addElement($ams);
$form->addElement('submit', 'send', 'Send');
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3c.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>HTML_QuickForm::advMultiSelect custom example 3</title>
<style type="text/css">
<!--
body {
  background-color: #FFF;
  font-family: Verdana, Arial, helvetica;
  font-size: 10pt;
}

table.pool {
  border: 0;
  background-color: lightyellow;
}
table.pool td {
  padding-left: 1em;
}
table.pool th {
  font-size: 80%;
  font-style: italic;
  text-align: center;
}
table.pool select {
  background-color: lightblue;
}

.inputCommand {
    background-color: #d0d0d0;
    border: 1px solid #7B7B88;
    width: 7em;
    margin-bottom: 2px;
}
 -->
</style>
<?php echo $ams->getElementJs(false); ?>
</head>
<body>
<?php
if ($form->validate()) {
    $clean = $form->getSubmitValues();

    echo '<pre>';
    print_r($clean);
    echo '</pre>';
}
$form->display();
?>
</body>
</html>

HTML_QuickForm_advmultiselect::loadArray

HTML_QuickForm_advmultiselect::loadArray() – Loads the options from an associative array

Synopsis
require_once 'HTML/QuickForm/advmultiselect.php';

mixed HTML_QuickForm_advmultiselect::loadArray ( array $arr , mixed $values = null )

Description

This method overloaded parent method of select element, to allow to load array of options with fancy attributes.

Parameter
array $arr

Associative array of options

mixed $values

(optional) Array or comma delimited string of selected values

Return value

returns TRUE on success

Throws

throws PEAR_Error

See

see HTML_QuickForm_advmultiselect::load()

Note

since version 1.5.0 (2009-02-15)

This function can not be called statically.

Example

See HTML_QuickForm_advmultiselect::load() example.

HTML_QuickForm_advmultiselect::getPersistantOptions

HTML_QuickForm_advmultiselect::getPersistantOptions() – Returns list of persistant options

Synopsis
require_once 'HTML/QuickForm/advmultiselect.php';

array HTML_QuickForm_advmultiselect::getPersistantOptions ( )

Description

Returns list of persistant options (key-values) that could not be selected or unselected.

Throws

throws no exceptions thrown

Note

since version 1.5.0 (2009-02-15)

This function can not be called statically.

HTML_QuickForm_advmultiselect::setPersistantOptions

HTML_QuickForm_advmultiselect::setPersistantOptions() – Sets which items should be persistant

Synopsis
require_once 'HTML/QuickForm/advmultiselect.php';

mixed HTML_QuickForm_advmultiselect::setPersistantOptions ( mixed $optionValues , boolean $persistant = true )

Description

Sets which items should have the disabled attribute to keep it persistant

Parameter
mixed $optionValues

Options (key-values) that should be persistant

boolean $persistant

(optional) TRUE if persistant, FALSE otherwise

Throws
Possible PEAR_Error values
Error message Reason Solution
Argument 1 of HTML_QuickForm_advmultiselect::setPersistantOptions is not a valid array Tried to give array or comma delimited string of selected values Check the $optionValues argument data type and content
Argument 2 of HTML_QuickForm_advmultiselect::setPersistantOptions is not a boolean Tried to give a TRUE or FALSE value Check the $persistant argument data type
Note

since version 1.5.0 (2009-02-15)

This function can not be called statically.

Example
<?php
require_once 'HTML/QuickForm.php';
require_once 'HTML/QuickForm/advmultiselect.php';

$form = new HTML_QuickForm('ams');
$form->removeAttribute('name');        // XHTML compliance

$fruit_array = array(
    'apple'     =>  'Apple',
    'orange'    =>  'Orange',
    'pear'      =>  'Pear',
    'banana'    =>  'Banana',
    'cherry'    =>  'Cherry',
    'tangerine' =>  'Tangerine'
);

$ams =& $form->createElement('advmultiselect', 'fruit', null, null,
                             array('class' => 'pool', 'style' => 'width:200px;')
);
$ams->setLabel(array('Fruit:', 'Available', 'Selected'));

$ams->setButtonAttributes('add'       , 'class=inputCommand');
$ams->setButtonAttributes('remove'    , 'class=inputCommand');
$ams->setButtonAttributes('all'       , 'class=inputCommand');
$ams->setButtonAttributes('none'      , 'class=inputCommand');
$ams->setButtonAttributes('toggle'    , 'class=inputCommand');
$ams->setButtonAttributes('moveup'    , 'class=inputCommand');
$ams->setButtonAttributes('movedown'  , 'class=inputCommand');
$ams->setButtonAttributes('movetop'   , 'class=inputCommand');
$ams->setButtonAttributes('movebottom', 'class=inputCommand');

$templateDual = '
<table{class}>
<!-- BEGIN label_2 --><tr><th>{label_2}</th><!-- END label_2 -->
<!-- BEGIN label_3 --><th>&nbsp;</th><th>{label_3}</th></tr><!-- END label_3 -->
<tr>
  <td>{unselected}</td>
  <td align="center">
    {add}<br />{remove}<br /><br />
    {all}<br />{none}<br />{toggle}<br /><br />
    {moveup}<br />{movedown}<br />{movetop}<br />{movebottom}
  </td>
  <td>{selected}</td>
</tr>
</table>
';

$ams->load($fruit_array, 'pear');

$ams->setPersistantOptions(array('pear', 'tangerine'));

$ams->setElementTemplate($templateDual);

$form->addElement($ams);

$buttons[] =& $form->createElement('submit', null, 'Submit');
$buttons[] =& $form->createElement('reset',  null, 'Reset');
$form->addGroup($buttons, null, '&nbsp;');
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3c.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>HTML_QuickForm::advMultiSelect persistant options example</title>
<style type="text/css">
<!--
body {
  background-color: #FFF;
  font-family: Verdana, Arial, helvetica;
  font-size: 10pt;
}

table.pool {
  border: 0;
  background-color: #787878;
}
table.pool td {
  padding-left: 1em;
}
table.pool th {
  font-size: 80%;
  font-style: italic;
  text-align: center;
}
table.pool select {
  color: #242424;
  background-color: #eee;
}

.inputCommand {
  width: 120px;
}
<?php echo $ams->getElementCss(); ?>
 -->
</style>
<?php echo $ams->getElementJs(false, true); ?>
</head>
<body>
<?php
if ($form->validate()) {
    $clean = $form->getSubmitValues();

    var_dump($clean);

    // if apple fruit is selected, then pear may be remove from next selection
    if (in_array('apple', $clean['fruit'])) {
        $ams->setPersistantOptions('pear', false);
    } else {
        $ams->setPersistantOptions('pear', true);
        $selection = $ams->getSelected();
        if (!in_array('pear', $selection)) {
            array_push($selection, 'pear');
            $ams->setSelected($selection);
        }
    }
}
$form->display();
?>
</body>
</html>

Buttons

Here, you can choose between standard form text or image button. You can also set the CSS class used to change the look and feel of buttons.

HTML_QuickForm_advmultiselect::setButtonAttributes

HTML_QuickForm_advmultiselect::setButtonAttributes() – Sets the button attributes

Synopsis
require_once 'HTML/QuickForm/advmultiselect.php';

void HTML_QuickForm_advmultiselect::setButtonAttributes ( string $button , mixed $attributes = NULL )

Description

The basic settings gave standard form input buttons. You may change the look with some CSS if you set the class attribute in the $attributes hash (second parameter). See example section.

Only five attributes may be set, they are:

name

The form input button name. Default are: 'add', or 'remove', or 'all', or 'none', or 'toggle', or 'up', or 'down', or 'top', or 'bottom'.

value

The form input button text. Default are ' >> ', or ' << ', or ' Select All ', or ' Select None ', or ' Toggle Selection ', or ' Up ', or ' Down ', or ' Top ', or ' Bottom '.

type

The form input button kind. Default is 'button' (Can be either 'button' or 'image').

class

A CSS class identifier in one of your stylesheets.

src

URL of the image file used.

Parameter
string $button

Button identifier, either 'add', 'remove', 'all', 'none', 'toggle', 'moveup' 'movedown' 'movetop' or 'movebottom'

mixed $attributes

(optional) Either a typical HTML attribute string or an associative array

Throws
Possible PEAR_Error values
Error message Reason Solution
Argument 1 of HTML_QuickForm_advmultiselect::setButtonAttributes is not a string Tried to give a button identifier of unknown type Check the $button argument data type
Argument 1 of HTML_QuickForm_advmultiselect::setButtonAttributes has unexpected value Tried to give a button identifier of unknown value Check the $button argument data range
Note

since version 0.4.0 (2005-06-25)

This function can not be called statically.

Example

In this example, the 'add' and 'remove' buttons have look set by the css class 'inputCommand'.

<?php
require_once 'HTML/QuickForm.php';
require_once 'HTML/QuickForm/advmultiselect.php';

$form = new HTML_QuickForm('ams');
$form->removeAttribute('name');        // XHTML compliance

$fruit_array = array(
    'apple'     =>  'Apple',
    'orange'    =>  'Orange',
    'pear'      =>  'Pear',
    'banana'    =>  'Banana',
    'cherry'    =>  'Cherry',
    'kiwi'      =>  'Kiwi',
    'lemon'     =>  'Lemon',
    'lime'      =>  'Lime',
    'tangerine' =>  'Tangerine',
);

// rendering with QF renderer engine and template system
$form->addElement('header', null, 'Advanced Multiple Select: custom layout ');

$ams =& $form->addElement('advmultiselect', 'fruit', null, $fruit_array);

$ams->setLabel(array('Fruit:', 'Available', 'Selected'));
$ams->setButtonAttributes('add',    array('value' => 'Add >>',
                                          'class' => 'inputCommand'
));
$ams->setButtonAttributes('remove', array('value' => '<< Remove',
                                          'class' => 'inputCommand'
));
$template = '
<table{class}>
<!-- BEGIN label_2 --><tr><th align="center">{label_2}</th><!-- END label_2 -->
<!-- BEGIN label_3 --><th align="center">{label_3}</th></tr><!-- END label_3 -->
<tr>
  <td>{unselected}</td>
  <td>{selected}</td>
</tr>
<tr>
  <td>{add}</td>
  <td>{remove}</td>
</tr>
</table>';
$ams->setElementTemplate($template);

if (isset($_POST['fruit'])) {
    $form->setDefaults(array('fruit' => $_POST['fruit']));
}

$form->addElement('submit', 'send', 'Send');
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3c.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>HTML_QuickForm::advMultiSelect example </title>
<style type="text/css">
<!--
body {
  background-color: #FFF;
  font-family: Verdana, Arial, helvetica;
  font-size: 10pt;
}

.inputCommand {
    background-color: #d0d0d0;
    border: 1px solid #7B7B88;
    width: 7em;
    margin-bottom: 2px;
}
// -->
</style>
<?php echo $ams->getElementJs(false); ?>
</head>
<body>
<?php
if ($form->validate()) {
    $clean = $form->getSubmitValues();

    echo '<pre>';
    print_r($clean);
    echo '</pre>';
}
$form->display();
?>
</body>
</html>

You may also use images rather than standard form input button. Replaces lines :

<?php
$ams->setButtonAttributes('add',    array('value' => 'Add >>',
                                          'class' => 'inputCommand'
));
$ams->setButtonAttributes('remove', array('value' => '<< Remove',
                                          'class' => 'inputCommand'
));
?>

by lines that should like :

<?php
$ams->setButtonAttributes('add',    array('type' => 'image',
                                          'src'  => '/img/add.png'
));
$ams->setButtonAttributes('remove', array('type' => 'image',
                                          'src'  => '/img/remove.png'
));
?>

Basic renderer

This renderer is based on HTML_QuickForm_advmultiselect code and require no external classes to do its job. It's very similar to HTML_Quickform default renderer .

HTML_QuickForm_advmultiselect::toHtml

HTML_QuickForm_advmultiselect::toHtml() – Returns the HTML generated for the advanced mutliple select component

Synopsis
require_once 'HTML/QuickForm/advmultiselect.php';

string HTML_QuickForm_advmultiselect::toHtml ( )

Description

Returns the advmultiselect element structure as HTML.

Throws

throws no exceptions thrown

Note

since version 0.4.0 (2005-06-25)

This function can not be called statically.

Template-based renderer

Here is the core of customization of this QuickForm element. With the three methods below, you can easily include it in an existing template page with all parts (CSS, JS, lists, buttons) at the right place.

HTML_QuickForm_advmultiselect::getElementCss

HTML_QuickForm_advmultiselect::getElementCss() – Gets default element stylesheet for a single multi-select shape render

Synopsis
require_once 'HTML/QuickForm/advmultiselect.php';

string HTML_QuickForm_advmultiselect::getElementCss ( boolean $raw = TRUE )

Description

If your browser does not support javascript, or for any reasons you have choosen to disable it, then your only possibility is to use the single checkboxes multi-select shape of HTML_QuickForm_advmultiselect element.

You get a more or less decent result with just the basic settings, but it is also highly configurable, so you can almost get what you want.

The basic settings can be applied with just the placeholder {stylesheet} into your template element. It can also be applied with getElementCss() method. If you does not have existing style tags in your html page, you must call the method with FALSE argument. Default behavior returns only the raw css data without style tags. Useful when using with template engine.

Parameter
boolean $raw

(optional) html output with style tags or just raw data

Throws

throws no exceptions thrown

Note

since version 0.4.0 (2005-06-25)

This function can not be called statically.

Example
<?php
require_once 'HTML/QuickForm.php';
require_once 'HTML/QuickForm/advmultiselect.php';

$form = new HTML_QuickForm('ams');
$form->removeAttribute('name');        // XHTML compliance

$fruit_array = array(
    'apple'     =>  'Apple',
    'orange'    =>  'Orange',
    'pear'      =>  'Pear',
    'banana'    =>  'Banana',
    'cherry'    =>  'Cherry',
    'kiwi'      =>  'Kiwi',
    'lemon'     =>  'Lemon',
    'lime'      =>  'Lime',
    'tangerine' =>  'Tangerine'
);

// rendering with QF renderer engine and template system
$form->addElement('header', null, 'Advanced Multiple Select: custom layout ');

$ams =& $form->addElement('advmultiselect', 'fruit', null, $fruit_array);
$ams->setLabel(array('Fruit:', 'Available', 'Selected'));

// template for a single checkboxes multi-select element shape
$template = '
<table{class}>
<!-- BEGIN label_3 --><tr><th>{label_3}</th></tr><!-- END label_3 -->
<tr>
  <td>{selected}</td>
</tr>
</table>
';
$ams->setElementTemplate($template);

if ($_SERVER['REQUEST_METHOD'] == 'GET') {
    // fruit default values already selected without any end-user actions
    $form->setDefaults(array('fruit' => array('kiwi','lime')));

} elseif (isset($_POST['fruit'])) {
    // fruit end-user selection
    $form->setDefaults(array('fruit' => $_POST['fruit']));
}

$buttons[] =& $form->createElement('submit', null, 'Submit');
$buttons[] =& $form->createElement('reset', null, 'Reset');
$form->addGroup($buttons);
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3c.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>HTML_QuickForm::advMultiSelect custom example 4b</title>
<style type="text/css">
<!--
body {
  background-color: #FFF;
  font-family: Verdana, Arial, helvetica;
  font-size: 10pt;
}
<?php echo $ams->getElementCss(); ?>
// -->
</style>
</head>
<body>
<?php
if ($form->validate()) {
    $clean = $form->getSubmitValues();

    echo '<pre>';
    print_r($clean);
    echo '</pre>';
}
$form->display();
?>
</body>
</html>

HTML_QuickForm_advmultiselect::getElementJs

HTML_QuickForm_advmultiselect::getElementJs() – Returns the javascript code generated to handle this element

Synopsis
require_once 'HTML/QuickForm/advmultiselect.php';

string HTML_QuickForm_advmultiselect::getElementJs ( boolean $raw = TRUE , boolean $min = FALSE )

Description

The basic (and default) settings can be applied with just the placeholder {javascript} into your template element. If you does not have existing script tags in your html page, you must call the method with FALSE argument. Default behaviour returns only the raw js data without script tags. Useful when using with template engine.

Parameter
boolean $raw

(optional) html output with script tags or just raw data

boolean $min

(optional) uses javascript compressed version

Throws

throws no exceptions thrown

Note

since version 0.4.0 (2005-06-25)

$min parameter is available since version 1.5.0

This function can not be called statically.

HTML_QuickForm_advmultiselect::setElementTemplate

HTML_QuickForm_advmultiselect::setElementTemplate() – Sets element template

Synopsis
require_once 'HTML/QuickForm/advmultiselect.php';

void HTML_QuickForm_advmultiselect::setElementTemplate ( string $html = NULL , boolean $js = TRUE )

Description

It is so easy to re-arrange select boxes, headers and buttons position. The template is a bit of html code with reserved placeholders words. They are:

stylesheet

The CSS delimited by the style tags required only for the single multi-select with checkboxes shape. Not included in the default template. You can use instead, the getElementCss() method.

javascript

The JavaScript delimited by the script tags required to manage item of both multi-select boxes. If it is not included, you can use instead, the getElementJs() method.

class

A CSS class identifier in one of your stylesheets that is the default table layout. Default values are:


<table border="0" cellpadding="10" cellspacing="0">
label_2

The unselected list header

label_3

The selected list header

unselected

The unselected list.

selected

The selected list.

add

The add button to swap one (or more) item from the unselected to the selected list.

remove

The remove button to swap one (or more) item back from the selected to the unselected list.

moveup

The button to move one item of the selected list to the top.

movedown

The button to move one item of the selected list to the bottom.

movetop

The button to move one item of the selected list directly at the top of the list

movebottom

The button to move one item of the selected list directly at the bottom of the list

Parameter
string $html

(optional) The HTML surrounding select boxes and buttons

boolean $js

(optional) if we need to include qfams javascript handler

Throws

throws no exceptions thrown

Note

since version 0.4.0 (2005-06-25)

This function can not be called statically.

Example

In this partial example, the fruit list select boxes are set to vertical alignement with images for the 'add' and 'remove' buttons. Default presentation are horizontal alignment with input text buttons in the middle side.

<?php
require_once 'HTML/QuickForm.php';
require_once 'HTML/QuickForm/advmultiselect.php';

$form = new HTML_QuickForm('ams');
$form->removeAttribute('name');        // XHTML compliance

$fruit_array = array(
    'apple'     =>  'Apple',
    'orange'    =>  'Orange',
    'pear'      =>  'Pear',
    'banana'    =>  'Banana',
    'cherry'    =>  'Cherry',
    'kiwi'      =>  'Kiwi',
    'lemon'     =>  'Lemon',
    'lime'      =>  'Lime',
    'tangerine' =>  'Tangerine',
);

$ams =& $form->addElement('advmultiselect', 'fruit', null, $fruit_array);
$ams->setLabel(array('Fruit:', 'Available', 'Selected'));
$ams->setButtonAttributes('add',    array('type' => 'image', 'src' => '/img/down.png'));
$ams->setButtonAttributes('remove', array('type' => 'image', 'src' => '/img/up.png'));

// vertical select box with image buttons as selector
$template = '
<table{class}>
<!-- BEGIN label_2 --><tr><th align="center">{label_2}</th></tr><!-- END label_2 -->
<tr>
  <td>{unselected}</td>
</tr>
<tr>
  <td align="center">{add}{remove}</td>
</tr>
<tr>
  <td>{selected}</td>
</tr>
<!-- BEGIN label_3 --><tr><th align="center">{label_3}</th></tr><!-- END label_3 -->
</table>';
$ams->setElementTemplate($template);

// ....
?>

Examples appendix

Basic usage

Basic usage with default layout

This example has no particular goals. It should be your first run to show and handle a advmultiselect element that will emulate a multi-select.

Without any customization

<?php
/**
 * Basic advMultiSelect HTML_QuickForm element
 * without any customization.
 *
 * @version    $Id: examples-basic1.xml,v 1.5 2009-02-11 08:51:16 farell Exp $
 * @author     Laurent Laville <pear@laurent-laville.org>
 * @package    HTML_QuickForm_advmultiselect
 * @subpackage Examples
 * @access     public
 * @example    examples/qfams_basic_1.php
 *             qfams_basic_1 source code
 * @link       http://www.laurent-laville.org/img/qfams/screenshot/basic1.png
 *             screenshot (Image PNG, 406x247 pixels) 4.95 Kb
 */

require_once 'HTML/QuickForm.php';
require_once 'HTML/QuickForm/advmultiselect.php';

$form = new HTML_QuickForm('amsBasic1');
$form->removeAttribute('name');        // XHTML compliance

// same as default element template but wihtout the label (in first td cell)
$withoutLabel = <<<_HTML
<tr valign="top">
    <td align="right">
        &nbsp;
    </td>
    <td align="left">
        <!-- BEGIN error --><span style="color: #ff0000;">{error}</span><br /><!-- END error -->{element}
    </td>
</tr>
_HTML;

// more XHTML compliant
// replace default element template with label, because submit button have no label
$renderer =& $form->defaultRenderer();
$renderer->setElementTemplate($withoutLabel, 'send');

$car_array = array(
    'dodge'     =>  'Dodge',
    'chevy'     =>  'Chevy',
    'bmw'       =>  'BMW',
    'audi'      =>  'Audi',
    'porsche'   =>  'Porsche',
    'kia'       =>  'Kia',
    'subaru'    =>  'Subaru',
    'mazda'     =>  'Mazda',
    'isuzu'     =>  'Isuzu',
);

// rendering with all default options
$form->addElement('header', null, 'Advanced Multiple Select: default layout ');

$form->addElement('advmultiselect', 'cars', 'Cars:', $car_array);

$form->addElement('submit', 'send', 'Send');
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3c.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>HTML_QuickForm::advMultiSelect basic example 1</title>
<style type="text/css">
<!--
body {
  background-color: #FFF;
  font-family: Verdana, Arial, helvetica;
  font-size: 10pt;
}
 -->
</style>
</head>
<body>
<?php
if ($form->validate()) {
    $clean = $form->getSubmitValues();

    echo '<pre>';
    print_r($clean);
    echo '</pre>';
}
$form->display();
?>
</body>
</html>

Extended usage

Custom usage with a simple template

In this example, here are our goals :

Your first template element

<?php
/**
 * Custom advMultiSelect HTML_QuickForm element
 * using stylesheet rules selectors and a template.
 *
 * The template allows to add label as headers of dual select box
 * and moves the button to another location (below each select box).
 *
 * @version    $Id: examples-custom1.xml,v 1.5 2009-02-11 08:51:16 farell Exp $
 * @author     Laurent Laville <pear@laurent-laville.org>
 * @package    HTML_QuickForm_advmultiselect
 * @subpackage Examples
 * @access     public
 * @example    examples/qfams_custom_1.php
 *             qfams_custom_1 source code
 * @link       http://www.laurent-laville.org/img/qfams/screenshot/custom1.png
 *             screenshot (Image PNG, 677x197 pixels) 4.80 Kb
 */

require_once 'HTML/QuickForm.php';
require_once 'HTML/QuickForm/advmultiselect.php';

$form = new HTML_QuickForm('amsCustom1');
$form->removeAttribute('name');        // XHTML compliance

// same as default element template but without the label (in first td cell)
$withoutLabel = <<<_HTML
<tr valign="top">
    <td align="right">
        &nbsp;
    </td>
    <td align="left">
        <!-- BEGIN error --><span style="color: #ff0000;">{error}</span><br /><!-- END error -->{element}
    </td>
</tr>
_HTML;

// more XHTML compliant
// replace default element template with label, because submit button have no label
$renderer =& $form->defaultRenderer();
$renderer->setElementTemplate($withoutLabel, 'send');

$fruit_array = array(
    'apple'     =>  'Apple',
    'orange'    =>  'Orange',
    'pear'      =>  'Pear',
    'banana'    =>  'Banana',
    'cherry'    =>  'Cherry',
    'kiwi'      =>  'Kiwi',
    'lemon'     =>  'Lemon',
    'lime'      =>  'Lime',
    'tangerine' =>  'Tangerine',
);

// rendering with QF renderer engine and template system
$form->addElement('header', null, 'Advanced Multiple Select: custom layout ');

$ams =& $form->addElement('advmultiselect', 'fruit', null, $fruit_array,
                           array('size' => 5,
                                 'class' => 'pool', 'style' => 'width:300px;'
                                )
);
$ams->setLabel(array('Fruit:', 'Available', 'Selected'));
$ams->setButtonAttributes('add',    array('value' => 'Add >>',
                                           'class' => 'inputCommand'
));
$ams->setButtonAttributes('remove', array('value' => '<< Remove',
                                           'class' => 'inputCommand'
));
$template = '
<table{class}>
<!-- BEGIN label_2 --><tr><th align="center">{label_2}</th><!-- END label_2 -->
<!-- BEGIN label_3 --><th align="center">{label_3}</th></tr><!-- END label_3 -->
<tr>
  <td>{unselected}</td>
  <td>{selected}</td>
</tr>
<tr>
  <td align="center">{add}</td>
  <td align="center">{remove}</td>
</tr>
</table>';
$ams->setElementTemplate($template);

$form->addElement('submit', 'send', 'Send');
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3c.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>HTML_QuickForm::advMultiSelect custom example 1</title>
<style type="text/css">
<!--
body {
  background-color: #FFF;
  font-family: Verdana, Arial, helvetica;
  font-size: 10pt;
}

table.pool {
  border: 0;
  background-color: lightyellow;
}
table.pool th {
  font-size: 80%;
  font-style: italic;
  text-align: center;
}
table.pool select {
  background-color: lightblue;
}

.inputCommand {
    background-color: #d0d0d0;
    border: 1px solid #7B7B88;
    width: 7em;
    margin-bottom: 2px;
}
 -->
</style>
<?php echo $ams->getElementJs(false); ?>
</head>
<body>
<?php
if ($form->validate()) {
    $clean = $form->getSubmitValues();

    echo '<pre>';
    print_r($clean);
    echo '</pre>';
}
$form->display();
?>
</body>
</html>

Advanced selection usage

Advanced selection

In this example, here are our goals :

How to do a global selection

<?php
/**
 * Custom advMultiSelect HTML_QuickForm element
 * with extended buttons (select all, select none, toggle selection)
 *
 * @version    $Id: examples-custom7.xml,v 1.5 2009-02-11 08:51:16 farell Exp $
 * @author     Laurent Laville <pear@laurent-laville.org>
 * @package    HTML_QuickForm_advmultiselect
 * @subpackage Examples
 * @access     public
 * @example    examples/qfams_custom_7.php
 *             qfams_custom_7 source code
 * @link       http://www.laurent-laville.org/img/qfams/screenshot/custom7.png
 *             screenshot (Image PNG, 640x525 pixels) 160 Kb
 */

require_once 'HTML/QuickForm.php';
require_once 'HTML/QuickForm/advmultiselect.php';

$form = new HTML_QuickForm('amsCustom7');
$form->removeAttribute('name');        // XHTML compliance

$fruit_array = array(
    'apple'     =>  'Apple',
    'orange'    =>  'Orange',
    'pear'      =>  'Pear',
    'banana'    =>  'Banana',
    'cherry'    =>  'Cherry',
    'kiwi'      =>  'Kiwi',
    'lemon'     =>  'Lemon',
    'lime'      =>  'Lime',
    'tangerine' =>  'Tangerine',
);


// rendering with QF renderer engine and template system
$form->addElement('header', null, 'Advanced Multiple Select: custom layout ');

$ams =& $form->addElement('advmultiselect', 'fruit', null, $fruit_array,
                           array('class' => 'pool', 'style' => 'width:200px;')
);
$ams->setLabel(array('Fruit:', 'Available', 'Selected'));

$ams->setButtonAttributes('add'     , 'class=inputCommand');
$ams->setButtonAttributes('remove'  , 'class=inputCommand');
$ams->setButtonAttributes('all'     , 'class=inputCommand');
$ams->setButtonAttributes('none'    , 'class=inputCommand');
$ams->setButtonAttributes('toggle'  , 'class=inputCommand');
$ams->setButtonAttributes('moveup'  , 'class=inputCommand');
$ams->setButtonAttributes('movedown', 'class=inputCommand');

// template for a single checkboxes multi-select element shape
$template1 = '
<table{class}>
<!-- BEGIN label_3 --><tr><th>{label_3}</th><th>&nbsp;</th></tr><!-- END label_3 -->
<tr>
  <td>{selected}</td>
  <td>{all}<br />{none}<br />{toggle}</td>
</tr>
</table>
';

// template for a dual multi-select element shape
$template2 = '
<table{class}>
<!-- BEGIN label_2 --><tr><th>{label_2}</th><!-- END label_2 -->
<!-- BEGIN label_3 --><th>&nbsp;</th><th>{label_3}</th></tr><!-- END label_3 -->
<tr>
  <td>{unselected}</td>
  <td align="center">
    {add}<br />{remove}<br /><br />{all}<br />{none}<br /><br />{moveup}<br />{movedown}<br />
  </td>
  <td>{selected}</td>
</tr>
</table>
';

if (isset($_POST['multiselect'])) {
    $ams->setElementTemplate($template2);
} else {
    $ams->setElementTemplate($template1);
}

if ($_SERVER['REQUEST_METHOD'] == 'GET') {
    // fruit default values already selected without any end-user actions
    $form->setDefaults(array('fruit' => array('kiwi','lime')));
}

$buttons[] =& $form->createElement('submit', null, 'Submit');
$buttons[] =& $form->createElement('reset',  null, 'Reset');
$buttons[] =& $form->createElement('checkbox', 'multiselect', null,
                                   'use dual select boxes layout');
$form->addGroup($buttons, null, '&nbsp;');
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3c.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>HTML_QuickForm::advMultiSelect custom example 7</title>
<style type="text/css">
<!--
body {
  background-color: #FFF;
  font-family: Verdana, Arial, helvetica;
  font-size: 10pt;
}

table.pool {
  border: 0;
  background-color: cyan;
}
table.pool td {
  padding-left: 1em;
}
table.pool th {
  font-size: 80%;
  font-style: italic;
  text-align: center;
}
table.pool select {
  color: gray;
  background-color: #eee;
}

.inputCommand {
  width: 120px;
}
<?php
if (!isset($_POST['multiselect'])) {
    echo $ams->getElementCss();
}
?>
 -->
</style>
<?php echo $ams->getElementJs(false); ?>
</head>
<body>
<?php
if ($form->validate()) {
    $clean = $form->getSubmitValues();

    echo '<pre>';
    print_r($clean);
    echo '</pre>';
}
$form->display();
?>
</body>
</html>

Sort usage

Auto-arrange feature usage

In this example, here are our goals :

How to sort the select boxes

<?php
/**
 * Custom advMultiSelect HTML_QuickForm element
 * that allows to manage sort of select boxes.
 *
 * @version    $Id: examples-custom5.xml,v 1.5 2009-02-11 08:51:16 farell Exp $
 * @author     Laurent Laville <pear@laurent-laville.org>
 * @package    HTML_QuickForm_advmultiselect
 * @subpackage Examples
 * @access     public
 * @example    examples/qfams_custom_5.php
 *             qfams_custom_5 source code
 * @link       http://www.laurent-laville.org/img/qfams/screenshot/custom5.png
 *             screenshot (Image PNG, 609x318 pixels) 9.94 Kb
 */

require_once 'HTML/QuickForm.php';
require_once 'HTML/QuickForm/advmultiselect.php';

$form = new HTML_QuickForm('amsCustom5');
$form->removeAttribute('name');        // XHTML compliance

// same as default element template but wihtout the label (in first td cell)
$withoutLabel = <<<_HTML
<tr valign="top">
    <td align="right">
        &nbsp;
    </td>
    <td align="left">
        <!-- BEGIN error --><span style="color: #ff0000;">{error}</span><br /><!-- END error -->{element}
    </td>
</tr>
_HTML;

// more XHTML compliant
// replace default element template with label, because submit button have no label
$renderer =& $form->defaultRenderer();
$renderer->setElementTemplate($withoutLabel, 'validate');

$fruit_array = array(
    'apple'     =>  'Apple',
    'orange'    =>  'Orange',
    'pear'      =>  'Pear',
    'banana'    =>  'Banana',
    'cherry'    =>  'Cherry',
    'kiwi'      =>  'Kiwi',
    'lemon'     =>  'Lemon',
    'lime'      =>  'Lime',
    'tangerine' =>  'Tangerine',
);

// decides either both select list will have their elements be arranged or not
if (isset($_POST['autoArrange'])) {
    if ($_POST['autoArrange'] == 'A') {
        $sort = SORT_ASC;
    } elseif ($_POST['autoArrange'] == 'D') {
        $sort = SORT_DESC;
    } else {
        $sort = false;
    }
} else {
    $sort = false;
}

// rendering with QF renderer engine and template system
$form->addElement('header', null,
                  'For demo purpose only: must be validate to be active');
$arrange[] =& $form->createElement('radio', null, null, 'Auto arrange asc.',  'A');
$arrange[] =& $form->createElement('radio', null, null, 'Auto arrange desc.', 'D');
$arrange[] =& $form->createElement('radio', null, null, 'No auto arrange',    'N');
$form->addGroup($arrange, 'autoArrange', 'Sort list:');
$form->setDefaults(array('autoArrange' => 'N'));

$form->addElement('submit', 'validate', 'Validate');

$form->addElement('header', null, 'Advanced Multiple Select: custom layout ');

$ams =& $form->addElement('advmultiselect', 'fruit', null, $fruit_array,
                           array('class' => 'pool', 'style' => 'width:200px;'),
                           $sort
);
$ams->setLabel(array('Fruit:', 'Available', 'Selected'));

$ams->setButtonAttributes('add'     , 'class=inputCommand');
$ams->setButtonAttributes('remove'  , 'class=inputCommand');
$ams->setButtonAttributes('moveup'  , 'class=inputCommand');
$ams->setButtonAttributes('movedown', 'class=inputCommand');

// template for a dual multi-select element shape
$template = '
<table{class}>
<!-- BEGIN label_2 --><tr><th>{label_2}</th><!-- END label_2 -->
<!-- BEGIN label_3 --><th>&nbsp;</th><th>{label_3}</th></tr><!-- END label_3 -->
<tr>
  <td>{unselected}</td>
  <td align="center">
    {add}<br />{remove}<br /><br />{moveup}<br />{movedown}<br />
  </td>
  <td>{selected}</td>
</tr>
</table>
';
$ams->setElementTemplate($template);

if ($_SERVER['REQUEST_METHOD'] == 'GET') {
    // fruit default values already selected without any end-user actions
    $form->setDefaults(array('fruit' => array('kiwi','lime')));
}

$buttons[] =& $form->createElement('submit', null, 'Submit');
$buttons[] =& $form->createElement('reset',  null, 'Reset');
$form->addGroup($buttons, null, '&nbsp;');
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3c.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>HTML_QuickForm::advMultiSelect custom example 5</title>
<style type="text/css">
<!--
body {
  background-color: #FFF;
  font-family: Verdana, Arial, helvetica;
  font-size: 10pt;
}

table.pool {
  border: 0;
  background-color: #339900;
}
table.pool td {
  padding-left: 1em;
}
table.pool th {
  font-size: 80%;
  font-style: italic;
  text-align: center;
}
table.pool select {
  color: white;
  background-color: #006600;
}

.inputCommand {
  width: 60px;
}
 -->
</style>
<?php echo $ams->getElementJs(false); ?>
</head>
<body>
<?php
if ($form->validate()) {
    $clean = $form->getSubmitValues();

    echo '<pre>';
    print_r($clean);
    echo '</pre>';
}
$form->display();
?>
</body>
</html>

Combines multiple elements

Multiple usage with two different layouts

In this example, here are our goals :

Two different layouts on the same page

<?php
/**
 * Mixed advMultiSelect HTML_QuickForm elements.
 * Two widgets on the same page/form with one javascript code instance
 *
 * @version    $Id: examples-multiple1.xml,v 1.5 2009-02-11 08:51:16 farell Exp $
 * @author     Laurent Laville <pear@laurent-laville.org>
 * @package    HTML_QuickForm_advmultiselect
 * @subpackage Examples
 * @access     public
 * @example    examples/qfams_multiple_1.php
 *             qfams_multiple_1 source code
 * @link       http://www.laurent-laville.org/img/qfams/screenshot/multiple1.png
 *             screenshot (Image PNG, 566x392 pixels) 8.82 Kb
 */

require_once 'HTML/QuickForm.php';
require_once 'HTML/QuickForm/advmultiselect.php';

$form = new HTML_QuickForm('amsMultiple1');
$form->removeAttribute('name');        // XHTML compliance

// same as default element template but wihtout the label (in first td cell)
$withoutLabel = <<<_HTML
<tr valign="top">
    <td align="right">
        &nbsp;
    </td>
    <td align="left">
        <!-- BEGIN error --><span style="color: #ff0000;">{error}</span><br /><!-- END error -->{element}
    </td>
</tr>
_HTML;

// more XHTML compliant
// replace default element template with label, because submit button have no label
$renderer =& $form->defaultRenderer();
$renderer->setElementTemplate($withoutLabel, 'send');

$fruit_array = array(
    'apple'     =>  'Apple',
    'orange'    =>  'Orange',
    'pear'      =>  'Pear',
    'banana'    =>  'Banana',
    'cherry'    =>  'Cherry',
    'kiwi'      =>  'Kiwi',
    'lemon'     =>  'Lemon',
    'lime'      =>  'Lime',
    'tangerine' =>  'Tangerine',
);

$car_array = array(
    'dodge'     =>  'Dodge',
    'chevy'     =>  'Chevy',
    'bmw'       =>  'BMW',
    'audi'      =>  'Audi',
    'porsche'   =>  'Porsche',
    'kia'       =>  'Kia',
    'subaru'    =>  'Subaru',
    'mazda'     =>  'Mazda',
    'isuzu'     =>  'Isuzu',
);

// rendering with all default options
$form->addElement('header', null, 'Advanced Multiple Select: default layout ');

$ams1 =& $form->addElement('advmultiselect', 'cars', 'Cars:', $car_array);
$ams1->setElementTemplate(null, false);

// rendering with css selectors and API selLabel(), setButtonAttributes()
$form->addElement('header', null, 'Advanced Multiple Select: custom layout ');

$ams2 =& $form->addElement('advmultiselect', 'fruit', null, $fruit_array,
                           array('size' => 5,
                                 'class' => 'pool', 'style' => 'width:200px;'
                                )
);

$ams2->setLabel(array('Fruit:', 'Available', 'Selected'));
$ams2->setButtonAttributes('add',    array('value' => 'Add', 'name' => 'add1',
                                           'class' => 'inputCommand'
));
$ams2->setButtonAttributes('remove', array('value' => 'Remove', 'name' => 'remove1',
                                           'class' => 'inputCommand'
));
$ams2->setElementTemplate(null, false);

$form->addElement('submit', 'send', 'Send');
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3c.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>HTML_QuickForm::advMultiSelect multiple example 1</title>
<style type="text/css">
<!--
body {
  background-color: #FFF;
  font-family: Verdana, Arial, helvetica;
  font-size: 10pt;
}

table.pool {
  border: 0;
  background-color: #339900;
  width:450px;
}
table.pool th {
  font-size: 80%;
  font-style: italic;
  text-align: left;
}
table.pool select {
  color: white;
  background-color: #006600;
}

.inputCommand {
    background-color: #d0d0d0;
    border: 1px solid #7B7B88;
    width: 7em;
    margin-bottom: 2px;
}
 -->
</style>
<?php
echo $ams1->getElementJs(false, true);
?>
</head>
<body>
<?php
if ($form->validate()) {
    $clean = $form->getSubmitValues();

    echo '<pre>';
    print_r($clean);
    echo '</pre>';
}
$form->display();
?>
</body>
</html>

Template engine usage

Template usage with Sigma engine

In this example, here are our goals :

ITDynamic renderer with Sigma

<?php
/**
 * Custom advMultiSelect HTML_QuickForm element
 * embedded into a Sigma template and using the QF dynamic renderer.
 *
 * @version    $Id: examples-template1.xml,v 1.4 2009-02-11 08:51:16 farell Exp $
 * @author     Laurent Laville <pear@laurent-laville.org>
 * @package    HTML_QuickForm_advmultiselect
 * @subpackage Examples
 * @access     public
 * @example    examples/qfams_template_1.php
 *             qfams_template_1 source code
 * @link       http://www.laurent-laville.org/img/qfams/screenshot/template1.png
 *             screenshot (Image PNG, 665x376 pixels) 23.3 Kb
 */

require_once 'HTML/Template/Sigma.php';
require_once 'HTML/QuickForm.php';
require_once 'HTML/QuickForm/Renderer/ITDynamic.php';
require_once 'HTML/QuickForm/advmultiselect.php';

$form = new HTML_QuickForm('amsTemplate1');
$form->removeAttribute('name');        // XHTML compliance

$fruit_array = array(
    'apple'     =>  'Apple',
    'orange'    =>  'Orange',
    'pear'      =>  'Pear',
    'banana'    =>  'Banana',
    'cherry'    =>  'Cherry',
    'kiwi'      =>  'Kiwi',
    'lemon'     =>  'Lemon',
    'lime'      =>  'Lime',
    'tangerine' =>  'Tangerine',
);

// rendering with css selectors and API selLabel(), setButtonAttributes()
$form->addElement('header', null, 'Advanced Multiple Select: custom layout ');

$form->addElement('text', 'name', 'Name:', array('size' => 40, 'maxlength' => 80));

$ams =& $form->addElement('advmultiselect', 'fruit', null, $fruit_array,
                           array('size' => 15,
                                 'class' => 'pool', 'style' => 'width:150px;'
                                )
);
$ams->setLabel(array('Fruit:', 'Available', 'Selected'));
$ams->setButtonAttributes('add',    array('value' => 'Add >>',
                                           'class' => 'inputCommand'
));
$ams->setButtonAttributes('remove', array('value' => '<< Remove',
                                           'class' => 'inputCommand'
));
$template = '
<table{class}>
<!-- BEGIN label_2 --><tr><th>{label_2}</th><!-- END label_2 -->
<!-- BEGIN label_3 --><th>&nbsp;</th><th>{label_3}</th></tr><!-- END label_3 -->
<tr>
  <td valign="top">{unselected}</td>
  <td align="center">{add}{remove}</td>
  <td valign="top">{selected}</td>
</tr>
</table>
';
$ams->setElementTemplate($template);

$form->addElement('submit', 'send', 'Send', array('class' => 'inputCommand'));

$form->addRule('name', 'Your name is required', 'required');
$form->addGroupRule('fruit', 'At least one fruit is required', 'required', null, 1);

$form->applyFilter('__ALL__', 'trim');
$form->applyFilter('__ALL__', 'strip_tags');

$valid = $form->validate();

$tpl = new HTML_Template_Sigma('.');
$tpl->loadTemplateFile('itdynamic.html');
$tpl->setVariable('ams_javascript', $ams->getElementJs(false));

$renderer = new HTML_QuickForm_Renderer_ITDynamic($tpl);

$form->accept($renderer);

if ($valid) {
    $clean = $form->getSubmitValues();

    $msg = sprintf("<p>Welcome <b>%s</b> you've selected these fruits:<br />%s</p>",
           $clean['name'], implode(', ', $clean['fruit']));

    $tpl->setVariable('message_form_validate', $msg);
}
$tpl->show();
?>

Live counter combines with multiple elements

Live counter on two advmultiselect elements

In this example, here are our goals :

Multiple live counters on same page

<?php
/**
 * Two advMultiSelect HTML_QuickForm elements with all properties
 * that can be display in one or two select box mode.
 * This example demonstrate the new feature of version 1.3.0 : Live Counter
 *
 * @version    $Id: examples-multiple2.xml,v 1.6 2009-02-11 08:51:16 farell Exp $
 * @author     Laurent Laville <pear@laurent-laville.org>
 * @package    HTML_QuickForm_advmultiselect
 * @subpackage Examples
 * @access     public
 * @example    examples/qfams_multiple_2.php
 *             qfams_multiple_2 source code
 * @link       http://www.laurent-laville.org/img/qfams/screenshot/multiple2.png
 *             screenshot (Image PNG, 595x511 pixels) 11.9 Kb
 */

require_once 'HTML/QuickForm.php';
require_once 'HTML/QuickForm/advmultiselect.php';

$form = new HTML_QuickForm('amsMultiple2');
$form->removeAttribute('name');        // XHTML compliance

$fruit_array = array(
    'apple'     =>  'Apple',
    'orange'    =>  'Orange',
    'pear'      =>  'Pear',
    'banana'    =>  'Banana',
    'cherry'    =>  'Cherry',
    'kiwi'      =>  'Kiwi',
    'lemon'     =>  'Lemon',
    'lime'      =>  'Lime',
    'tangerine' =>  'Tangerine',
);

$car_array = array(
    'dodge'     =>  'Dodge',
    'chevy'     =>  'Chevy',
    'bmw'       =>  'BMW',
    'audi'      =>  'Audi',
    'porsche'   =>  'Porsche',
    'kia'       =>  'Kia',
    'subaru'    =>  'Subaru',
    'mazda'     =>  'Mazda',
    'isuzu'     =>  'Isuzu',
);

// template for a single checkboxes multi-select element shape with live counter
$template1 = '
<table{class}>
<!-- BEGIN label_3 --><tr><th>{label_3}(<span id="{selected_count_id}">{selected_count}</span>)</th><th>&nbsp;</th></tr><!-- END label_3 -->
<tr>
  <td>{selected}</td>
  <td>{all}<br />{none}<br />{toggle}</td>
</tr>
</table>
';

// template for a dual multi-select element shape with live counter
$template2 = '
<table{class}>
<!-- BEGIN label_2 --><tr><th>{label_2}(<span id="{unselected_count_id}">{unselected_count}</span>)</th><!-- END label_2 -->
<!-- BEGIN label_3 --><th>&nbsp;</th><th>{label_3}(<span id="{selected_count_id}">{selected_count}</span>)</th></tr><!-- END label_3 -->
<tr>
  <td>{unselected}</td>
  <td align="center">
    {add}<br />{remove}<br /><br />{all}<br />{none}<br />{toggle}<br /><br />{moveup}<br />{movedown}<br />
  </td>
  <td>{selected}</td>
</tr>
</table>
';

$defaults = array();

// first QF ams element
$form->addElement('header', null, 'Advanced Multiple Select: Live Counter - pool1 style ');

$ams1 =& $form->addElement('advmultiselect', 'cars', null, $car_array,
    array('size' => 10, 'class' => 'pool1', 'style' => 'width:200px;')
);
$ams1->setLabel(array('Cars:', 'Available', 'Selected'));
$ams1->setButtonAttributes('add',      array('name' => 'add1',      'class' => 'inputCommand'));
$ams1->setButtonAttributes('remove',   array('name' => 'remove1',   'class' => 'inputCommand'));
$ams1->setButtonAttributes('all',      array('name' => 'all1',      'class' => 'inputCommand'));
$ams1->setButtonAttributes('none',     array('name' => 'none1',     'class' => 'inputCommand'));
$ams1->setButtonAttributes('toggle',   array('name' => 'toggle1',   'class' => 'inputCommand'));
$ams1->setButtonAttributes('moveup',   array('name' => 'moveup1',   'class' => 'inputCommand'));
$ams1->setButtonAttributes('movedown', array('name' => 'movedown1', 'class' => 'inputCommand'));

if (isset($_POST['multiselect1'])) {
    $ams1->setElementTemplate($template2);
} else {
    $ams1->setElementTemplate($template1);
}

// second QF ams element
$form->addElement('header', null, 'Advanced Multiple Select: Live Counter - pool2 style ');

$ams2 =& $form->addElement('advmultiselect', 'fruit', null, $fruit_array,
    array('size' => 5, 'class' => 'pool2', 'style' => 'width:300px;')
);
$ams2->setLabel(array('Fruit:', 'Available', 'Selected'));
$ams2->setButtonAttributes('add',      array('name' => 'add2',      'class' => 'inputCommand'));
$ams2->setButtonAttributes('remove',   array('name' => 'remove2',   'class' => 'inputCommand'));
$ams2->setButtonAttributes('all',      array('name' => 'all2',      'class' => 'inputCommand'));
$ams2->setButtonAttributes('none',     array('name' => 'none2',     'class' => 'inputCommand'));
$ams2->setButtonAttributes('toggle',   array('name' => 'toggle2',   'class' => 'inputCommand'));
$ams2->setButtonAttributes('moveup',   array('name' => 'moveup2',   'class' => 'inputCommand'));
$ams2->setButtonAttributes('movedown', array('name' => 'movedown2', 'class' => 'inputCommand'));

if (isset($_POST['multiselect2'])) {
    $ams2->setElementTemplate($template2);
} else {
    $ams2->setElementTemplate($template1);
}

$buttons[] =& $form->createElement('submit', null, 'Submit');
$buttons[] =& $form->createElement('reset',  null, 'Reset');
$buttons[] =& $form->createElement('checkbox', 'multiselect1', null,
                                   'cars list dual select');
$buttons[] =& $form->createElement('checkbox', 'multiselect2', null,
                                   'fruit list dual select');
$form->addGroup($buttons, null, '&nbsp;');
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3c.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>HTML_QuickForm::advMultiSelect multiple example 2</title>
<style type="text/css">
<!--
body {
  background-color: #FFF;
  font-family: Verdana, Arial, helvetica;
  font-size: 10pt;
}

table.pool1, table.pool2 {
  border: 0;
  background-color: #339900;
  width:450px;
}
table.pool2 {
  background-color: #CFC;
}
table.pool1 th, table.pool2 th {
  font-size: 80%;
  font-style: italic;
  text-align: left;
}
table.pool1 td, table.pool2 td {
  vertical-align: top;
}
table.pool1 select, table.pool2 select {
  color: white;
  background-color: #006600;
}

.inputCommand {
    background-color: #d0d0d0;
    border: 1px solid white;
    width: 9em;
    margin-bottom: 2px;
}
<?php
if (!isset($_POST['multiselect1'])) {
    echo $ams1->getElementCss();
}
if (!isset($_POST['multiselect2'])) {
    echo $ams2->getElementCss();
}
?>
 -->
</style>
<?php echo $ams1->getElementJs(false); ?>
</head>
<body>
<?php
if ($form->validate()) {
    $clean = $form->getSubmitValues();

    echo '<pre>';
    print_r($clean);
    echo '</pre>';
}
$form->display();
?>
<script type="text/javascript">
//
function init() {
    QFAMS.init(['cars','fruit']);
}
window.addEventListener('load', init, false);
//
</script>
</body>
</html>