> Zend Framework中文手册 > 12.4. Dojo 表单元素和装饰器

12.4. Dojo 表单元素和装饰器

建立在 dijit 视图助手 之上的 Zend_Dojo_Form 类家族在你的表单里自然地使用 Dijits。

有三个选项用来在你的表单里使用 Dojo 表单元素:

  • Zend_Dojo::enableForm(). 递归地为装饰器和所有表单的元素添加插件路径。 另外,它将 dojo-enable 视图对象。然而注意,任何在这个调用 之后 附加 的子表单也需要用 Zend_Dojo::enableForm()

  • 分别使用 Dojo-specific 表单Zend_Dojo_Form和子表单 Zend_Dojo_Form_SubForm实现。 这些可以做为 Zend_FormZend_Form_SubForm的随时替换,包含所有合适的装饰器 和元素路径,设置一个 Dojo-specific 缺省的显示组类并 dojo-enable 视图。

  • 最后并且是最单调的是,你可以自己设置合适的装饰器和元素路径,设置缺省显示组类 并 dojo-enable 视图。因为 Zend_Dojo::enableForm() 已经做了这个, 有个小原因需要这样做。

例 12.11.  在你的表单里开启 Dojo

“等等” 你会说,“我已经用我自己定制的表单类扩展了 Zend_form!怎么 Dojo-enable 它?”

首先而且是最简单的是,修改从 Zend_Form 扩展为从 Zend_Dojo_Form 扩展, 并更新任何实例化 Zend_Form_SubForm 的地方为实例化 Zend_Dojo_Form_SubForm

第二个方法是在定制表单的 init() 方法里调用 Zend_Dojo::enableForm(); 当表单定义完成,遍历所有子表单来 dojo-enable 它们:

class My_Form_Custom extends Zend_Form
{
    public function init()
    {
        // Dojo-enable the form:
        Zend_Dojo::enableForm($this);

        // ... continue form definition from here

        // Dojo-enable all sub forms:
        foreach ($this->getSubForms() as $subForm) {
            Zend_Dojo::enableForm($subForm);
        }
    }
}

        

dijit-specific 表单装饰器和元素的用法和使用任何其它表单装饰漆或元素一样。

12.4.1. Dijit-Specific 表单装饰器

大多数表单元素可以使用 DijitElement 装饰器,它从元素抓取 dijit 参数, 然后和其它元数据一起传递给由元素指定的视图助手。对于装饰表单、子表单和显示组, 有一组和不同的布局 dijits 对应的装饰器。

所有的 jijit 装饰器寻找给定被装饰元素的 dijitParams 属性, 并把它们压到 $params 数组传递给被使用的 dijit 视图助手; 这些就和其它属性分离,这样就不会有重复的信息。

12.4.1.1. DijitElement 装饰器

就像 视图助手装饰器, DijitElement 也在元素里有个 helper 属性,解析时,它将被用作视图助手。 Dijit 参数将直接从元素理拉出来,但也可能通过 dijitParams 键(键值应当是个联合数组选项) 作为选项被传递。

每个元素有个独一无二的 ID (从元素的getId()方法读出)很重要。 如果在 dojo() 视图助手里检测到重复的 ID,装饰器将触发一个提示, 接着通过追加 uniqid() 的返回值到标识符来生成一个独一无二的 ID。

标准用法是在装饰器链附加这个装饰器为第一个装饰器,不需要另外的选项。

例 12.12. DijitElement 装饰器用法

$element->setDecorators(array(
    'DijitElement',
    'Errors',
    'Label',
    'ContentPane',
));

            

12.4.1.2. DijitForm 装饰器

DijitForm 装饰器和 表单装饰器 非常类似;事实上,它们可以交互使用,因为它们使用同样的视图助手名('form')。

因为 dijit.form.Form 不要求任何 dijit 参数来配置,主要的不同之处是 dijit 表单视图助手 要求传递一个 DOM ID 来确保程序生成 dijit。装饰器通过传递表单名为表示符来保证它。

12.4.1.3. DijitContainer-based 装饰器

DijitContainer 装饰器实际上是一个摘要类,其它装饰器都从它派生。它 提供了和 DijitElement 一样的功能, 并带有另外的标题支持。许多布局 dijits 要求或使用标题;如果可能,DijitContainer 将使用元素的 legend 属性,如果传递 它也可以使用 'legend' 或 'title'装饰器选项其中之一。如果有对应的翻译适配器,标题将被翻译。

下列的装饰器从 DijitContainer 继承:

  • AccordionContainer

  • AccordionPane

  • BorderContainer

  • ContentPane

  • SplitContainer

  • StackContainer

  • TabContainer

例 12.13. DijitContainer 装饰器用法

// Use a TabContainer for your form:
$form->setDecorators(array(
    'FormElements',
    array('TabContainer', array(
        'id'          => 'tabContainer', 
        'style'       => 'width: 600px; height: 500px;',
        'dijitParams' => array(
            'tabPosition' => 'top'
        ), 
    )),
    'DijitForm',
));

