简体   繁体   中英

Laravel 4 validation in bootstrap modal

I'm a newbie to Laravel 4, and I'm trying to get a form validation in bootstrap modal. My modal have a form with a text input and a submit button, and I want that when the validation fails, the modal show me the error. But the modal, after the validation and the page refresh, is closed. Here is the code from the controller and the view:
Controller code:

    public function postAvatar()
{
        $avatar_rules = array(
            'avatar_src' => 'url',

        );
        $validator = Validator::make(Input::all(), $avatar_rules);
        $validator->setAttributeNames(User::$names_attr); 

        if ($validator->passes()) 
        {                
        $avatar_src = (Input::get('avatar_src'))? Input::get('avatar_src') : URL::asset('assets/images/user/default-user-avatar.png');
        $user = User::find(Auth::id());
        $user->avatar_src = $avatar_src;

        if ($user){
         return Redirect::to('dashboard')->withSuccess("Success: avatar updated.");  
        }
        return Redirect::to('dashboard')->withError("Error: an error has occurred.");
        }
        return Redirect::back()->withErrors($validator);                
    }

View code:

    <!-- Modal -->
<div class="modal fade" id="avatarModal" tabindex="-1" role="dialog" aria-labelledby="avatarModalLabel" aria-hidden="true">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span></button>
        <h4 class="modal-title" id="avatarModalLabel">Update avatar</h4>
      </div>
      <div class="modal-body">
          <h4><span class="label label-info">Current avatar</span></h4>
          <img class="img-circle img-responsive dashboard-avatar" src="{{ $user->avatar_src }}" alt="{{ $user->username }} avatar">     
          <div class="divider"></div>
          <h4><span class="label label-info">New avatar</span></h4>
          {{ Form::open(array('url' => 'dashboard/avatar', 'method'=>'post', 'role'=>'form')) }}
            <ul>
                @foreach($errors->all() as $error)
                <div class="alert alert-danger" role="alert">{{ $error }}</div>
                @endforeach
            </ul>          
          <div class="form-group">
            <label for="avatar_src" class="control-label">Link avatar</label>
            <input type="text" name="avatar_src" class="form-control" id="avatar_src" placeholder="Link of avatar image url">
          </div>     
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
        <button type="submit" class="btn btn-primary">Update</button>
      </div>
         {{ Form::close() }}       
    </div>
  </div>
</div>

How can I resolve ? Thanks.

SOLVED:
Controller code:

public function postAvatar()
{
        $avatar_rules = array(
            'avatar_src' => 'url',

        );
        $validator = Validator::make(Input::all(), $avatar_rules);
        $validator->setAttributeNames(User::$names_attr); 

        if ($validator->passes()) 
        {                
        $avatar_src = (Input::has('avatar_src'))? Input::get('avatar_src') : URL::asset('assets/images/user/default-user-avatar.png');
        $user = User::find(Auth::id());
        $user->avatar_src = $avatar_src;

        if ($user->save()){
         if(Request::ajax()){
           return Response::json(array('success' => true));
        }
        }
        return Redirect::to('dashboard')->withError("Error: an error has occurred.");
        }
            return Response::json(array('errors' => $validator->errors()->toArray()));
        }

View code:

<!-- Modal -->
<div class="modal fade" id="avatarModal" tabindex="-1" role="dialog" aria-labelledby="avatarModalLabel" aria-hidden="true">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span></button>
        <h4 class="modal-title" id="avatarModalLabel">Update avatar</h4>
      </div>
      <div class="modal-body">
          <h4><span class="label label-info">Current avatar</span></h4>
          <img class="img-circle img-responsive dashboard-avatar" src="{{ $user->avatar_src }}" alt="{{ $user->username }} avatar">     
          <div class="divider"></div>
          <h4><span class="label label-info">New avatar</span></h4>
          {{ Form::open(array('url' => 'dashboard/avatar', 'id'=>'avatar_form', 'method'=>'post', 'role'=>'form')) }}
          <div class="alert alert-danger avatar_alert" role="alert" style="display: none">
              <ul></ul>
          </div>
            <ul>
            </ul>          
          <div class="form-group">
            <label for="avatar_src" class="control-label">Link avatar</label>
            <input type="text" name="avatar_src" class="form-control s_tooltip" id="avatar_src" placeholder="Avatar image links">
          </div>     
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
        <button type="submit" class="btn btn-primary">Update</button>
      </div>
         {{ Form::close() }}       
    </div>
  </div>
</div>

Ajax:

<script>
$(document).on('submit', '#avatar_form', function(event){
    var info = $('.avatar_alert');
    event.preventDefault();
    var data = { avatar_src: $("#avatar_src").val() }

    $.ajax({
        url: "/dashboard/avatar",
        type: "POST",
        data: data,
    }).done(function(response) {
            info.hide().find('ul').empty();
        if(response.errors)
        {
            $.each(response.errors, function(index, error){
                info.find('ul').append(error);
            });
            info.slideDown();
        }
        else if(response.success){
          window.location.href = "/dashboard";
        }
    });
});
</script>

Your best bet would be to validate the form via AJAX to avoid the page reloading entirely. You would then check the response of your AJAX request for the presence of errors and show them inside the modal if they exist.

You could also add in client side validation to prevent the request being made until the rules are satisfied. I wouldn't recommend using this INSTEAD of server side validation but using it ASWELL as is normally quite desirable.

To accomplish this, you'd need to do something along these lines:

Javascript:

Catch submit event of your form and make an AJAX request.

$(document).on('submit', 'form', function(event){
    event.preventDefault();

    var data = { avatar_src: $("#avatar_src").val(); };

    $.ajax({
        url: "/dashboard/avatar",
        data: data
        type: "POST",
    }).done(function(response) {
        if(response.errors)
        {
            // Add error to Modal Body
        }
        else
        {
            // Show success message, close modal?
        }
    });
});

Backend:

Modify your controller method to detect if the current request is an AJAX request and if so, return the response in JSON instead of Redirecting. For example:

if(Request::ajax())
{
    return Response::json(array('errors' => $validator->messages()));
}
else
{
    return Redirect::back()->withErrors($validator);
}

I've not tested any of that code so might contain some typos/errors but hopefully this helps you!

I was facing same issue. After research on internet,I found that Laravel don't support withSuccess('success_msg') method.

     return Redirect::to('dashboard')->withSuccess("Success: avatar updated."); 

Here is complete discussion on this topic: https://github.com/laravel/framework/issues/906 .

But you can handle this issue with this approach:-

- For Error message:-

[code has to be added in controller]

return Redirect::to('view')->withErrors('your error message.');

[code has to be added in view]

@if(isset($errors) && count($errors->all())>0)
<ul>
@foreach($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
@endif

- for succcess message:-

[code has to be added in controller]

$success_msg='your success message.';
Session::flash('successMsg', $success_msg);
return Redirect::to('view');

[code has to be added in view]

@if (Session::has('successMsg'))
{{ Session::get('successMsg') }}
@endif

This approach is working fine for me. For better display of your errors you can use bootstrap css.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM