【问题标题】:Laravel 5.7 validate fields with asterisk, required_ifLaravel 5.7 验证带星号的字段,required_if
【发布时间】:2019-06-07 02:31:31
【问题描述】:

我有一个 Vue 表单,可让用户为其个人资料添加工作经验。 用户可以通过单击按钮添加额外的体验。单击该按钮将添加一个带有新输入字段的新项目。我无法添加整个脚本,因为它已经很大了。但这里有一个例子给你一个想法:

<div class="item">
    <div class="row">
        <div class="form-group col-md-6">
            <label class="form-label">Title</label>
            <input type="text" name="experiences[0][title]" class="form-control">
        </div>
        <div class="form-group col-md-6">
            <label class="form-label">Institution</label>
            <input type="text" name="experiences[0][institution]" class="form-control">
        </div>
    </div>
    <div class="row">
        <div class="col-md-12">
            <textarea name="experiences[0][comments]" class="form-control"></textarea>
        </div>
    </div>
</div>
<div class="item">
    <div class="row">
        <div class="form-group col-md-6">
            <label class="form-label">Title </label>
            <input type="text" name="experiences[1][title]" class="form-control">
        </div>
        <div class="form-group col-md-6">
            <label class="form-label">institution </label>
            <input type="text" name="experiences[1][institution]" class="form-control">
        </div>
    </div>
    <div class="row">
        <div class="col-md-12">
            <textarea name="experiences[1][comments]" class="form-control"></textarea>
        </div>
    </div>
</div>

在每个元素之后都有一个按钮来添加新行。这工作正常,但我有一些验证问题。 如果其中一个字段有值,我只想验证这些字段。例如: 如果experiences[0][institution] 有值,则需要experiences[0][title]experiences[0][comments]。 这必须在每个订单中都有效。如果title 有值,则需要其他字段。 我真的无法找到一种方法来验证这一点。这是我的验证规则:

$this->validate(request(), [
        'experiences.*.title'       => 'required_if:experiences.*.institution,null',
        'experiences.*.institution' => 'required_if:experiences.*.title,null',
]);

这里的问题是它根本无法验证。我不知道如何制定一条规则,如果字段 X 有值,则需要 Y 和 Z。

希望这里的任何人都可以帮助我找到解决方案! :)

【问题讨论】:

    标签: php laravel vue.js laravel-5.7


    【解决方案1】:

    就像 Azeame 所说,制定一个自定义验证规则并检查是否所有值都已填充或全部为空。在以下行中的一些东西:

    public function passes($attribute, $value)
    {
        $required = ['title','institution','comments'];
    
        $experience = collect($value)->reject(function ($item, $key) {
            return empty($item);
        });
    
        if (count($experience) == 0) {
            return true;
        }
    
        foreach ($required as $field) {
            if ( !$experience->has($field)) {
                return false;
            }
        }
    
        return true;
    }
    

    也许有更好的方法,但这应该可行。

    【讨论】:

    • 我会试试看的:)
    【解决方案2】:

    required_if 不适用于 null,因为它会将其视为字符串 ("null"),但它可以使用布尔值。

    您可以改为使用required_without 规则:

    $this->validate(request(), [
        "experiences.*.title"       => "required_without:experiences.*.institution",
        "experiences.*.institution" => "required_without:experiences.*.title",
    ]);
    

    例子

    $experiences = [
        [
            "title"       => "My title",
            "institution" => "",
            "comments"    => "<p>My first description</p>", //passes
        ],
        [
            "title"       => "",
            "institution" => "My title",
            "comments"    => "<p>My second description</p>", //passes
        ],
        [
            "title"       => "My title",
            "institution" => "My title",
            "comments"    => "<p>My third description</p>", //passes
        ],
        [
            "title"       => "",
            "institution" => null,
            "comments"    => "<p>My forth description</p>", //fails
        ],
    
    ];
    
    $rules = [
        "experiences.*.title"       => "required_without:experiences.*.institution",
        "experiences.*.institution" => "required_without:experiences.*.title",
    ];
    
    $validator = Validator::make(compact('experiences'), $rules);
    
    dd($validator->fails());
    

    【讨论】:

    • 不知何故它跳过了验证的第一部分。如果我将title 留空并给institution 一个它不会验证的值。但是merge 之后的第二部分效果很好:-)
    • @Ruub 你能在上面的例子中显示dd(request('experiences')) 的输出吗?
    • [ "title" =&gt; null, "institution" =&gt; "My Company", "comments" =&gt; "&lt;p&gt;My first description&lt;/p&gt;", ], [ "title" =&gt; "My title", "institution" =&gt; null, "comments" =&gt; "&lt;p&gt;My second description&lt;/p&gt;", ] ];
    • 等等,确切的输出是:array:2 [ 0 =&gt; array:3 [ "title" =&gt; null "institution" =&gt; "My Company" "comments" =&gt; "&lt;p&gt;My first description&lt;/p&gt;" ] 1 =&gt; array:3 [ "title" =&gt; "My title" "institution" =&gt; null "comments" =&gt; "&lt;p&gt;My second description&lt;/p&gt;" ] ]
    • @Ruub 从头开始​​,这是正在使用的规则的问题。我现在会更新我的答案。
    【解决方案3】:

    使用php artisan make:rule 编写自定义规则,并在passes() 函数中编写检查以确保所有数组键都存在并且至少2 个数组值不为空。我在想这样的事情:

    function passes($attribute, $value){
        if(array_keys($value) !== ['title','institution','comments']){
            return false;
        }
        if(empty($value['title']) && empty($value['institution'])){
            return false;
        }
    
        return true;
    }
    

    并且在您的$this-&gt;validate 中将规则传递为['experiences.*' =&gt;['array', new CustomRule()] 而不是required_if...

    我还没有检查过这个,所以如果它坏了,请随时编辑。

    【讨论】:

    • 我也有制作自定义规则的想法,但真的希望有一种更“简单”的方式来做到这一点:)
    • 其实很简单,试一试,你会惊讶的,如果我现在手机里没有wifi,我就直接写给你吧跨度>
    • @Ruub 我更新了答案,看看这是否对你有用,我相信它应该很好用
    • 我会试试看的:)
    • 我又编辑了一遍,虽然我不是第一个 if 语句实际上有什么好处,但是现在是凌晨 4:30,我还没有睡觉,所以我暂时把它留了下来,你也可以用与 null 的比较来替换空调用,需要睡眠
    猜你喜欢
    • 2016-10-13
    • 2021-03-06
    • 2022-12-08
    • 2019-03-11
    • 1970-01-01
    • 2019-03-21
    • 1970-01-01
    • 2018-11-05
    • 1970-01-01
    相关资源
    最近更新 更多