// Use a ContentPane in your sub form (which can be used with all but 
// AccordionContainer):
$subForm->setDecorators(array(
    'FormElements',
    array('HTMLTag', array('tag' => 'dl')),
    'ContentPane',
));

            

12.4.2. Dijit-Specific 表单元素

每个被提供视图助手的 dijit 表单都有相应的Zend_Form元素。它们都有下列方法来处理 dijit 参数:

  • setDijitParam($key, $value): 设置一单个的 dijit 参数。 如果 dijit 参数已经存在,则覆盖它。

  • setDijitParams(array $params): 一次设置若干 dijit 参数。 同样,已经存在的参数被覆盖。

  • hasDijitParam($key): 是否有个给定的 dijit 参数被定义和存在。

  • getDijitParam($key): 获取给定 $key 的 dijit 参数,如果不可用,则返回 null。

  • getDijitParams(): 获取所有的 dijit 参数。

  • removeDijitParam($key): 删除给定 $key 的 dijit 参数。

  • clearDijitParams(): 清除所有当前定义的 dijit 参数。

Dijit 参数存储在 dijitParams 公共属性里。这样,你可以 通过设置这个元素的属性来 dijit-enable 一个存在的表单元素。 你将不会有 上述访问器来简化处理这些参数。

另外,dijit-specific 元素实现一个不同的装饰器列表,相应如下:

$element->addDecorator('DijitElement')
        ->addDecorator('Errors')
        ->addDecorator('HtmlTag', array('tag' => 'dd'))
        ->addDecorator('Label', array('tag' => 'dt'));

实际上,DijitElement 装饰器用来替换标准的 ViewHelper 装饰器。

最后,基本的 Dijit 元素确保在视图中设置 Dojo 视图助手路径。

一个提供 多重 摘要表单元素的功能的 DijitElement 的变量 DijitMulti 让开发者指定 'multiOptions' - 一般是 select 选项或 radio 选项。

下列 dijit 元素随标准的 Zend Framework 版本发行。

12.4.2.1. 按钮

虽然不是从 标准 Button 元素中派生, 它确实实现了相同的功能,并可以随时替换它。展示一下下列函数:

  • getLabel() 如果没有提供名字,将使用元素名作为按钮标签。另外, 如果翻译适配器有匹配的翻译信息,它将翻译这个名字。

  • isChecked() 确定是否提交的值和标签(label)匹配,如果匹配,返回true。 这对于当提交表单时确定用了那个按钮很有用。

另外,只有 DijitElementDtDdWrapper 装饰器用于按钮元素。

例 12.14.  按钮 dijit 元素用法范例

$form->addElement(
    'Button',
    'foo',
    array(
        'label' => 'Button Label',
    )
);

12.4.2.2. 检查框

虽然不是从 标准检查框元素 里派生, 但它确实实现了相同的功能。展示一下下列函数:

  • setCheckedValue($value): 设置一个值,当元素被选就用这个值。

  • getCheckedValue(): 获取当元素被时选使用的值。

  • setUncheckedValue($value): 设置一个值,当元素不被选中就用这个值。

  • getUncheckedValue(): 获取当元素不被选中时使用的值。

  • setChecked($flag): 标记元素为选中或未选中。

  • isChecked(): 确定元素是否被选中。

例 12.15.  检查框 dijit 元素用法范例

$form->addElement(
    'CheckBox',
    'foo',
    array(
        'label'          => 'A check box',
        'checkedValue'   => 'foo',
        'uncheckedValue' => 'bar',
        'checked'        => true,
    )
);

12.4.2.3.  组合框(ComboBox)和 FilteringSelect

正如在组合框 dijit 视图助手文档 里的注释, 组合框是介于选择和文本输入之间的混合体,可以从列表中选择也可以输入内容到列表里。 FilteringSelect 也一样,但不允许任意输入。

12.4. Dojo 表单元素和装饰器 组合框(ComboBoxes) 返回标签值

组合框返回标签值而不是选项值,它可期望导致分离(disconnect)。 由于这个原因,组合框不自动注册一个 InArray 校验器(而 FilteringSelects 会)。

