frenzyapp / turbolinks

Turbolinks is a direct port of the rails turbolinks gem and the jquery.turbolinks gem for projects using the Laravel 4.1+.
MIT License
162 stars 13 forks source link

Usage Help #13

Open lucadegasperi opened 7 years ago

lucadegasperi commented 7 years ago

Hello, I've integrated this package into my app. All the script are included inside the page (turbolinks and jquery ujs). I have a login page but when trying to submit the page nothing happens. Validation does not fire. Is there a good example I can look at for this?

Thanks

tortuetorche commented 7 years ago

Hi @lucadegasperi,

Can you post the HTML of your form here, please?

lucadegasperi commented 7 years ago

Sure!

This is the login form of a Laravel app.

<form class="form-horizontal" role="form" method="POST" action="{{ url('/login') }}" id="login-form" data-remote="true">
                        {{ csrf_field() }}

                        <div class="form-group{{ $errors->has('email') ? ' has-error' : '' }}">
                            <label for="email" class="col-md-4 control-label">E-Mail Address</label>

                            <div class="col-md-6">
                                <input id="email" type="email" class="form-control" name="email" value="{{ old('email') }}" autofocus>

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

                        <div class="form-group{{ $errors->has('password') ? ' has-error' : '' }}">
                            <label for="password" class="col-md-4 control-label">Password</label>

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

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

                        <div class="form-group">
                            <div class="col-md-6 col-md-offset-4">
                                <div class="checkbox">
                                    <label>
                                        <input type="checkbox" name="remember"> Remember Me
                                    </label>
                                </div>
                            </div>
                        </div>

                        <div class="form-group">
                            <div class="col-md-8 col-md-offset-4">
                                <button type="submit" class="btn btn-primary">
                                    Login
                                </button>

                                <a class="btn btn-link" href="{{ url('/password/reset') }}" data-turbolinks-action="advance">
                                    Forgot Your Password?
                                </a>
                            </div>
                        </div>
                    </form>

On failure this procedure is ran:

return response()->redirectTo('login')
            ->withHeaders(['X-Turbolinks' => 'advance'])
            ->withInput($request->input())
            ->withErrors($errors, $this->errorBag());
lucadegasperi commented 7 years ago

The browser console shows that the ajax request for submitting the form is called correctly

tortuetorche commented 7 years ago

You should use the https://github.com/efficiently/jquery-laravel/tree/2.2 package. You just need the PHP part, without the Larasset package. So:

composer require efficiently/jquery-laravel:2.2.*

Add this service provider to your config/app.php file:

Efficiently\JqueryLaravel\JqueryLaravelServiceProvider::class,

You can now add this security Middleware to the $middleware variable, in your app/Http/Kernel.php file:

    protected $middleware = [
        //...
        \Efficiently\JqueryLaravel\VerifyJavascriptResponse::class,
    ];

Then, edit your app/Http/Controllers/Controller.php file to add the Efficiently\JqueryLaravel\ControllerAdditions trait:


//...
class Controller extends BaseController
{
    //...
    use \Efficiently\JqueryLaravel\ControllerAdditions;
    //...
}
lucadegasperi commented 7 years ago

Thank you, But I'd like to understand how things work from a basic point of view before relying on some library that hides the complexity away (and form the name requires jQuery as well), Would you be able to help me learn all this?

Basically giving different types of inputs what should happen if turbolinks is put in the mix.

tortuetorche commented 7 years ago

Can you try this:

return response()->redirectTo('login')
            ->withHeaders(['X-Turbolinks' => 'replace'])
            ->withInput($request->input())
            ->withErrors($errors, $this->errorBag());
lucadegasperi commented 7 years ago

That's what I tried above :) Digging in further revealed that despite the library setting a 200 status code, when the response contains a "Location" header the 200 code gets converted to a 302. Removing the "Location" header resulted in everything working fine. And therefore turbolinks followed the redirect, resulting in the data flashed on the session being lost.

Has this happened to you as well?

tortuetorche commented 7 years ago

FYI,

Here the first response from turbolinks: turbolinks_redirect_1

Then the second response, the redirection itself: turbolinks_redirect_2

PS: My login form doesn't have the data-remote attribute.

tortuetorche commented 7 years ago

But I'd like to understand how things work from a basic point of view before relying on some library that hides the complexity away

For more information, see https://github.com/helthe/Turbolinks/pull/10#issue-168283224 and https://github.com/frenzyapp/turbolinks/blob/3.0.0/src/Frenzy/Turbolinks/TurbolinksServiceProvider.php#L85