Xoops表单

来自站长百科
跳转至: 导航、​ 搜索

导航: 上一页 | 首页 | DedeCMS | 帝国CMS | Drupal | PHPCMS | PHP168 | Joomla | PowerEasy | SupeSite

表单的多种展现形式[ ]

XOOPS模块开发中讲解了表单对象,调用XoopsThemeForm类的display函数显示表单,在XOOPS系统中除了 XoopsThemeForm类之外,还有XoopsSimpleForm类也是继承自XoopsForm类,提供简单的表单展现形式。而且还可以自定义继承自XoopsForm类的子类来提供更多的展现形式。但是XoopsForm类的子类并不区分具体的表单元素,因此在需要区分具体的表单元素时,通过继承XoopsForm类的子类就不便于展现,此时XoopsForm类还可以把表单的内容输出到模板中。接下来本例将讲解如何处理表单的多种展现形式,本例的文件夹结构如下:

/modules/formrender
	/images
	/logo.png
	/templates
	/formrender_assign.html
	/assign.php
	/index.php
	/xoops_version.php

其中xoops_version.php的内容如下:

/modules/formrender/xoops_version.php
<?php
$modversion['name'] = "表单 - 多种展现形式";
$modversion['version'] = 0.01;
$modversion['description'] = "演示表单的多种展现形式";
$modversion['author'] = <<<AUTHOR
胡争辉 QQ: 443089607 QQMail: hu_zhenghui@qq.com GTalk: huzhengh
GMail: huzhengh@gmail.com Skype: huzhenghui"
AUTHOR;
$modversion['credits'] = "";
$modversion['license'] = "版权所有";
$modversion['image'] = "images/logo.png";
$modversion['dirname'] = "formrender";
$modversion["hasMain"] = 1;
$modversion["sub"][0]["name"] = "模板化";
$modversion["sub"][0]["url"] = "assign.php";
$modversion["templates"][0]["file"] = "formrender_assign.html";
$modversion["templates"][0]["description"] = "Template for assign.php";
?>

使用XoopsSimpleForm类显示表单的页面源代码如下:

/modules/formrender/index.php
<?php
require_once dirname(__FILE__)."/../../mainfile.php";
include XOOPS_ROOT_PATH."/header.php";
include_once XOOPS_ROOT_PATH."/class/xoopsformloader.php";
$simple_form = new XoopsSimpleForm("Simple Form", "simple_form", "");
$simple_form->addElement(new XoopsFormLabel("Id", 1, "id"));
$simple_form->addElement(new XoopsFormText("Section", "section", 20, 20));
$simple_form->addElement(new XoopsFormButton("", "submit", _SUBMIT, "submit"));
$simple_form->display();
include XOOPS_ROOT_PATH."/footer.php";
?>

与前面代码比较可以看出,差别仅在于创建表单对象的类名。

$simple_form = new XoopsSimpleForm("Simple Form", "simple_form", "");

效果如图 3 1 XoopsSimpleForm效果所示。

Xop104.png

该表单对象生成的HTML代码如下:

Simple Form
<form name='simple_form' id='simple_form' action='' method='post'>
    <b>Id</b><br />
    1<br />
    <b>Section</b><br />
    <input type='text' name='section' id='section' size='20' maxlength='20' value='' /><br />
    <b></b><br />
    <input type='submit' class='formButton' name='submit' id='submit' value='提交' /><br />
</form>

通过对比可以理解XoopsSimpleForm类的显示方式。在实际项目中,很少有直接使用XoopsSimpleForm类的情况,而且通过XoopsSimpleForm类把表单的内容输出到模板中,如果要把本例的表单输出到模板中,需要进行如下的修改:

/modules/formrender/assign.php
<?php
require_once dirname(__FILE__)."/../../mainfile.php";
$xoopsOption["template_main"] = "formrender_assign.html";
include XOOPS_ROOT_PATH."/header.php";
/* 详见源文件 */
$simple_form->assign($xoopsTpl);
include XOOPS_ROOT_PATH."/footer.php";
?>

与index.php页面相比,仅修改了一行代码。

$simple_form->assign($xoopsTpl);

其中assign函数用于将表单的内容输出到模板中,

/class/xoopsform/form.php
	function assign(&$tpl) {}