组合框和 FilteringSelect 表单元素提供访问器和增变器来检查和设置选择选项和指定 dojo.data 数据存储(如果使用的话)。 它们从 DijitMulti 继承,允许你通过 setMultiOptions()setMultiOption() 方法指定选择选项。 另外,下列方法可用:

  • getStoreInfo(): 获取当前设置的所有数据存储信息,如果没有,返回一个空的数组。

  • setStoreId($identifier): 设置存储标识符变量(在 Dojo 里通常由属性 'jsId' 指定)。 这个应当是有效的 javascript 变量名。

  • getStoreId(): 获取存储标识符变量名。

  • setStoreType($dojoType): 设置数据存储类,例如"dojo.data.ItemFileReadStore"。

  • getStoreType(): 获取 dojo 数据存储类。

  • setStoreParams(array $params): 设置任何用于配置数据存储对象的参数。 例如,dojo.data.ItemFileReadStore 期望一个'url'参数指向一个能返回 dojo.data 对象的位置。

  • getStoreParams(): 获取任何当前设置的数据存储参数,如果没有,返回一个空数组。

  • setAutocomplete($flag): 标识当用户离开元素时,是否选择的条目将被使用。

  • getAutocomplete(): 获取自动完成标志的值。

缺省地,如果没有 dojo.data 存储和元素一起注册,该元素就注册 一个 InArray 校验器,它依靠注册的选项的数组键来校验。 你可以通过调用 setRegisterInArrayValidator(false) 或 传递一个 false 值给 registerInArrayValidator 配置键 来禁止该行为。

例 12.16.  使用组合框 dijit 元素做选择输入的范例

$form->addElement(
    'ComboBox', 
    'foo', 
    array(
        'label'        => 'ComboBox (select)',
        'value'        => 'blue',
        'autocomplete' => false,
        'multiOptions' => array(
            'red'    => 'Rouge',
            'blue'   => 'Bleu',
            'white'  => 'Blanc',
            'orange' => 'Orange',
            'black'  => 'Noir',
            'green'  => 'Vert',
        ),
    )
);

例 12.17.  带数据存储的组合框 dijit 元素用法范例

$form->addElement(
    'ComboBox', 
    'foo', 
    array(
        'label'       => 'ComboBox (datastore)',
        'storeId'     => 'stateStore',
        'storeType'   => 'dojo.data.ItemFileReadStore',
        'storeParams' => array(
            'url' => '/js/states.txt',
        ),
        'dijitParams' => array(
            'searchAttr' => 'name',
        ),
    )
);

上述例子也可以使用 FilteringSelect 来代替 ComboBox

12.4.2.4.  货币文字框

货币文字框主要用来支持货币输入。货币可以是本地化的,并且支持带小数的和不带小数的数值。

在内部,货币文字框由 NumberTextBox、 ValidationTextBox 和 TextBox 派生, 所有对这些类可用的方法也对它可用。另外,也可用下列约束方法:

  • setCurrency($currency): 设置要使用的货币类型; 遵循 ISO-4217 规范。

  • getCurrency(): 获取当前货币类型。

  • setSymbol($symbol): 设置 3-letter ISO-4217 货币符号。

  • getSymbol(): 获取当前货币符号。

  • setFractional($flag): 设置是否支持小数值。

  • getFractional(): 获取小数标记的状态。

例 12.18.  货币文字框 dijit 元素用法范例

$form->addElement(
    'CurrencyTextBox', 
    'foo', 
    array(
        'label'          => 'Currency:',
        'required'       => true,
        'currency'       => 'USD',
        'invalidMessage' => 'Invalid amount. Include dollar sign, commas, and cents.',
        'fractional'     => false,
    )
);

12.4.2.5.  日期文字框

日期文字框提供一个下拉式日历用来选择日期,也有一个客户端的日期校验和格式化。

在内部,日期文字框从 ValidationTextBox 和 TextBox 派生, 所有对这些类可用的方法也对它可用。另外,下列方法也可以独立使用:

  • setAmPm($flag)getAmPm(): 是否在时间上使用 AM/PM。

  • setStrict($flag)getStrict(): 是否用严格的正则表达式校验输入。如果是缺省的 false,则对空白字符和一些缩写不严格检查。

  • setLocale($locale)getLocale(): 设置和获取用于特定元素的地方。

  • setDatePattern($pattern)getDatePattern(): 提供和读取 unicode 日期格式模型 来格式化日期。

  • setFormatLength($formatLength)getFormatLength(): 提供和读取格式长度类型,是 "long"、 "short"、 "medium" 或 "full" 其中之一。

  • setSelector($selector)getSelector(): 提供和读取选择器的风格, "date" 或 "time"。

例 12.19.  日期文字框 dijit 元素用法范例

$form->addElement(
    'DateTextBox', 
    'foo', 
    array(
        'label'          => 'Date:',
        'required'       => true,
        'invalidMessage' => 'Invalid date specified.',
        'formatLength'   => 'long',
    )
);

12.4.2.6.  水平滑尺(HorizontalSlider)

水平滑尺提供了一个滑尺 UI 小部件用来在一个范围内选择数值。 在内部,它设置一个隐藏元素的值然后由表单提交。

