牛骨文教育服务平台(让学习变的简单)

从1.0.6开始,支持自定义扩展表单项

版本 新增功能
1.0.7 支持调用公共资源

虽然目前ZBuilder提供了超过30种表单项,但还是不足以满足用户的需求。为此,我们对表单构建器进行了功能扩展,让开发者可以自己定义表单项。

由于刚支持该功能,可能有些地方还不够人性化或者满足需求,所以在使用中若有什么更好的建议,欢迎到论坛发帖。

下面介绍如何扩展表单项,这里以扩展“颜色选择器”来作为演示。虽然ZBuilder本身已经有“颜色选择器”,但我们这次用自定义扩展的方式实现相同的功能。

1.建立表单项目录

首先,我们在目录:extendform下新建一个目录,名字就test。这个目录名称就是我们要扩展的表单项类型名称。

注意,目录名为全小写,并且不要和已存在的表单项类型冲突。

2.放入颜色选择器需要的文件(可选)

这一步是可选的,如果你创建的表单项无需依赖任何js或css,可以跳过这一步。因为颜色选择器需要依赖一些js和css文件,所以要把相关的文件放在该目录下。

3.建立入口文件

接着,我们在test目录下创建名称为Builder.php的入口文件,这个文件名是固定的,必须为Builder.php

然后我们需要在该入口文件中,创一个item方法,这个方法是用于在调用ZBuilder时供使用者调用的方法。

<?php

namespace form	est;

class Builder
{
    /**
     * 取色器
     * @param string $name 表单项名
     * @param string $title 标题
     * @param string $tips 提示
     * @param string $default 默认值
     * @param string $mode 模式:默认为rgba(含透明度),也可以是rgb
     * @param string $extra_attr 额外属性
     * @param string $extra_class 额外css类名
     * @author 蔡伟明 <314013107@qq.com>
     * @return mixed
     */
    public function item($name = "", $title = "", $tips = "", $default = "", $mode = "rgba", $extra_attr = "", $extra_class = "") 
    {
        return [
            "name"        => $name,
            "title"       => $title,
            "tips"        => $tips,
            "value"       => $default,
            "mode"        => $mode,
            "extra_class" => $extra_class,
            "extra_attr"  => $extra_attr,
        ];
    }
}

命名空间固定为form表单项名

item方法的参数是自定义的,你的表单项需要用到什么参数,就写什么参数,根据实际情况来写。它需要返回一个数组,这个数组就是你在模板中需要用到的数据。如果需要在这里么进行一些判断或者处理,都是可以的,只要最终反回一个数组即可。

需要注意的是,返回的数据中,必须包含name,而且不得包含键为type的数组元素,系统会自动添加上对应的type,比如上面的代码,实际上输出到页面时,会自动添加上type => "test"

4.定义需要加载的js和css文件(可选)

这一步也是可以选的,如果你的表单项并不依赖任何js或css文件,可以忽略这一步。

<?php

namespace form	est;

class Builder
{
    /**
     * 取色器
     * @param string $name 表单项名
     * @param string $title 标题
     * @param string $tips 提示
     * @param string $default 默认值
     * @param string $mode 模式:默认为rgba(含透明度),也可以是rgb
     * @param string $extra_attr 额外属性
     * @param string $extra_class 额外css类名
     * @author 蔡伟明 <314013107@qq.com>
     * @return mixed
     */
    public function item($name = "", $title = "", $tips = "", $default = "", $mode = "rgba", $extra_attr = "", $extra_class = "")
    {
        return [
            "name"        => $name,
            "title"       => $title,
            "tips"        => $tips,
            "value"       => $default,
            "mode"        => $mode,
            "extra_class" => $extra_class,
            "extra_attr"  => $extra_attr,
        ];
    }

    /**
     * @var array 需要加载的js
     */
    public $js = [
        "bootstrap-colorpicker/bootstrap-colorpicker.min.js",
        "test.js" // 默认加载当前表单项目录下的test.js
    ];

    /**
     * @var array 需要加载的css
     */
    public $css = [
        "bootstrap-colorpicker/css/bootstrap-colorpicker.css"
    ];
}

在这里,我们加入了两个js文件,一个是颜色选择器的js文件,一个是用来创建颜色选择器的js文件。另外加入了一个css样式文件。