参数$tpl是模板对象,在页面中通常是$xoopsTpl对象。将表单的内容输出到模板后,就可以在模板中使用了,本例中对应的模板源代码如下:

/modules/formrender/templates/formrender_assign.html
<{strip}>
    <fieldset>
        <legend>
            <{$simple_form.title}>
        </legend>
	    <form name="<{$simple_form.name}>" action="<{$simple_form.action}>" method="<{$simple_form.method}>" <{$simple_form.extra}> >
	        <{$simple_form.javascript}>
	        <table>
                <tr class="odd">
                    <td style="text-align: right;">
                        <{$simple_form.elements.id.caption}>
                    </td>
                    <td>
                        <{$simple_form.elements.id.body}>
                    </td>
                </tr>
                <tr class="even">
                    <td style="text-align: right;">
                        <{$simple_form.elements.section.caption}>
                    </td>
                    <td>
                        <{$simple_form.elements.section.body}>
                    </td>
                </tr>
	        </table>
            <{$simple_form.elements.submit.body}>
	    </form>
    </fieldset>
<{/strip}>

assign函数按表单的名称输出到模板,例如本例中表单的名称是simple_form,所以模板中的变量是$simple_form;表单的标题输出成了$simple_form.title变量;表单的名称输出成了$simple_form.name变量;表单的提交目标输出成$simple_form.action;表单的提交方法输出成了$simple_form.method;表单其他的标记输出成了$simple_form.extra,通常包括表单验证相关代码。例如本例中生成的form标记代码如下:

<form name="simple_form" action="" method="post" onsubmit="return xoopsFormValidate_simple_form();" >

$simple_form.javascript包括与表单相关的脚本,通常包括表单验证相关的代码,例如本例中生成的脚本如下。

<!-- Start Form Validation JavaScript //-->
<script type='text/javascript'>
<!--//
function xoopsFormValidate_simple_form() { myform = window.document.simple_form; return true;
}
//--></script>
<!-- End Form Vaidation JavaScript //-->

上述变量都是针对于表单的变量,$simple_form中还包括针对表单对象的变量,这些变量以数组的形式保存在$simple_form.elements中,每个表单对象对应于数组的一项,键名就是表单对象的名称,例如名称为id的标签对象,对应的变量就是$simple_form.elements.id,该变量也是数组,例如键名为caption的项代表对象的标题,键名为body的项代表对象的内容。本例中$simple_form.elements.id.caption代表标签对象的标题 Id,$simple_form.elements.id.body代表标签对象的内容1。不同类型的表单对象都包括相同的键名,本例中文本框对象的名称是section,对应的变量是$simple_form.elements.section,相应的代表文本框对象标题的变量就是$simple_form.elements.section.caption,值是Section,相应的代表文本框对象内容的变量就是$simple_form.elements.section.body,生成的HTML代码如下:

<input type='text' name='section' id='section' size='20' maxlength='20' value= />

表单元素对应的变量包括与显示该表单元素相关的信息,这些信息可以按需在模板中使用,也可以不使用,例如本例中的提交按钮的名称是submit,对应的变量为$simple_form.elements.submit。本例中没有使用提交按钮的标题变量$simple_form.elements.submit.caption,只使用了提交按钮的内容变量$simple_form.elements.submit.body,生成的HTML代码如下:

<input type='submit' class='formButton' name='submit' id='submit' value='提交' />

显示的效果如图3-2用模板显示表单所示。

Xop105.png

表单基础控件[ ]

上一节介绍了XOOPS系统中表单的多种展现形式,XOOPS系统提供的表单控件均支持这些表现形式,前面介绍了生成文本框的 XoopsFormText类、生成提交按钮的XoopsFormButton类、生成隐藏域的XoopsFormHidden类、生成标签的 XoopsFormLabel类,本节中继续介绍其他的基础控件。本例的文件夹结构如下:

/modules/formelement
	/images
	/logo.png
	/index.php
	/xoops_version.php

其中xoops_version.php文件内容如下:

/modules/formelement/xoops_version.php
<?php
$modversion['name'] = "表单 - 基本元素";
$modversion['version'] = 0.01;
$modversion['description'] = "演示表单的基本元素";
$modversion['author'] = <<<AUTHOR
胡争辉 QQ: 443089607 QQMail: hu_zhenghui@qq.com GTalk: huzhengh
GMail: huzhengh@gmail.com Skype: huzhenghui"
AUTHOR;
$modversion['credits'] = "";
$modversion['license'] = "版权所有";
$modversion['image'] = "images/logo.png";
$modversion['dirname'] = "formelement";
$modversion["hasMain"] = 1;
?>

页面源代码如下。

/modules/formelement/index.php
<?php
require_once dirname(__FILE__)."/../../mainfile.php";
$myts = MyTextSanitizer::getInstance();
/* 详见源文件 */
include XOOPS_ROOT_PATH."/header.php";
include_once XOOPS_ROOT_PATH."/class/xoopsformloader.php";
$form_element = new XoopsThemeForm("Form Element", "form_element", "");
/* 详见源文件 */
$form_element->display();
include XOOPS_ROOT_PATH."/footer.php";
?>

生成的页面效果如图3-3基本元素所示。

Xop106.png

由于需要处理提交表单,所以先获取文本处理对象。

$myts = MyTextSanitizer::getInstance();

在对提交的数据处理后,开始显示页面,先加载表单相关类。

include_once XOOPS_ROOT_PATH."/class/xoopsformloader.php";

然后创建表单对象。

$form_element = new XoopsThemeForm("Form Element", "form_element", "");

为表单对象添加控件后显示表单。

$form_element->display();

下面逐一讲解表单中的控件以及相应的处理方式。首先处理复选框,先判断是否提交了复选框控件的数据。复选框控件包括任意多个复选框,所以数据应为数组,如果没有提交复选框数据,则数据值应为空数组。

if (false === isset($_POST["checkbox"])) {
    $checkbox = array();

如果提交的数据不是数组,则数据值也应为数组。

} elseif (false === is_array($_POST["checkbox"])) {
    $checkbox = array();

如果提交的数据是数组,则需要对提交的数据转义,还原成原始数据。

} else {
    $checkbox = array();
    foreach ($_POST["checkbox"] as $checkbox_value) {
        if(true === is_string($checkbox_value)) {
            $checkbox[] = $myts->stripSlashesGPC($checkbox_value);
        }
    }
}

这里通过遍历数组成员,对每个成员转义然后组合成数据数组。复选框控件支持初始值,但是复选框的初始值需要经过转义,由于复选框的初始值是数组,所以需要遍历数组成员,对每个成员转义后组合成数组。

$checkbox_values = array();
foreach ($checkbox as $checkbox_value) {
    $checkbox_values[] = $myts->htmlSpecialChars($checkbox_value);
}

其中htmlSpecialChars函数是MyTextSanitizer类的成员函数,定义如下。

/class/module.textsanitizer.php
	function htmlSpecialChars($text) {}

转义后生成的数组可以作为创建复选框控件的初始值。

$form_checkbox = new XoopsFormCheckBox("Check Box", "checkbox", $checkbox_values);

其中XoopsFormCheckBox是复选框类,构造函数定义如下。

/class/xoopsform/formcheckbox.php
	function XoopsFormCheckBox($caption, $name, $value = null, $delimeter = "") {}

参数$caption是复选框的标题,参数$name是复选框的名称,参数$value是复选框的初始值。创建复选框对象后,可以向复选框添加选项。

$form_checkbox->addOption("disablesmiley", _DISABLESMILEY);
$form_checkbox->addOption("disablehtml", _DISABLEHTML);

其中addOption是XoopsFormCheckBox类的成员函数,定义如下。

function addOption($value, $name="") {}

其中参数$value是复选框的值,参数$name是复选框显示的文字。本例中复选框的值是固定内容,而且没有需要转义的特殊字符,所以直接传入,如果是可变的内容,而且包括需要转义的特殊字符,则需要转义,本例的代码则需要改为如下的形式。

$form_checkbox->addOption($myts->htmlSpecialChars("disablesmiley"), _DISABLESMILEY);
$form_checkbox->addOption($myts->htmlSpecialChars("disablehtml"), _DISABLEHTML);

添加选项后就可以把复选框对象加入到表单中。

$form_element->addElement($form_checkbox);

最后在页面中生成的HTML代码如下。