水平滑尺从 abstract Slider dijit element 派生。另外,有许多方法用来设置和配置滑尺刻度和刻度标签。

  • setTopDecorationDijit($dijit)setBottomDecorationDijit($dijit): 设置 dijit 的名字用于滑尺的顶或底。这个不包括"dijit.form."前缀, 已经是最终的名字 - "HorizontalRule" 或 "HorizontalRuleLabels"。

  • setTopDecorationContainer($container)setBottomDecorationContainer($container): 指定用于刻度的容器元素的名字,如:'topRule'、 'topContainer'等。

  • setTopDecorationLabels(array $labels)setBottomDecorationLabels(array $labels): 设置标签用于 RuleLabels dijit 类型之一,这些是索引数组; 指定一个空间来跳过给定的标签位置(如开头或结尾)。

  • setTopDecorationParams(array $params)setBottomDecorationParams(array $params): 配置给定的刻度或刻度标签 dijit 的 dijit 参数。

  • setTopDecorationAttribs(array $attribs)setBottomDecorationAttribs(array $attribs): 指定给定的刻度或刻度标签 HTML 元素容器的 HTML 属性。

  • getTopDecoration()getBottomDecoration(): 获取所有由上述增变器给定规则或 RuleLabels 定义的元数据。

例 12.20.  水平滑尺 dijit 元素用法范例

下面创建一个整数范围为 -10到10的水平滑尺。顶上有 20%、 40%、 60% 和 80%标记。 底下有 0 、50% 和 100%。每次改变,隐藏元素的值就更新一次。

$form->addElement(
    'HorizontalSlider', 
    'horizontal', 
    array(
        'label'                     => 'HorizontalSlider',
        'value'                     => 5,
        'minimum'                   => -10,
        'maximum'                   => 10,
        'discreteValues'            => 11,
        'intermediateChanges'       => true,
        'showButtons'               => true,
        'topDecorationDijit'        => 'HorizontalRuleLabels',
        'topDecorationContainer'    => 'topContainer',
        'topDecorationLabels'       => array(
                ' ',
                '20%',
                '40%',
                '60%',
                '80%',
                ' ',
        ),
        'topDecorationParams'      => array(
            'container' => array(
                'style' => 'height:1.2em; font-size=75%;color:gray;',
            ),
            'list' => array(
                'style' => 'height:1em; font-size=75%;color:gray;',
            ),
        ),
        'bottomDecorationDijit'     => 'HorizontalRule',
        'bottomDecorationContainer' => 'bottomContainer',
        'bottomDecorationLabels'    => array(
                '0%',
                '50%',
                '100%',
        ),
        'bottomDecorationParams'   => array(
            'list' => array(
                'style' => 'height:1em; font-size=75%;color:gray;',
            ),
        ),
    )
);

12.4.2.7.  数字微调控制器(NumberSpinner)

数字微调控制器是一个文本元素用来输入数字值;它也包括用于增加和减少一定值的元素。

可用方法如下:

  • setDefaultTimeout($timeout)getDefaultTimeout(): 设置和获取缺省超时值,以毫秒为单位, 当按住按钮时,数值就发生变化。

  • setTimeoutChangeRate($rate)getTimeoutChangeRate(): 设置和获取比率,以毫秒为单位, 就是当按住按钮时,数值的变化率。

  • setLargeDelta($delta)getLargeDelta(): 设置和读取当按钮被按住数字应当改变的值的大小。

  • setSmallDelta($delta)getSmallDelta(): 设置和读取当按钮被按住一次数字的变化量。

  • setIntermediateChanges($flag)getIntermediateChanges(): 设置和读取当按钮被按住时是否显示数值的标志。

  • setRangeMessage($message)getRangeMessage(): 设置和读取指示可用数值范围的信息。

  • setMin($value)getMin(): 设置和获取最小可能值。

  • setMax($value)getMax(): 设置和获取最大可能值。

例 12.21.  数字微调控制器 dijit 元素用法范例

$form->addElement(
    'NumberSpinner', 
    'foo', 
    array(
        'value'             => '7',
        'label'             => 'NumberSpinner',
        'smallDelta'        => 5,
        'largeDelta'        => 25,
        'defaultTimeout'    => 500,
        'timeoutChangeRate' => 100,
        'min'               => 9,
        'max'               => 1550,
        'places'            => 0,
        'maxlength'         => 20,
    )
);

12.4.2.8.  数字框

数字框是一个文本元素用来输入数字值,不象数字增变器,数字框用手工输入。 校验和限制可以使数值在一定的范围并符合一定的格式。

在内部,数字框从 ValidationTextBox 和 TextBox派生; 所有对这些类可用的方法都可用,另外,下列方法可以独立使用:

  • setLocale($locale)getLocale(): 指定和获取一个特定或预备的地方来使用 dijit。

  • setPattern($pattern)getPattern(): 设置和获取一个 数字模型格式 来格式化数字。

  • setType($type)getType(): 设置和获取数字格式类型(应当为 'decimal'、'percent' 或 'currency'其中之一 )。

  • setPlaces($places)getPlaces():设置和获取有多少小数位。

  • setStrict($flag)getStrict(): 设置和读取严格标志的值,它用来指示对空白字符和非数字字符控制的严格程度。

