【问题标题】:Octobercms Builder - How to write validation code for backend form and modify fieldsOctobercms Builder - 如何为后端表单编写验证代码和修改字段
【发布时间】:2019-11-08 21:56:48
【问题描述】:

在使用 Joomla 10 年后,我对这个美妙的 10 月很陌生,并希望继续努力。 我正在使用出色的 Builder 插件,并希望在后端使用“创建”或“更新”表单进行“复杂”验证。

在网上浏览了很多次后,我不知道如何以及在哪里放置代码以添加业务验证规则?

我使用 yaml 选项来获得动态字段和简单的验证。 现在我想要复杂的规则,例如:如果类别是 X,类型是 Y,则(文本)名称字段设置为 'ZZZ' 有人可以让我在 PHP 中添加这样的代码吗?

我能够读取字段值,但无法以编程方式更改输入。 经过多次尝试,我被困在这个问题上。 任何帮助将不胜感激。谢谢。

[编辑] 在 Raja 的帮助下,我修改了我的代码,如下所示: PHP模型

class Event extends Model {
    use \October\Rain\Database\Traits\Validation;
    use \October\Rain\Database\Traits\SoftDelete;

    public $rules = [];

    // in models/your_object_model
    public function filterFields($fields, $context = null) {
        echo "\r\n".'filterFields() : '.$this->nom."\r\n";
        // var_dump($fields->nom);
        if ( $this->nom == 'toto' ) {
            echo $this->nom.' is french'."\r\n";
            $fields->pays->value = 'FR';
            $fields->pays->hidden = true;
            $fields->ville->value = 'Paris';
        }
    }
}

YAML:

fields:
    nom:
        label: Nom
        span: full
        type: text
    description:
        label: Description
        size: ''
        span: full
        type: richeditor
    pays:
        label: Pays
        span: auto
        default: US
        type: text
        dependsOn: nom
    ville:
        label: Ville
        span: auto
        default: NY
        dependsOn: nom
        type: text

我的理解是 filterFields() 是基于 YAML dependsOn: nom 触发的。

当我填写“Nom”并点击描述时,结果现在是:

1) 当我进入函数时,我仍然无法更改表单中的值,因为我显示字符串“toto is french”

2)在我尝试修改的文本字段上,我得到了无尽的微调器,现在无法用鼠标输入字段,只能用键盘输入

3) 如何删除绿色字符串 X_OCTOBER_ASSETS ?

Picture of the result on Description clic

【问题讨论】:

  • 你试过filterfields方法了吗?您可以操纵后端字段值。见这里:octobercms.com/docs/backend/forms#filter-form-fields
  • 谢谢,我尝试了这个功能,但是:1)我无法将文本字段与值进行比较,即:if ($this->nom == "toto") {} 2)我不知道如何修改表单字段值,具体取决于我的验证逻辑?
  • 我在下面添加了一个小例子。

标签: octobercms octobercms-backend


【解决方案1】:

要操作表单字段,您应该覆盖模型中的 filterFields 方法 - Docs

假设我们的模型有 4 个字段,其中 NamePublish 取决于 CategoryType 的值。

字段定义

category:
    label: Category
    type: dropdown
    options:
        category_a: Category A
        category_b: Category B
        category_c: Category C
type:
    label: Type
    type: dropdown
    options:
        type_a: Type A
        type_b: Type B
        type_c: Type C
name:
    label: Name
    comment: 'Comment..'
    dependsOn: [category,type] 

publish:
    label: Publish
    type: switch
    comment: 'Comment..'
    default: true
    dependsOn: [category,type]

注意:使用dependsOn 选项设置字段依赖项。这里Name 字段依赖于categorytype

型号

public function filterFields($fields, $context = null)
{
    // Category selected has a value of 'category_b';
    if ($this->category == 'category_b') {

       // Try this to see available properties on this field type
       // var_dump($fields->name);

        // Category = 'category_b' && Type selected = 'type_c'...
        if ($this->type == 'type_c') {
            $fields->name->value = 'Category set to B and Type to C';
            $fields->publish->value = false;
            $fields->publish->hidden = true;
        } else {
            $fields->name->value = "Category set to B";
            $fields->name->comment = 'Comment changed..';
            $fields->publish->value = false;
            $fields->publish->comment = "Switch has been turned off";
        }
    }
    elseif (($this->category == 'category_a') && ($this->type == 'type_a')) {
        $fields->name->value = 'Category set to A';
        // ect...
    }
}

这是非常直接的。您可以更新某个字段的所有属性,如果您只需要显示评论或隐藏某些内容,这将非常有用。 context 参数让您可以更好地控制何时应用过滤器,例如 update

希望这将帮助您入门。

编辑

为什么要将echo $this->nom.' is french'."\r\n";echo "\r\n".'filterFields() : '.$this->nom."\r\n"; 添加到filterFields 函数中?

只需删除这些行,就不会出现任何错误。

在我的示例中,我提到这是一种可视化数据响应的快速方法。查看 Backend\Classes\FormBackend\Classes\FormField 以更好地了解它的工作原理。

您的方法可能如下所示:

public function filterFields($fields, $context = null) {
    if ( $this->nom == 'toto' ) {
        $fields->pays->value = 'FR';
        $fields->pays->hidden = true;
        $fields->ville->value = 'Paris';
    }
}

【讨论】:

  • 天哪!谢谢拉贾。我在这个问题上花了 2 周时间!!! echo() 用于调试。我认为它不会干扰验证。现在它正在工作!再次感谢 !!!你知道我怎样才能有弹出窗口进行调试吗?
  • 我还找到了\Flash::info('Hello'); 的一种弹出窗口。非常感谢拉贾!
【解决方案2】:

这一切都可以在models.php 文件中完成并且工作with Model Events。您也可以在顶部使用use Author\Plugin\Models\Model 调用您想要注册的特定模型外观。

例如,我喜欢在 slug 后面加上 ID,这样您就可以使用 afterSave() 事件。您将记录与$this 一起使用。

public function afterSave()
{
    $id = $this->id;
    if (strpos($this->slug, '-'.$id) === false) 
    {
        $this->slug = $this->slug.'-'.$id;
    }
}

如果您想验证模型,您可以使用public $rules found here。以下是所需的唯一名称的示例以及验证器失败时弹出的图像。

public $rules = [
    'name' => 'required|unique:author_plugin_database',
];

【讨论】:

  • 感谢 Brandon 的友好回答!我试过 afterSave() 但由于我的表单中有很多字段,我没有设置所有字段,只调用了 setFieldsAttribute() 和 beforeValidate() 。在这些方法中,我只能获取表单值,并且无法以编程方式设置它们。更改表单字段值的正确语法是什么?
  • 抱歉,我误解了您的意图。 Raja 对你想要做的事情有比我更接近的答案。
  • 谢谢布兰登。我将您的回答用于其他目的。 filterFields() 现在在我的表单中被调用,但我不能在提交之前修改表单值 -> cf。图片
猜你喜欢
  • 2016-09-25
  • 1970-01-01
  • 1970-01-01
  • 2020-08-20
  • 2017-10-26
  • 2017-10-19
  • 2015-05-15
  • 2018-02-11
  • 2017-08-05
相关资源
最近更新 更多