<input type='checkbox' name='checkbox[]' value='disablesmiley' />关闭表情图
<input type='checkbox' name='checkbox[]' value='disablehtml' />关闭HTML语法

通过对比可以了解复选框对象生成HTML代码的方式。然后讲解密码框,先判断是否提交了密码框控件的数据,密码框的数据应当是字符串,如果没有提交相应的数据,则设置为空字符串。

if (false === isset($_POST["password"])) {
    $password = "";

然后判断提交的数据是否是字符串,如果不是字符串则设置密码框的值为空字符串。

} elseif (false === is_string($_POST["password"])) {
    $password = "";

如果提交的数据是字符串,则转义后获取用户提交的内容。

} else {
    $password = $myts->stripSlashesGPC($_POST["password"]);
}

用户提交的内容作为密码框控件的初始值时,还需要进行转义。

$form_password = new XoopsFormPassword("Password", "password", 20, 20,
    $myts->htmlSpecialChars($password));

其中XoopsFormPassword是密码框类,构造函数定义如下。

/class/xoopsform/formpassword.php
	function XoopsFormPassword($caption, $name, $size, $maxlength, $value="") {}

参数$caption是密码框的标题,参数$name是密码框的名称,参数$size是密码框的显示大小,参数$maxlength是密码框中文字的最大长度,参数$value是密码框的初始值,该值需要转义。创建对象后,就可以把密码框加入到表单中。

$form_element->addElement($form_password);

最后在页面中生成的HTML代码如下。

<input type='password' name='password' id='password' size='20' maxlength='20' value= />

通过对比可以了解密码框的生成方式。接下来讲解单选按钮,先判断是否提交了单选按钮的数据,单选按钮的数据应当是字符串,如果没有提交相应的数据,则设置单选按钮提交的数据为空字符串。

if (false === isset($_POST["radio"])) {
    $radio = "";

然后判断提交的数据是否是字符串,如果不是字符串则设置单选按钮提交的数据为空字符串。

} elseif (false === is_string($_POST["radio"])) {
    $radio = "";

如果提交的数据是字符串,则转义后获取用户通过单选按钮提交的内容。

} else {
    $radio = $myts->stripSlashesGPC($_POST["radio"]);
}

用户提交的内容作为单选按钮的初始值时,还需要进行转义。

$form_radio = new XoopsFormRadio("Radio","radio", $myts->htmlSpecialChars($radio));

其中XoopsFormRadio是单选按钮类,构造函数定义如下。

/class/xoopsform/formradio.php
	function XoopsFormRadio($caption, $name, $value = null, $delimeter = "") {}

参数$caption是单选按钮的标题,参数$name是单选按钮的名称,参数$value是单选按钮的初始值,该值需要转义。创建对象后,就可以为单选按钮添加选项了。

$form_radio->addOption("left", _LEFT);
$form_radio->addOption("center", _CENTER);
$form_radio->addOption("right", _RIGHT);

其中addOption是XoopsFormRadio类的成员函数,定义如下。

function addOption($value, $name="") {}

其中参数$value是单选按钮的值,参数$name是单选按钮显示的文字。本例中单选按钮的值是固定内容,而且没有需要转义的特殊字符,所以直接传入,如果是可变的内容,而且包括需要转义的特殊字符,则需要转义,本例的代码则需要改为如下的形式。

$form_radio->addOption($myts->htmlSpecialChars("left"), _LEFT);
$form_radio->addOption($myts->htmlSpecialChars("center"), _CENTER);
$form_radio->addOption($myts->htmlSpecialChars("right"), _RIGHT);

添加选项后就可以把单选按钮对象加入到表单中。

$form_element->addElement($form_radio);

在页面中生成的HTML代码如下。

<input type='radio' name='radio' value='left' />靠左
<input type='radio' name='radio' value='center' />居中
<input type='radio' name='radio' value='right' />靠右

通过对比可以了解单选按钮的生成方式。然后讲解选择框,选择框包括单项选择框和多项选择框两种情况,首先讲解单项选择框,与单选按钮类似,先判断是否提交了单项选择框的数据,单项选择框的数据应当是字符串,如果没有提交相应的数据,则设置单项选择框提交的数据为空字符串。

