【问题标题】:How can I validate textboxes that are dependent on each other and display error messages under dynamically (using JS) added input textboxes?如何验证相互依赖的文本框并在动态(使用 JS)添加的输入文本框下显示错误消息?
【发布时间】:2021-12-09 07:46:43
【问题描述】:

在我的表单中,我有一组“参加的研讨会”文本输入 - 用户输入研讨会标题、日期和研讨会主持人/组织者。

                <table class="table" id="addRemoveSeminar">
                    <thead>
                        <tr>
                            <th scope="col">Title</th>
                            <th scope="col">Date Taken</th>
                            <th scope="col">Conducted By</th>
                            <th><button type="button" name="add" onclick="addSeminar()" id="dynamic-ar-seminar" class="btn btn-outline-primary">Add Seminar</button></th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr>
                            <th scope="row"><input type="text" id="" name="Seminars[0][title]"></th>
                            <td><input type="date" id="" name="Seminars[0][date]"></td>
                            <td><input type="text" id="" name="Seminars[0][conducted_by]"></td>
                        </tr>
                    </tbody>

                </table>

表单最初只加载一组这些文本输入,但如果用户想要添加更多研讨会,他们可以单击 “添加研讨会”按钮,这三个输入框将出现一组新的输入框。这是js代码:

JS 文件:

function addSeminar() {
    var i = 0;

        ++i;
        $("#addRemoveSeminar").append('<tr><th scope="row"><input type="text" id="" name="Seminars[' + i +
        '][title]"></th><td><input type="date" id="" name="Seminars[' + i +
        '][date]"></td><td><input type="text" id="" name="Seminars[' + i +
        '][conducted_by]"></td><td><button type="button" class="btn btn-outline-danger remove-input-field">Delete</button></td></tr>'
            );

    $(document).on('click', '.remove-input-field', function () {
        $(this).parents('tr').remove();
    });
}

如您所见,titledateconducted_by 的名称属性将作为键添加到 Seminars 数组中。

问题 1: 如果验证失败,我不只是想对所有错误调用 foreach() 并将它们显示在页面顶部,我希望每个错误都显示在它对应的文本框的底部。 甚至是那些通过 Javascript 动态添加的。我该怎么做?

问题 2: 目前,所有这些输入在验证规则中都可以为空。但是,如果用户应该在其中一个输入框中输入值,我希望另外两个输入框是必需的。 例如,如果用户键入研讨会标题,则不能将日期和conducted_by 输入框留空。

我尝试阅读 Laravel 文档:https://laravel.com/docs/8.x/validation#complex-conditional-validation 部分,但我 努力弄清楚如何实现给定的示例

use Illuminate\Support\Facades\Validator;

$validator = Validator::make($request->all(), [
    'email' => 'required|email',
    'games' => 'required|numeric',
]);

在我当前的情况下,因为我用于所有输入的当前验证语法是request()-&gt;validate()。我该怎么做?

我当前在控制器中的验证:

$validated = request()->validate([
                'Seminars.*.title' => ['nullable','max:100',new LetterSpaceOnly],
            'Seminars.*.date' => ['nullable','before_or_equal: today','date'],
            'Seminars.*.conducted_by' =>  ['nullable','max:100',new LetterSpaceOnly]

]);

非常感谢您