例 12.22.  数字框 dijit 元素用法范例

$form->addElement(
    'NumberTextBox', 
    'elevation', 
    array(
        'label'          => 'NumberTextBox',
        'required'       => true,
        'invalidMessage' => 'Invalid elevation.',
        'places'         => 0,
        'constraints'    => array(
            'min'    => -20000,
            'max'    => 20000,
        ),
    )
);

12.4.2.9. 密码框

密码框是个 ValidationTextBox,它和密码输入有联系;它唯一的意图是允许 dijit-themed 文本输入密码并提供客户端校验。

在内部,密码框从 ValidationTextBox 和 TextBox 派生; 所有对这些类可用的方法都可用。

例 12.23. 密码框 dijit 元素用法范例

$form->addElement(
    'PasswordTextBox', 
    'password', 
    array(
        'label'          => 'Password',
        'required'       => true,
        'trim'           => true,
        'lowercase'      => true,
        'regExp'         => '^[a-z0-9]{6,}$',
        'invalidMessage' => 'Invalid password; must be at least 6 alphanumeric characters',
    )
);

12.4.2.10. 单选按钮

单选按钮封装了标准单选输入元素来提供一个和其它 dojo dijits 一致的外观。 (因为英文为 radio button,单选按钮在过去也被翻译为无线电按钮,但从功能上讲,单选按钮更准确 Jason Qi注)

单选按钮从 DijitMulti 继承,它让你通过 setMultiOptions()setMultiOption() 方法来指定选择选项。

缺省地,该元素注册一个 InArray 校验器,它依靠注册的选项的数组键来校验。 你可以通过调用 setRegisterInArrayValidator(false) 或传递一个 false 值给 registerInArrayValidator配置键来禁止该行为。

例 12.24.  单选按钮 dijit 元素用法范例

$form->addElement(
    'RadioButton', 
    'foo', 
    array(
        'label' => 'RadioButton',
        'multiOptions'  => array(
            'foo' => 'Foo',
            'bar' => 'Bar',
            'baz' => 'Baz',
        ),
        'value' => 'bar',
    )
);

12.4.2.11. 滑尺摘要元素

水平滑尺 和 垂直滑尺 都是从滑尺摘要元素派生而来的。它包含了许多通用的方法来配置你的滑尺,包括:

  • setClickSelect($flag)getClickSelect(): 设置和获取确定是否点击滑尺来可以修改数值的标志。

  • setIntermediateChanges($flag)getIntermediateChanges(): 设置和获取是否对每个滑尺修改时间发送通知的标志。

  • setShowButtons($flag)getShowButtons(): 设置和获取是否在两端显示按钮的标志。如果有的话,客户可以通过点击按钮来修改滑尺的值。

  • setDiscreteValues($value)getDiscreteValues(): 设置和获取滑尺的不连续的数值。

  • setMaximum($value)getMaximum():设置滑尺的最大值。

  • setMinimum($value) and getMinimum():设置滑尺的最小值。

  • setPageIncrement($value)getPageIncrement(): 设置滑尺在键盘事件上修改的数量。

范例在每个具体的继承类里提供。

12.4.2.12. 提交按钮

虽然没有叫提交按钮的 Dijit,但我们还是在此提供一个按钮 dijit 用来提交 表单而不需请求任何另外的 javascript 绑定。它的工作方式和 按钮 dijit 一模一样。

例 12.25. Example SubmitButton dijit element usage

$form->addElement(
    'SubmitButton', 
    'foo', 
    array(
        'required'   => false,
        'ignore'     => true,
        'label'      => 'Submit Button!',
    )
);

12.4.2.13. 文字框

文字框用来输入文字,在外观上和其它 dijit 保持一致。然而,它有一些过滤和校验的功能,详见下列方法:

  • setLowercase($flag)getLowercase(): 设置和获取是否把输入转为小写的标志。

  • setPropercase($flag)getPropercase(): 设置和获取是否把输入转换为适当的大小写的标志。 Case.

  • setUppercase($flag)getUppercase(): 设置和获取是否把输入转为大写的标志。

  • setTrim($flag)getTrim(): 设置和获取是否把引导和拖尾的空白字符去掉的标志。

  • setMaxLength($length)getMaxLength(): 设置和获取输入的最大长度。

例 12.26.  文字框 dijit 元素用法范例

$form->addElement(
    'TextBox', 
    'foo', 
    array(
        'value'      => 'some text',
        'label'      => 'TextBox',
        'trim'       => true,
        'propercase' => true,
    )
);

12.4.2.14. Textarea

Textarea 就像标准的 HTML textarea一样。然而,它不支持行列的设置。 作为替代,textarea 宽度可以用标准的 CSS 来设置,行就完全忽略了。当输入字符增加时,textarea 就垂直增长。