if (false === isset($_POST["selectsingle"])) {
    $select_single = "";

然后判断提交的数据是否是字符串,如果不是字符串则设置单项选择框提交的数据为空字符串。

} elseif (false === is_string($_POST["selectsingle"])) {
    $select_single = "";

如果提交的数据是字符串,则转义后获取用户通过单项选择框提交的内容。

} else {
    $select_single = $myts->stripSlashesGPC($_POST["selectsingle"]);
}

用户提交的内容作为单项选择框的初始值时,不需要进行转义。

$form_select_single = new XoopsFormSelect("Select Single", "selectsingle", $select_single);

其中XoopsFormSelect是选择框类,构造函数定义如下。

/class/xoopsform/formselect.php
	function XoopsFormSelect($caption, $name, $value=null, $size=1, $multiple=false) {}

参数$caption是选择框的标题,参数$name是选择框的名称,参数$value是选择框的初始值,该值需要转义,参数$size是选择框显示的条目数,参数$multiple指示选择框为单项选择框还是多项选择框,值为false时代表单项选择框,值为true时代表多项选择框,默认值是 false。创建对象后,就可以为单项选择框添加选项了。

$form_select_single->addOption("startswith", _STARTSWITH);
$form_select_single->addOption("endswith", _ENDSWITH);
$form_select_single->addOption("matches", _MATCHES);
$form_select_single->addOption("contains", _CONTAINS);

其中addOption是XoopsFormSelect类的成员函数,定义如下。

function addOption($value, $name="") {}

其中参数$value是选项的值,参数$name是选项显示的文字。与复选框和单选按钮不同,选择框会对选项的值进行转义处理,所以在传入时不需要额外的转义。添加选项后就可以把单项选择框加入到表单中。

$form_element->addElement($form_select_single);

在页面中生成的HTML代码如下。

<select  size='1' name='selectsingle' id='selectsingle'>
<option value='startswith' selected='selected'>起始</option>
<option value='endswith'>结束</option>
<option value='matches'>符合</option>
<option value='contains'>包含</option>
</select>

通过对比可以了解单项选择框的生成方式。下面讲解多项选择框,与复选框类似,先判断是否提交了多项选择框的数据。多项选择框允许同时选择任意多个选项,所以数据应为数组,如果没有提交多项选择框数据,则数据值应为空数组。

if (false === isset($_POST["selectmultiple"])) {
    $select_multiple = array();

如果提交的数据不是数组,则数据值也应为数组。

} elseif (false === is_array($_POST["selectmultiple"])) {
    $select_multiple = array();

如果提交的数据是数组,则需要对提交的数据转义,还原成原始数据。

} else {
    $select_multiple = array();
    foreach ($_POST["selectmultiple"] as $select_value) {
        if (true === is_string($select_value)) {
            $select_multiple[] = $myts->stripSlashesGPC($select_value);
        }
    }
}

这里通过遍历数组成员,对每个成员转义然后组合成数据数组。用户提交的数据作为多项选择框的初始值时,不需要进行转义。

$form_select_multiple = new XoopsFormSelect("Select Multiple", "selectmultiple",
    $select_multiple, 5, true);

创建多项选择框后,可以向多项选择框添加选项。

$form_select_multiple->addOption("second", _SECOND);
$form_select_multiple->addOption("minute", _MINUTE);
$form_select_multiple->addOption("hour", _HOUR);
$form_select_multiple->addOption("day", _DAY);
$form_select_multiple->addOption("week", _WEEK);
$form_select_multiple->addOption("month", _MONTH);

添加选项后就可以把复选框对象加入到表单中。

$form_element->addElement($form_select_multiple);

最后在页面中生成的HTML代码如下。

<select  size='5' name='selectmultiple[]' id='selectmultiple[]' multiple='multiple'>
<option value='second'>1秒</option>
<option value='minute'>1分钟</option>
<option value='hour'>1小时</option>
<option value='day'>1天</option>
<option value='week'>1周</option>
<option value='month'>1月</option>
</select>

通过对比可以了解多项选择框对象生成HTML代码的方式。接下来讲解重置按钮,重置按钮与提交按钮类似,都是通过XoopsFormButton类生成,区别在于参数$type的值设置为reset。

$form_reset = new XoopsFormButton("reset", "reset", "Reset", "reset");
$form_element->addElement($form_reset);

