laravel - 在正确的选项卡中显示验证错误

Posted

技术标签:

【中文标题】laravel - 在正确的选项卡中显示验证错误【英文标题】:laravel - Display validation error in the proper tab 【发布时间】:2021-06-28 10:24:49 【问题描述】:

我正在使用引导选项卡为用户在三个不同的选项卡之间导航。第一个选项卡(主选项卡)用于显示用户详细信息,第二个选项卡用于编辑信息,第三个选项卡允许用户更改密码。

每当我在编辑选项卡中出现验证错误时,它都会返回到第一个选项卡,我必须选择编辑选项卡才能看到错误。同样,来自第三个选项卡的任何验证错误也将返回到我的第一个选项卡。

show.blade.php

div class="container">
  <div class="row my-2">
      <div class="col-lg-8 order-lg-2">
          <ul class="nav nav-tabs">
              <li class="nav-item">
                  <a href="" data-target="#profile" data-toggle="tab" class="nav-link active">Profile</a>
              </li>
              @can('update',$user)
              <li class="nav-item">
                  <a href="" data-target="#edit" data-toggle="tab" class="nav-link">Edit</a>
              </li>
              @endcan
              <li class="nav-item">
                <a href="" data-target="#change-password" data-toggle="tab" class="nav-link">Change Password</a>
            </li>
          </ul>
          <div class="tab-content py-4">
              <div class="tab-pane active" id="profile">
                  <h5 class="mb-3">User Profile</h5>
                  <div class="row">
                      <div class="col-md-6">
                          <h6>Name</h6>
                          <p>
                             $user->name
                          </p>
                          <h6>Email</h6>
                          <p>
                             $user->email
                          </p>
                      </div>
                  </div>
                  <!--/row-->
              </div>
              <div class="tab-pane " id="edit">
                  <form method="POST" action="route('profile.update',[$user])">
                      @csrf
                      @method('PATCH')
                      <div class="form-group row">
                          <label class="col-lg-3 col-form-label form-control-label">Name</label>
                          <div class="col-lg-9">
                              <input class="form-control" type="text" id="name" name="name" onkeyup="checkInput()" value="$user->name" >
                          </div>
                      </div>
                      <div class="form-group row">
                          <label class="col-lg-3 col-form-label form-control-label">Email</label>
                          <div class="col-lg-9">
                              <input class="form-control" type="email" name="email" value="$user->email" disabled>
                          </div>
                      </div>                  
                      <div class="form-group row">
                          <label class="col-lg-3 col-form-label form-control-label"></label>
                          <div class="col-lg-9">
                              <input type="reset" class="btn btn-secondary" value="Cancel">
                              <button type="submit" id="save-btn" class="btn btn-primary" disabled>Save Changes</button>
                          </div>
                      </div>
                      @if(count($errors))
                      <ul class="alert alert-danger">
                          @foreach($errors->all() as $error)
                              <li>$error</li>
                          @endforeach
                      </ul>
                      @endif
                  </form>
              </div>
            <div class="card tab-pane " id="change-password">
                <div class="card-header">Change password</div>
                  <div class="card-body">
                   @if (session('error'))
                    <div class="alert alert-danger">
                       session('error') 
                    </div>
                   @endif
                   @if (session('success'))
                    <div class="alert alert-success">
                         session('success') 
                    </div>
                    @endif
                    <form class="form-horizontal" method="POST" action="route('changePassword')">
                       @csrf
                        <div class="form-group $errors->has('current-password') ? ' has-error' : '' ">
                            <label for="new-password" class="col-md-4 control-label">Current Password</label>
                            <div class="col-md-6">
                                <input id="current-password" type="password" class="form-control" name="current-password" required>
                                @if ($errors->has('current-password'))
                                    <span class="help-block">
                                        <strong> $errors->first('current-password') </strong>
                                    </span>
                                @endif
                            </div>
                        </div>
                        <div class="form-group $errors->has('new-password') ? ' has-error' : '' ">
                            <label for="new-password" class="col-md-4 control-label">New Password</label>

                            <div class="col-md-6">
                                <input id="new-password" type="password" class="form-control" name="new-password" required>

                                @if ($errors->has('new-password'))
                                    <span class="help-block">
                                        <strong> $errors->first('new-password') </strong>
                                    </span>
                                @endif
                            </div>
                        </div>

                        <div class="form-group">
                            <label for="new-password-confirm" class="col-md-4 control-label">Confirm New Password</label>

                            <div class="col-md-6">
                                <input id="new-password-confirm" type="password" class="form-control" name="new-password_confirmation" required>
                            </div>
                        </div>

                        <div class="form-group">
                            <div class="col-md-6 col-md-offset-4">
                                <button type="submit" class="btn btn-primary">
                                    Change Password
                                </button>
                            </div>
                        </div>
                    </form>
                </div>
            </div>
          </div>
      </div>

