Laravel 5.7使用星号,required_if验证字段

时间:2019-01-12 10:53:45

标签: php laravel vue.js laravel-5.7

我有一个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。

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

3 个答案:

答案 0 :(得分:3)

就像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;
}

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

答案 1 :(得分:1)

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());

答案 2 :(得分:1)

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

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->validate中将规则作为['experiences.*' =>['array', new CustomRule()]而不是required_if...

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