为了便于查看提交的结果,本例还在表单中增加标签显示提交的内容,如图 3 4 基本元素提交的结果所示。

Xop107.png


自定义控件[ ]

上一节介绍了XOOPS系统中提供的表单基础控件,这些控件是对HTML元素的简单封装。除了直接使用基础控件外,在XOOPS系统中还支持自定义控件,使用自定义控件与使用基础控件同样方便,本节中将介绍XOOPS系统中的自定义控件。本例的文件夹结构如下:

/modules/formextends
	/images
	/logo.png
	/index.php
	/xoops_version.php

其中xoops_version.php文件内容如下:

/modules/formextends/xoops_version.php
<?php
$modversion['name'] = "表单 - 自定义控件";
$modversion['version'] = 0.01;
$modversion['description'] = "演示表单的自定义控件";
$modversion['author'] = <<<AUTHOR
胡争辉 QQ: 443089607 QQMail: hu_zhenghui@qq.com GTalk: huzhengh
GMail: huzhengh@gmail.com Skype: huzhenghui"
AUTHOR;
$modversion['credits'] = "";
$modversion['license'] = "版权所有";
$modversion['image'] = "images/logo.png";
$modversion['dirname'] = "formextends";
$modversion["hasMain"] = 1;
?>

页面源代码如下。

/modules/formelement/index.php
<?php
require_once dirname(__FILE__)."/../../mainfile.php";
/* 详见源文件 */
include XOOPS_ROOT_PATH."/header.php";
include_once XOOPS_ROOT_PATH."/class/xoopsformloader.php";
$form_extends = new XoopsThemeForm("Form Extends", "form_extends", "");
/* 详见源文件 */
$form_element->display();
include XOOPS_ROOT_PATH."/footer.php";
?>

生成的页面效果如图3-5自定义控件所示。

Xop108.png

XOOPS系统支持多种自定义控件的开发方式,最简单的自定义控件就是自定义数据,例如本例中使用的RadioYN控件,就是继承自基础控件中Radio控件,然后自定义选项。源代码如下:

/class/xoopsform/formradioyn.php
class XoopsFormRadioYN extends XoopsFormRadio
{
	function XoopsFormRadioYN($caption, $name, $value=null, $yes=_YES, $no=_NO)
	{
		$this->XoopsFormRadio($caption, $name, $value);
		$this->addOption(1, $yes);
		$this->addOption(0, $no);
	}
}

从代码中可以看出自定义数据控件需要替换父类的构造函数,在构造函数中先调用父对象的构造函数,然后添加自定义的选项。在使用时和使用对应的基础控件相同,可以省略添加选项的代码。由于自定义数据控件中预先定义了选项,所以在判断没有提交自定义数据控件的数据时,该控件的默认值也应当是选项之一,本例中RadioYN控件的数据范围是0和1,所以默认值选择了其中的0。

if (false === isset($_POST["radioyn"])) {
    $radioyn = "0";

如果提交了自定义数据控件的数据,则需要进一步判断提交的数据是否是自定义数据控件中预先定义的选项,如果提交的数据值不是选项之一,则也需要设定默认值。

} elseif (false === in_array($_POST["radioyn"], array("0", "1"))) {
    $radioyn = "0";

如果提交的数据值是选项之一,则控件的值为提交的数据。

} else {
    $radioyn = $_POST["radioyn"];
}

这样就获取了预定义数据控件提交的数据。

注意:本例中RadioYN控件预定义的选项值是0和1,均为整数类型,而PHP中提交的数据值均为字符串类型,所以在判断是应当按字符串类型判断,而取值时则应按需要进行相应的类型转换。由于本例中预定义的选项不涉及转义相关字符,所以不需要进行转义。如果预定义数据控件涉及转义字符,则应当先进行转义恢复原始数据。

通过以上步骤获取的数据可以作为预定义数据控件的初始值。

$form_radioyn = new XoopsFormRadioYN("Radio Yes/No", "radioyn", $radioyn);
$form_extends->addElement($form_radioyn);

最后在页面中生成的HTML代码如下。

<input type='radio' name='radioyn' value='1' />是
<input type='radio' name='radioyn' value='0' checked='checked' />否