配置文件控制器:

 public function update(UpdateProfileRequest $request, User $user)

        $this->authorize('update',$user);

        $validated = $request->validated();

        $user->update([
            'name' => $request->input('name')
        ]);


        return redirect($user->path())->with('message',"Profile has been updated");;
    

更改密码控制器:

public function changePassword(Request $request)
        if (!(Hash::check($request->input('current-password'), Auth::user()->password))) 
            // The passwords matches the password of the user in the database
            return redirect()->back()->with("error","Your current password does not matches with the password you provided. Please try again.");
        

        if(strcmp($request->get('current-password'), $request->get('new-password')) == 0)
            //Current password and new password are same
            return redirect()->back()->with("error","New Password cannot be same as your current password. Please choose a different password.");
        

        $validatedData = $request->validate([
            'current-password' => 'required',
            'new-password' => 'required|string|min:8|confirmed',
        ]);

        //Change Password
        $user = Auth::user();
        $user->password = bcrypt($request->input('new-password'));
        $user->save();

        return redirect()->back()->with("success","Password changed successfully !");

    

我尝试添加:

...
<div class="tab-pane  count($errors) ? '' : 'active' " id="profile">
...
<div class="tab-pane  count($errors) ? 'active' : '' " id="edit">
...

但它仅在有两个选项卡时才有效。我该如何解决这个问题?

【问题讨论】:

【参考方案1】:

您可以激活带有特定字段错误检查的选项卡。这种方法有效,因为您还分离了表单。分开的表格不会同时出现错误。

...
<div class="tab-pane  ($errors->has('name') || $errors->has('email')) ? 'active' : '' " id="profile">
...
<div class="tab-pane  ($errors->has('current-password') || $errors->has('new-password') || $errors->has('new-password_confirmation') ) ? 'active' : '' " id="edit">
...

【讨论】:

您的解决方案有效,但是如果错误来自控制器,我该如何处理?就像它通过了验证,但当前密码与数据库不匹配,所以它抛出一个错误,但又在主选项卡上结束。 您可以将?tab=profile?tab=password 查询字符串添加到表单操作路径中,例如:route('profile.update',[$user, 'tab'=&gt;'profile'])route('changePassword', ['tab'=&gt;'password'])。在控制器中,您可以使用$request-&gt;get('tab', 'profile') 获取选项卡查询值(配置文件是默认选项卡。)并在返回时返回 $tab 值视图并为激活选项卡添加 $tab 相等检查。如果您不想使用查询字符串,也可以将选项卡值作为隐藏输入字段发送到表单中。 你能举个例子吗?我添加了一个像``` ```这样的输入隐藏字段,在控制器中我做了这样的检查``` if (!(Hash: :check($request->input('current-password'), Auth::user()->password))) return redirect() ->back() ->with("error","你的当前密码与您提供的密码不匹配。请重试。") ->with('password', $request->input('password')); ``` 那么在我的标签中,我可以使用会话来检查标签吗? 我解决了,但我使用会话密钥必须检查

以上是关于laravel - 在正确的选项卡中显示验证错误的主要内容,如果未能解决你的问题,请参考以下文章

多个选项卡中的 MVC 表单验证 - 自动跳转到有验证错误的选项卡?

Hybris 后台 - 在正确的选项卡中显示属性

使用 JavaScript 的 Google 地图无法在 jQuery 选项卡中正确显示

419 页面在 laravel 5.7 中过期

如何使用 Ajax 从另一个页面操作引导选项卡

如何使用 vuejs 在 laravel 刀片中显示验证错误