例 12.27.  Textarea dijit 元素用法范例

$form->addElement(
    'Textarea', 
    'textarea', 
    array(
        'label'    => 'Textarea',
        'required' => true,
        'style'    => 'width: 200px;',
    )
);

12.4.2.15.  时间文字框

时间文字框是提供下拉式选择时间的文字输入框。下拉框可配置为显示一特定的时间窗口,带有特定的增量。

在内部,时间文字框从 日期文字框、 校验文字框 和 文字框 派生。 所有对这些类可用的方法都可用。另外,下列方法可以独立使用:

  • setTimePattern($pattern)getTimePattern(): 设置和获取 unicode 时间格式模型 来格式化时间。

  • setClickableIncrement($format)getClickableIncrement(): 设置 ISO-8601 字符串,来表示 每个在时间 picker increses 的可点击的元素的数量。

  • setVisibleIncrement($format)getVisibleIncrement(): 在时间选择器中设置增量的可见性,必须遵循 ISO-8601格式。

  • setVisibleRange($format)getVisibleRange(): 在时间选择器中在给定的时刻,设置和获取可见时间的范围,必须遵循 ISO-8601格式。

例 12.28.  时间文字框 dijit 元素用法范例

下面讲生成一个时间文字框,每次显示 2 小时,增量是 10 分钟。

$form->addElement(
    'TimeTextBox', 
    'foo', 
    array(
        'label'              => 'TimeTextBox',
        'required'           => true,
        'visibleRange'       => 'T04:00:00',
        'visibleIncrement'   => 'T00:10:00',
        'clickableIncrement' => 'T00:10:00',
    )
);

12.4.2.16. 校验文字框

校验文字框添加校验和限制给文字输入。 在内部,它从 文字框 派生, 并增加了下列访问器和增变器来处理 dijit 参数:

  • setInvalidMessage($message)getInvalidMessage(): 设置和获取工具提示消息来显示什么时候值没有通过校验。

  • setPromptMessage($message)getPromptMessage(): 设置和获取工具提示消息来显示元素用法。

  • setRegExp($regexp)getRegExp(): 设置和获取用于校验元素的正则表达式。正则表达式不需要边界(不象 PHP 的 preg* 函数家族)。

  • setConstraint($key, $value)getConstraint($key): 设置和获取另外的限制,用于校验元素;使用子类。限制存储在 dijit 参数数组中,键值为 'constraints'。

  • setConstraints(array $constraints)getConstraints(): 设置和获取独立的限制,用于校验元素,是哟功能子类。

  • hasConstraint($key): 测试是否有给定的限制存在。

  • removeConstraint($key)clearConstraints(): 删除元素中一个或所有的限制。

例 12.29.  校验文字框 dijit 元素用法范例

下面生成一个校验文字框,要求只包含字符的单个字符串(例如,没有空格,大部分标点符号无效)。

$form->addElement(
    'ValidationTextBox', 
    'foo', 
    array(
        'label'          => 'ValidationTextBox',
        'required'       => true,
        'regExp'         => '[\w]+',
        'invalidMessage' => 'Invalid non-space text.',
    )
);

12.4.2.17. 垂直滑尺(VerticalSlider)

垂直滑尺是水平滑尺的兄弟, 操作基本相同。唯一的区别是,对垂直滑尺来说使用了 'left*' 和 'right*' 替换了 在水平滑尺中的 'top*' 和 'bottom*',并且使用 VerticalRule 和 VerticalRuleLabels 分别替代了 HorizontalRule 和 HorizontalRuleLabels。

例 12.30.  垂直 dijit 元素使用范例

下面创建一个整数范围为 -10到10的垂直滑尺。左边有 20%、 40%、 60% 和 80%标记。 右边有 0 、50% 和 100%。每次改变,隐藏元素的值就更新一次。

$form->addElement(
    'VerticalSlider', 
    'foo', 
    array(
        'label'                    => 'VerticalSlider',
        'value'                    => 5,
        'style'                    => 'height: 200px; width: 3em;',
        'minimum'                  => -10,
        'maximum'                  => 10,
        'discreteValues'           => 11,
        'intermediateChanges'      => true,
        'showButtons'              => true,
        'leftDecorationDijit'      => 'VerticalRuleLabels',
        'leftDecorationContainer'  => 'leftContainer',
        'leftDecorationLabels'     => array(
                ' ',
                '20%',
                '40%',
                '60%',
                '80%',
                ' ',
        ),
        'rightDecorationDijit' => 'VerticalRule',
        'rightDecorationContainer' => 'rightContainer',
        'rightDecorationLabels' => array(
                '0%',
                '50%',
                '100%',
        ),
    )
);

12.4.3. Dojo 表单范例

例 12.31. 使用 Zend_Dojo_Form

