Giter Site home page Giter Site logo

turbolinks.ex's Introduction

Turbolinks

Hex Version Build Status

Docs

Motive

When you visit location /one and the server redirects you to location /two, you expect the browser’s address bar to display the redirected URL.

However, Turbolinks makes requests using XMLHttpRequest, which transparently follows redirects. There’s no way for Turbolinks to tell whether a request resulted in a redirect without additional cooperation from the server.

To work around this problem, send the Turbolinks-Location header in response to a visit that was redirected, and Turbolinks will replace the browser’s topmost history entry with the value you provide.

source

Installation

Add Turbolinks to your list of dependencies in mix.exs:

def deps do
  [{:turbolinks, "~> 1.0"}]
end

Usage with Phoenix

in package.json

{
  ...
  "dependencies": {
    "phoenix": "file:deps/phoenix",
    "phoenix_html": "file:deps/phoenix_html",
++  "turbolinks": "^5.0.0"
  }
  ...
}

Run npm install and update /web/static/app.js

import "phoenix_html"
++ import Turbolinks from 'turbolinks'
++ Turbolinks.start()

in /web/web.ex

defmodule Web do
  def controller do
    quote do
      use Phoenix.Controller
++    use Turbolinks
      import MyApp.Router.Helpers
      import MyApp.Gettext
    end
  end

  def view do
    quote do
      use Phoenix.View, root: "lib/web/templates",
                        namespace: Web

      # Import convenience functions from controllers
--    import Phoenix.Controller, only: [get_flash: 2, view_module: 1]
++    import Phoenix.Controller, only: [get_flash: 2, view_module: 1, get_csrf_token: 0]

      # Use all HTML functionality (forms, tags, etc)
      use Phoenix.HTML

      import Web.Router.Helpers
      import Web.ErrorHelpers
      import Web.Gettext
    end
  end
end

in /web/router.ex

defmodule Web.Router
  pipeline :browser do
    plug :accepts, ["html"]
    plug :fetch_session
    plug :fetch_flash
    plug :protect_from_forgery
    plug :put_secure_browser_headers
++  plug Turbolinks
  end
end

Redirecting After a Form Submission

Turbolinks module imports a redirect/2 function with API parity with phoenix's redirect/2 function. This provides progressive enhancement when we submit a form with XHR.

More details can be found here

Unobtrusive JavaScript

in package.json

{
  ...
  "dependencies": {
    "phoenix": "file:deps/phoenix",
    "phoenix_html": "file:deps/phoenix_html",
    "turbolinks": "^5.0.0",
++  "jquery": "^3.1.0",
++  "jquery-ujs": "^1.2.2"
  },
  ...
}

in brunch-config.js

{
  ...
  npm: {
    enabled: true,
++  globals: {
++    jQuery: 'jquery',
++    $: 'jquery'
++  }
  },
  ...
}

Run npm install and update /web/static/app.js

-- import "phoenix_html"
++ import 'jquery-ujs'
import Turbolinks from 'turbolinks'

Turbolinks.start()

in web/templates/layout/app.html.slim, add these two meta tags

head
++  meta name="csrf-token" content="#{get_csrf_token()}"
++  meta name="csrf-param" content="_csrf_token"
  ...
--  script src="#{Routes.static_path(@conn, "/js/app.js")}"
++  script data-turbolinks-track="reload" src="#{Routes.static_path(@conn, "/js/app.js")}"
  ...
body
  ...

To submit form remotely set the data-remote html attribute on the form to true, this is an example for phoenix_slim

= form_for @changeset, @action, [data: [remote: true]], fn f ->
  = text_input f, :title, placeholder: "Post title"
  = text_input f, :body, placeholder: "Post body"
  = submit "Submit", class: "button is-primary"

To use a remote link like logging out that makes a DELETE call

= link(@conn, to: session_path(@conn, :delete), data: [method: :delete, remote: true]

turbolinks.ex's People

Contributors

easterpeanut avatar fatboypunk avatar fmcgeough avatar imranismail avatar jung-hunsoo avatar markschultz avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

turbolinks.ex's Issues

Multiple AJAX requests (one successful and the rest cancelled) with a remote form

Following the instructions in the README, I made a search form that sends an AJAX request and everything was working fine at first, together with the turbolinks. However, I noticed that every time I submitted the form, there was one additional and identical cancelled AJAX request. The requests were piling up so this started slowing the page down eventually.

The solution that I found was moving the <script src="<%= static_path(@conn, "/js/app.js") %>"></script> in app.html.eex from the body to the head.

Maybe there's a better solution. I'm not sure if Turbolinks.clearCache() could work - tried using it to no avail (maybe I tried the wrong approach though). In any case, I think this issue should be discussed.

on phoenix 1.3 compile error : undefined function get_csrf_token/0

In the readme you are using get_csrf_token() inside the app.html.eex
on phoenix 1.3 not every function from Phoenix.Controller is imported into Phoenix.View
you might want to add the following line change
from
import Phoenix.Controller, only: [get_flash: 2, view_module: 1]
to
import Phoenix.Controller, only: [get_flash: 2, view_module: 1, get_csrf_token: 0]
Then everything compiles

Parameter order issue?

In master, set_location_header in Turbolinks module has the parameters in the wrong order, no? See the call on line 44. It passes in conn as the second parameter. but the new code has:

defp set_location_header(conn, location) do

Jquery and jquery-ujs conflict

Jquery and jquery-ujs and conflict and my all method:delete links giving no route error. After changing jQuery: 'jquery' to jquery: 'jquery' links work. But turbolinks doesnt work after that. I created a new app from zero with readme i still get same error

app.js

import "phoenix_html"
import "jquery-ujs"

Brunch-config.js

npm: {
enabled: true,
globals: {
$: 'jquery',
jQuery: 'jquery' }};

jQuery is not defined

rails.js:559Uncaught ReferenceError: jQuery is not defined(…)

The jquery-ujs library requires jQuery global to be defined.

Workaround:

Add to brunch-config.js:

  npm: {
    enabled: true,
    whitelist: ["phoenix", "phoenix_html"],
    globals: {
      $: 'jquery',
      jQuery: 'jquery'
    }
  }

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.