【问题讨论】:

    标签: validation laravel-8


    【解决方案1】:

    对于第二个问题,您可以使用required_with 验证规则。 你可以在这里查看documentaion

    现在,对于第二个问题,由于字段是在加载 DOM 之后添加的,因此当 Laravel 验证输入时它不会出现。
    但是,这里有一个工作。
    在这个例子中,我们可以使用old 助手,你也可以在这里查看docs
    这里有一点关于old 的背景信息,当您提交表单时,您的所有输入都将闪现到会话中,我们可以使用上面的帮助器检索它们。
    因此,这里的解决方法是,每当验证失败时,它将返回“旧”输入,使用该帮助程序,我们可以重新创建用户提交的第一个表,并且我们可以在每个输入下显示错误字段。 对于现在的代码: 这是视图的代码,我们检查会话中是否有旧值:

                <table class="table" id="addRemoveSeminar">
                    <thead>
                        <tr>
                            <th scope="col">Title</th>
                            <th scope="col">Date Taken</th>
                            <th scope="col">Conducted By</th>
                            <th><button type="button" name="add" onclick="addSeminar()" id="dynamic-ar-seminar" class="btn btn-outline-primary">Add Seminar</button></th>
                        </tr>
                    </thead>
                    <tbody>
    
                        @if (old('Seminars'))
                            @foreach (old('Seminars') as $key => $seminar)
                                <tr>
                                    <th scope="row">
                                        <input type="text" id="" name="Seminars[{{ $key }}][title]" value="{{ $seminar['title'] }}">
                                        @if ($errors->has('Seminars.' . $key . '.title'))
                                            {{ $errors->first('Seminars.' . $key . '.title') }}
                                        @endif
                                    </th>
                                    <td>
                                        <input type="date" id="" name="Seminars[{{ $key }}][date]" value="{{ $seminar['date'] }}">
                                        @if ($errors->has('Seminars.' . $key . '.date'))
                                            {{ $errors->first('Seminars.' . $key . '.date') }}
    
                                        @endif
                                    </td>
                                    <td>
                                        <input type="text" id="" name="Seminars[{{ $key }}][conducted_by]" value="{{ $seminar['conducted_by'] }}">
                                        @if ($errors->has('Seminars.' . $key . '.conducted_by'))
                                            {{ $errors->first('Seminars.' . $key . '.conducted_by') }}
    
                                        @endif
                                    </td>
                                    <td><button type="button" class="btn btn-outline-danger remove-input-field">Delete</button></td>
                                </tr>
    
                            @endforeach
                        @else
    
                            <tr>
                                <th scope="row">
                                    <input type="text" id="" name="Seminars[0][title]">
    
                                </th>
                                <td>
                                    <input type="date" id="" name="Seminars[0][date]">
    
                                </td>
                                <td>
                                    <input type="text" id="" name="Seminars[0][conducted_by]">
    
                                </td>
                            </tr>
    
                        @endif
                    </tbody>
    
                </table>
    
    
    

    这是控制器验证规则

            $this->validate($request, [
                'Seminars.*.title' => 'sometimes|required_with:Seminars.*.date, Seminars.*.conducted_by',
                'Seminars.*.date' => 'sometimes|required_with:Seminars.*.title, Seminars.*.conducted_by',
                'Seminars.*.conducted_by' => 'sometimes|required_with:Seminars.*.title, Seminars.*.date',
            ]);
    ...
    

    另外,还有一件事,在您的 JS 代码中,onclick 事件应该在函数之外。

    function addSeminar() {
         @if (old('Seminars'))
                var i = {{ count(old('Seminars')) }} - 1;
            @else
                i= 0;
            @endif
    
            ++i;
            $("#addRemoveSeminar").append('<tr><th scope="row"><input type="text" id="" name="Seminars[' + i +
            '][title]"></th><td><input type="date" id="" name="Seminars[' + i +
            '][date]"></td><td><input type="text" id="" name="Seminars[' + i +
            '][conducted_by]"></td><td><button type="button" class="btn btn-outline-danger remove-input-field">Delete</button></td></tr>'
                );
    
        
    }
    
    $(document).on('click', '.remove-input-field', function () {
            $(this).parents('tr').remove();
        });
    
    

    要更改验证消息,您可以按如下方式使用它:
    
     $this->validate($request, [
                'Seminars.*.title' => 'sometimes|required_with:Seminars.*.date, Seminars.*.conducted_by',
                'Seminars.*.date' => 'sometimes|required_with:Seminars.*.title, Seminars.*.conducted_by',
                'Seminars.*.conducted_by' => 'sometimes|required_with:Seminars.*.title, Seminars.*.date',
            ],
    
        [
            'Seminars.*.title.required_with' => 'Custom message here',
            'Seminars.*.date.required_with' => 'Custom message here',
            'Seminars.*.conducted_by' => 'Custom message here',
    
        ]);
    

    并根据需要更改消息。

    我希望一切都清楚。

    【讨论】:

    • 感谢您抽出宝贵时间!我现在正在尝试这个。我有一个自定义规则LetterSpaceOnly,我想将其包含在验证中。如何使用 'rule1|rule2` 语法来做到这一点?当我尝试添加new LetterSpaceOnly时,返回错误Method Illuminate\Validation\Validator::validateNewLetterSpaceOnly does not exist.
    • 您可以使用数组版本的验证'Seminars.*.title' =&gt;['sometimes', 'required_with:Seminars.*.date, Seminars.*.conducted_by', new LetterSpacing]
    • 功能正常,但错误显示为The Seminars.0.date field is required when Seminars.0.title / Seminars.0.conducted_by is present.。有没有办法让它更具用户可读性?
    • 我编辑了答案,检查一下
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-18
    • 1970-01-01
    相关资源
    最近更新 更多