【问题标题】:Silverstripe Multiple Errors on formsSilverstripe 表单上的多个错误
【发布时间】:2023-12-05 14:29:01
【问题描述】:

我试图弄清楚如何向表单字段添加多个错误消息。这是我目前在 doFormAction 方法中使用的逻辑:

$errors = $validation->ValidateInput($data);
foreach($errors as $key => $value){
    if(!empty($value)){
        $errorMessages = "<ul>";
        foreach($value as $errorMessage){
            $errorMessages = $errorMessages . "<li>" . $errorMessage . "</li>"
        }
        $errorMessages = $errorMessages . "</ul>";
        $form->AddErrorMessage($key, $errorMessages, 'bad');
    }
}

上面的打印输出实际上不会为我打印出列表,它会在字符打印到页面上之前对字符进行 html 编码。如果我尝试使用这样的东西:

$form->AddErrorMessage("Field1", "First Error", 'bad');
$form->AddErrorMessage("Field1", "Second Error", 'bad');

我只会看到最后一条错误消息。 silverstripe 表单有没有办法在单个字段上生成多个错误消息?

编辑: 这是 silverstripe 的函数:

public function addErrorMessage($fieldName, $message, $messageType, $escapeHtml = true) {
    Session::add_to_array("FormInfo.{$this->FormName()}.errors",  array(
       'fieldName' => $fieldName,
       'message' => $escapeHtml ? Convert::raw2xml($message) : $message,
       'messageType' => $messageType,
    ));
}

这意味着当我第二次添加错误消息时,它会覆盖第一个错误消息,因为它使用相同的名称。

【问题讨论】:

    标签: forms silverstripe


    【解决方案1】:

    如果我没记错的话,AddErrorMessage 应该每个字段最多添加一个错误。即使每个字段有多个规则,我也从未添加过一条以上的错误消息,因为它可能 (a) 让用户感到困惑,并且 (b) 解决一个问题也可能解决其他问题。

    我宁愿使用客户端验证(http://parsleyjs.orghttps://rickharrison.github.io/validate.js/,...),这是为了快速反馈。然后我会再次检查服务器端,但绝大多数问题已经在客户端解决了;因此,对于罕见的用例来说,如果它有点乏味,我不会太担心。

    如果您仍想更改它,请查看 http://api.silverstripe.org/3.1/source-class-Form.html#567-581 — 您应该能够覆盖/编写自己的实现,涵盖每个字段的多个错误,但我不确定这是否值得。

    【讨论】:

    • 仅供参考,它确实看起来像 adds multiple error's at least to the session 对于单个字段虽然我认为你是对的,但我相信其他地方会限制显示的错误。
    • 对,我完全忽略了add_to_array 并认为它只是将它设置为键"FormInfo.{$this-&gt;FormName()}.errors"
    • 我将进行前端验证,现在我正在构建纯粹的后端。我正在努力让我的网站在没有 javascript 的情况下完全正常运行,因为我认为没有必要这样做。因此,我想一口气告诉用户他们犯的所有错误。这是我刚刚编写的一个随机示例,他们输入的密码为 123abc。我想回复他们说,嘿,你从来没有输入过特殊字符,嘿,你从来没有输入过大写字母,嘿,你的密码不是至少 8 个字符,等等......似乎没有办法在 1 上做到这一点字段。
    • 我现在所做的是用逗号附加所有错误并将其作为单个错误发送,但这似乎是一个糟糕的解决方案。该函数根据字段名称创建一个数组,因此当我再次使用相同的字段名称时,它将覆盖第一个。
    • @Bagzli,我将查看其余代码以显示错误,然后(希望)提供解决方案:)