如果是1.0.7版本以上,则可以使用模板变量替换来调用公共资源

public $js = [
    "__LIBS__/bootstrap-colorpicker/bootstrap-colorpicker.min.js",
    "test.js"
];

表示引用/public/static/libs/bootstrap-colorpicker/bootstrap-colorpicker.min.js,更多资源路径请参考变量参考

test.js内容如下:

$(document).ready(function () {
    jQuery(".js-colorpicker").each(function(){
        var $colorpicker = jQuery(this);

        var $colorpickerMode    = $colorpicker.data("colorpicker-mode") ? $colorpicker.data("colorpicker-mode") : "hex";
        var $colorpickerinline  = $colorpicker.data("colorpicker-inline") ? true : false;

        $colorpicker.colorpicker({
            "format": $colorpickerMode,
            "inline": $colorpickerinline
        });
    });
});

5.创建表单项模板文件

入口文件写好后,我们需要创建一个模板文件,用来输出内容。因为我们扩展的表单项类型为test,所以模板文件名必须为test.html

代码如下:

<div class="form-group col-xs-12 {$extra_class|default=""}" id="form_group_{$name}">
    <label class="col-xs-12" for="{$name}">{$title|htmlspecialchars}</label>
    <div class="col-sm-12">
        <div class="js-colorpicker input-group" data-colorpicker-mode="{$mode == "" ? "rgba" : $mode}">
            <input class="form-control" type="text" id="{$name}" name="{$name}" value="{$value|default=""}" placeholder="请从右边选择颜色" {$extra_attr|default=""}>
            <span class="input-group-addon"><i style="background-color: rgb(92, 144, 210);"></i></span>
        </div>
        {notempty name="tips"}
        <div class="help-block">{$tips}</div>
        {/notempty}
    </div>
</div>

6.调用表单项方法

自此,所有准备工作已经完成,接下来就是使用我们自定义的表单项了,完整的表单项目录是这样的。

因为我们定义的表单项类型为test,所以在ZBuilder中可以直接使用->addTest()来创建表单项,add接上类型名称首字母大写。

return ZBuilder::make("form")
    ->addTest("color", "取色器")
    ->fetch();

也可以用->addFormItem()方法

return ZBuilder::make("form")
    ->addFormItem("test", "color", "取色器")
    ->fetch();

或者->addFormItems()方法

return ZBuilder::make("form")
    ->addFormItems([
    	["text", "username", "用户名"],
    	["test", "color", "取色器"]
    ])
    ->fetch();

当然,也支持布局,但需要在模板中添加一段代码

col-md-{$_layout|default="12"}

test.html最终是这样的

<div class="form-group col-md-{$_layout|default="12"} col-xs-12 {$extra_class|default=""}" id="form_group_{$name}">
    <label class="col-xs-12" for="{$name}">{$title|htmlspecialchars}</label>
    <div class="col-sm-12">
        <div class="js-colorpicker input-group" data-colorpicker-mode="{$mode == "" ? "rgba" : $mode}">
            <input class="form-control" type="text" id="{$name}" name="{$name}" value="{$value|default=""}" placeholder="请从右边选择颜色" {$extra_attr|default=""}>
            <span class="input-group-addon"><i style="background-color: rgb(92, 144, 210);"></i></span>
        </div>
        {notempty name="tips"}
        <div class="help-block">{$tips|clear_js}</div>
        {/notempty}
    </div>
</div>

然后我们就可以使用布局参数了

return ZBuilder::make("form")
    ->addText("username", "用户名")
    ->addTest("color", "取色器")
    ->layout(["color" => 6])
    ->fetch();

当然,也可以这样。

return ZBuilder::make("form")
    ->addText("username", "用户名")
    ->addFormItem("test:6", "color", "取色器")
    ->fetch();

或者这样

return ZBuilder::make("form")
    ->addFormItems([
    	["text", "username", "用户名"],
    	["test:6", "color", "取色器"]
    ])
    ->fetch();

也可以放在表单分组中。

return ZBuilder::make("form")
    ->addText("username", "用户名")
    ->addGroup([
    	"分组1" => [
        	["test", "color", "取色器"]
        ],
        "分组2" => [
        	["text", "nickname", "昵称"]
        ]
    ])
    ->fetch();