Zend_Form 一起使用 Dojo的最容易的办法是利用 Zend_Dojo_Form, 直接使用或继承都可以。这个范例继承 Zend_Dojo_Form,并示范了所有 dijit 元素的用法。 它生成了四个子表单,并装饰了表单来使用 TabContainer,把每个子表单显示在它自己的 tab 上。

class My_Form_Test extends Zend_Dojo_Form
{
    /**
     * Options to use with select elements
     */
    protected $_selectOptions = array(
        'red'    => 'Rouge',
        'blue'   => 'Bleu',
        'white'  => 'Blanc',
        'orange' => 'Orange',
        'black'  => 'Noir',
        'green'  => 'Vert',
    );

    /**
     * Form initialization
     * 
     * @return void
     */
    public function init()
    {
        $this->setMethod('post');
        $this->setAttribs(array(
            'name'  => 'masterForm',
        ));
        $this->setDecorators(array(
            'FormElements',
            array('TabContainer', array(
                'id' => 'tabContainer', 
                'style' => 'width: 600px; height: 500px;',
                'dijitParams' => array(
                    'tabPosition' => 'top'
                ), 
            )),
            'DijitForm',
        ));
        $textForm = new Zend_Dojo_Form_SubForm();
        $textForm->setAttribs(array(
            'name'   => 'textboxtab',
            'legend' => 'Text Elements',
            'dijitParams' => array(
                'title' => 'Text Elements',
            ),
        ));
        $textForm->addElement(
                'TextBox', 
                'textbox', 
                array(
                    'value'      => 'some text',
                    'label'      => 'TextBox',
                    'trim'       => true,
                    'propercase' => true,
                )
            )
            ->addElement(
                'DateTextBox', 
                'datebox', 
                array(
                    'value' => '2008-07-05',
                    'label' => 'DateTextBox',
                    'required'  => true,
                )
            )
            ->addElement(
                'TimeTextBox', 
                'timebox', 
                array(
                    'label' => 'TimeTextBox',
                    'required'  => true,
                )
            )
            ->addElement(
                'CurrencyTextBox', 
                'currencybox', 
                array(
                    'label' => 'CurrencyTextBox',
                    'required'  => true,
                    // 'currency' => 'USD',
                    'invalidMessage' => 'Invalid amount. Include dollar sign, commas, and cents.',
                    // 'fractional' => true,
                    // 'symbol' => 'USD',
                    // 'type' => 'currency',
                )
            )
            ->addElement(
                'NumberTextBox', 
                'numberbox', 
                array(
                    'label' => 'NumberTextBox',
                    'required'  => true,
                    'invalidMessage' => 'Invalid elevation.',
                    'constraints' => array(
                        'min' => -20000,
                        'max' => 20000,
                        'places' => 0,
                    )
                )
            )
            ->addElement(
                'ValidationTextBox', 
                'validationbox', 
                array(
                    'label' => 'ValidationTextBox',
                    'required'  => true,
                    'regExp' => '[\w]+',
                    'invalidMessage' => 'Invalid non-space text.',
                )
            )
            ->addElement(
                'Textarea', 
                'textarea', 
                array(
                    'label'    => 'Textarea',
                    'required' => true,
                    'style'    => 'width: 200px;',
                )
            );
        $toggleForm = new Zend_Dojo_Form_SubForm();
        $toggleForm->setAttribs(array(
            'name'   => 'toggletab',
            'legend' => 'Toggle Elements',
        ));
        $toggleForm->addElement(
                'NumberSpinner', 
                'ns', 
                array(
                    'value'             => '7',
                    'label'             => 'NumberSpinner',
                    'smallDelta'        => 5,
                    'largeDelta'        => 25,
                    'defaultTimeout'    => 1000,
                    'timeoutChangeRate' => 100,
                    'min'               => 9,
                    'max'               => 1550,
                    'places'            => 0,
                    'maxlength'         => 20,
                )
            )
            ->addElement(
                'Button', 
                'dijitButton', 
                array(
                    'label' => 'Button',
                )
            )
            ->addElement(
                'CheckBox', 
                'checkbox', 
                array(
                    'label' => 'CheckBox',
                    'checkedValue'  => 'foo',
                    'uncheckedValue'  => 'bar',
                    'checked' => true,
                )
            )
            ->addElement(
                'RadioButton', 
                'radiobutton', 
                array(
                    'label' => 'RadioButton',
                    'multiOptions'  => array(
                        'foo' => 'Foo',
                        'bar' => 'Bar',
                        'baz' => 'Baz',
                    ),
                    'value' => 'bar',
                )
            );
        $selectForm = new Zend_Dojo_Form_SubForm();
        $selectForm->setAttribs(array(
            'name'   => 'selecttab',
            'legend' => 'Select Elements',
        ));
        $selectForm->addElement(
                'ComboBox', 
                'comboboxselect', 
                array(
                    'label' => 'ComboBox (select)',
                    'value' => 'blue',
                    'autocomplete' => false,
                    'multiOptions' => $this->_selectOptions,
                )
            )
            ->addElement(
                'ComboBox', 
                'comboboxremote', 
                array(
                    'label' => 'ComboBox (remoter)',
                    'storeId' => 'stateStore',
                    'storeType' => 'dojo.data.ItemFileReadStore',
                    'storeParams' => array(
                        'url' => '/js/states.txt',
                    ),
                    'dijitParams' => array(
                        'searchAttr' => 'name',
                    ),
                )
            )
            ->addElement(
                'FilteringSelect', 
                'filterselect', 
                array(
                    'label' => 'FilteringSelect (select)',
                    'value' => 'blue',
                    'autocomplete' => false,
                    'multiOptions' => $this->_selectOptions,
                )
            )
            ->addElement(
                'FilteringSelect', 
                'filterselectremote', 
                array(
                    'label' => 'FilteringSelect (remoter)',
                    'storeId' => 'stateStore',
                    'storeType' => 'dojo.data.ItemFileReadStore',
                    'storeParams' => array(
                        'url' => '/js/states.txt',
                    ),
                    'dijitParams' => array(
                        'searchAttr' => 'name',
                    ),
                )
            );
        $sliderForm = new Zend_Dojo_Form_SubForm();
        $sliderForm->setAttribs(array(
            'name'   => 'slidertab',
            'legend' => 'Slider Elements',
        ));
        $sliderForm->addElement(
                'HorizontalSlider', 
                'horizontal', 
                array(
                    'label' => 'HorizontalSlider',
                    'value' => 5,
                    'minimum' => -10,
                    'maximum' => 10,
                    'discreteValues' => 11,
                    'intermediateChanges' => true,
                    'showButtons' => true,
                    'topDecorationDijit' => 'HorizontalRuleLabels',
                    'topDecorationContainer' => 'topContainer',
                    'topDecorationLabels' => array(
                            ' ',
                            '20%',
                            '40%',
                            '60%',
                            '80%',
                            ' ',
                    ),
                    'topDecorationParams' => array(
                        'container' => array(
                            'style' => 'height:1.2em; font-size=75%;color:gray;',
                        ),
                        'list' => array(
                            'style' => 'height:1em; font-size=75%;color:gray;',
                        ),
                    ),
                    'bottomDecorationDijit' => 'HorizontalRule',
                    'bottomDecorationContainer' => 'bottomContainer',
                    'bottomDecorationLabels' => array(
                            '0%',
                            '50%',
                            '100%',
                    ),
                    'bottomDecorationParams' => array(
                        'list' => array(
                            'style' => 'height:1em; font-size=75%;color:gray;',
                        ),
                    ),
                )
            )
            ->addElement(
                'VerticalSlider', 
                'vertical', 
                array(
                    'label' => 'VerticalSlider',
                    'value' => 5,
                    'style' => 'height: 200px; width: 3em;',
                    'minimum' => -10,
                    'maximum' => 10,
                    'discreteValues' => 11,
                    'intermediateChanges' => true,
                    'showButtons' => true,
                    'leftDecorationDijit' => 'VerticalRuleLabels',
                    'leftDecorationContainer' => 'leftContainer',
                    'leftDecorationLabels' => array(
                            ' ',
                            '20%',
                            '40%',
                            '60%',
                            '80%',
                            ' ',
                    ),
                    'rightDecorationDijit' => 'VerticalRule',
                    'rightDecorationContainer' => 'rightContainer',
                    'rightDecorationLabels' => array(
                            '0%',
                            '50%',
                            '100%',
                    ),
                )
            );

        $this->addSubForm($textForm, 'textboxtab')
             ->addSubForm($toggleForm, 'toggletab')
             ->addSubForm($selectForm, 'selecttab')
             ->addSubForm($sliderForm, 'slidertab');
    }
}

例 12.32.  修改已存在的表单来使用 Dojo

通过使用 Zend_Dojo::enableForm() 静态方法,已存在的表单也可以使用 Dojo。

第一个范例示范装饰已存在的表单实例:

$form = new My_Custom_Form();
Zend_Dojo::enableForm($form);
$form->addElement(
'ComboBox',
'query',
array(
    'label'        => 'Color:',
    'value'        => 'blue',
    'autocomplete' => false,
    'multiOptions' => array(
        'red'    => 'Rouge',
        'blue'   => 'Bleu',
        'white'  => 'Blanc',
        'orange' => 'Orange',
        'black'  => 'Noir',
        'green'  => 'Vert',
    ),
)
);

另外,你可以在表单初始化上做点小文章:

class My_Custom_Form extends Zend_Form
{
    public function init()
    {
        Zend_Dojo::enableForm($this);

        // ...
    }
}

当然,如果你可以那样做 ... 你可以并应该简单地修改类来继承 Zend_Dojo_Form, 它可以随时替换已经 Dojo-enabled 的 Zend_Form ...