通过对比前一小节的单选按钮控件可以了解自定义数据控件的工作方式。自定义数据控件是自定义控件的两种常见形式之一,另一种常见形式是自定义浏览器脚本控件,通过将特定的客户端脚本封装在控件中,增加控件在浏览器中的交互功能,例如本例中的Color Picker控件就是继承自Text控件,并增加颜色选择器功能,颜色选择器控件在文本框控件的基础上实现了三个函数的替换。首先是替换了文本框控件的构造函数,按照HTML中颜色所使用的#XXXXXX格式设置了文本框的长度。

/class/xoopsform/formcolorpicker.php
class XoopsFormColorPicker extends XoopsFormText
{
	function XoopsFormColorPicker($caption, $name, $value="#FFFFFF")
	{
		$this->XoopsFormText($caption, $name, 9, 7, $value);
	}
}

第二个是替换显示函数,在调用文本框控件的显示函数之前,先加载颜色选择器相关的javascript脚本,在调用文本框的显示函数之后,显示启动颜色选择器的按钮。

/class/xoopsform/formcolorpicker.php
class XoopsFormColorPicker extends XoopsFormText
{
	function render()
	{
		if(isset($GLOBALS['xoTheme'])) {
			$GLOBALS['xoTheme']->addScript('include/color-picker.js');
		} else {
			echo "<script type=\"text/javascript\" src=\"".XOOPS_URL."/include/color-picker.js\"></script>";
		}
		$this->setExtra(' style="background-color:'.$this->getValue().';"');
		return parent::render()."\n<input type='reset' value=' ... ' onclick=\"return TCP.popup('".XOOPS_URL."/include
/',document.getElementById('".$this->getName()."'));\">\n";
	}
}

第三个是替换客户端验证函数,在用户提交数据前,在客户端验证文本框中的内容是否符合颜色所使用的格式要求。

/class/xoopsform/formcolorpicker.php
class XoopsFormColorPicker extends XoopsFormText
{
	/**
	 * Returns custom validation Javascript
	 * 
	 * @return	string	Element validation Javascript
	 */
	function renderValidationJS() {
		$eltname    = $this->getName();
		$eltcaption = trim( $this->getCaption() );
		$eltmsg = empty($eltcaption) ? sprintf( _FORM_ENTER, $eltname ) : sprintf( _FORM_ENTER, $eltcaption );
		return "if ( !(new RegExp(\"^#[0-9a-fA-F]{6}\",\"i\").test(myform.{$eltname}.value)) ) { window.alert(\"{$eltmsg}\"); myform.
{$eltname}.focus(); return false; }";
	}
}

由于颜色选择器需要特定的数据格式,所以在判断没有提交颜色选择器数据时,默认颜色应当符合格式要求,本例中选择#FFFFFF作为默认颜色。

if (false === isset($_POST["colorpicker"])) {
    $colorpicker = "#FFFFFF";

如果提交了颜色选择器的数据,则需要进一步判断提交的数据是否是字符串,如果提交的数据不是字符串,则也需要设定为默认颜色。

} elseif (false === is_string($_POST["colorpicker"])) {
    $colorpicker = "#FFFFFF";

如果提交的数据是字符串,则还需要判断字符串是否符合颜色格式的要求,如果不符合颜色格式的要求,则也需要设定默认值。

} elseif (0 === preg_match("/^#[0-9a-fA-F]{6}$/i", $_POST["colorpicker"])) {
    $colorpicker = "#FFFFFF";

如果提交的字符串符合颜色格式,则控件的值为提交的数据。

} else {
    $colorpicker = $_POST["colorpicker"];
}

这样就获取了颜色选择器提交的数据,该数据可以作为颜色选择器的初始值。

$form_colorpicker = new XoopsFormColorPicker("Color Picker", "colorpicker",
    $colorpicker);
$form_extends->addElement($form_colorpicker);

最后在页面中生成的HTML代码如下。

<input type='text' name='colorpicker' id='colorpicker' size='9' maxlength='7' value='#FFFFFF' style="background-color:#FFFFFF;" />
<input type='reset' value=' ... ' onclick="return TCP.popup('http://localhost/xoopstutorial/include/',document.getElementById('colorpicker'));">

通过对比前一小节的文本框控件可以了解自定义浏览器脚本控件的工作方式。