Skip to content
This repository has been archived by the owner on Jul 28, 2018. It is now read-only.

Partial replacement #468

Merged
merged 35 commits into from
Feb 27, 2015
Merged

Partial replacement #468

merged 35 commits into from
Feb 27, 2015

Conversation

kristianpd
Copy link
Contributor

This closes #448 by adding partial replace capabilities to Turbolinks.

@Thibaut @dhh @arthurnn

kristianpd and others added 30 commits February 27, 2015 08:43
@Thibaut
Copy link
Collaborator

Thibaut commented Feb 27, 2015

tldr;

<body>
  <div id="sidebar" data-turbolinks-permanent>
    Sidebar, never changed!
  </div>

  <div id="flash" data-turbolinks-temporary>
    You have new comments. <%= link_to 'See new comments', comments_path, change: 'comments' %>
  </div>

  <section id="comments:collection">
    <article id="comment_123"></article>
  </section>

  <div>
    <a id="comments:link">See 45 more comments</a>
  </div>

  <%= form_for Comment.new, remote: true, id: 'new_comment' do |form| %>
    <% # Show validation errors %>

    <%= form.text_area :content %>
    <%= form.submit %>
  <% end %>
</body>

<script>
# Will change #flash, #comments:collection, #comments:link
Turbolinks.visit(url, change: 'comments')

# Will change #flash, #comment_123
Turbolinks.visit(url, change: 'comment_123')

# Will only keep #sidebar
Turbolinks.visit(url)

# Will only keep #sidebar, #flash
Turbolinks.visit(url, keep: 'flash')

# Will keep nothing
Turbolinks.visit(url, flush: true)

# Same as visit() but takes a string
Turbolinks.replace(html, options)
</script>
class CommentsController < ActionController::Base
  def index
    # renders, but keeps #sidebar
  end

  def create
    @comment = Comment.new(comment_params)

    if @comment.save
      # This will change #flash, #comments:collection, #comments:link
      # -> Turbolinks.visit('/comments', change: 'comments')
      redirect_to comments_url, change: 'comments'
    else
      # Validation failure
      # -> Turbolinks.replace('<%=j render :new %>', change: 'new_comment')
      render :new, change: :new_comment
    end
  end
end


private

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✂️ newline, indent all below private.

@dhh
Copy link
Contributor

dhh commented Feb 27, 2015

Lovely. For the record, this goes into master under the target that master is now targeting a 3.0 release.

dhh added a commit that referenced this pull request Feb 27, 2015
@dhh dhh merged commit ad6ef8b into turbolinks:master Feb 27, 2015
@arthurnn arthurnn deleted the turboer-links branch February 27, 2015 18:56
@arthurnn
Copy link
Contributor

🎉 ❤️ 💚 💛 😍

@aantix
Copy link

aantix commented Feb 27, 2015

Fantastic @kristianpd

@kmcphillips
Copy link

🚀 🌙

@Thibaut Thibaut mentioned this pull request Feb 28, 2015
@Thibaut
Copy link
Collaborator

Thibaut commented Feb 28, 2015

FYI me and @kristianpd will write docs for this next week.

@Thibaut
Copy link
Collaborator

Thibaut commented Feb 28, 2015

And I'm also going to try to add some automated JS tests.

@Thibaut Thibaut mentioned this pull request Mar 1, 2015
@kurtfunai
Copy link

👍 🍰

@reed
Copy link
Collaborator

reed commented Mar 3, 2015

As it is now, Turbolinks.visit(url, change: 'comments') won't change the current URL. I see the value of that, but I also see scenarios where I'd want the URL to change. Would anyone object if I added the ability to specify that you want it to change?

Something like this:

Turbolinks.visit(url, change: 'search-results', change_url: true)

@Thibaut @kristianpd @dhh

@dhh
Copy link
Contributor

dhh commented Mar 3, 2015

Why wouldn’t Turobolinks.visit not always change the url, even when using change? Change just says “wherever we’re going, we’re just only going to change this specific DOM element”.

On Mar 3, 2015, at 11:17 AM, Nick Reed notifications@github.com wrote:

As it is now, Turbolinks.visit(url, change: 'comments') won't change the current URL. I see the value of that, but I also see scenarios where I'd want the URL to change. Would anyone object if I added the ability to specify that you want it to change?

Something like this:

Turbolinks.visit(url, change: 'search-results', change_url: true)
@Thibaut https://github.com/Thibaut @kristianpd https://github.com/kristianpd @dhh https://github.com/dhh

Reply to this email directly or view it on GitHub #468 (comment).

@reed
Copy link
Collaborator

reed commented Mar 3, 2015

Yeah, I thought I saw the value of not changing the URL, but the more I think about it, I can't come up with a scenario where you wouldn't want it to change. Not that that means there isn't one.

The relevant code currently looks like this:

if doc = processResponse()
  reflectNewUrl url unless options.change? || options.keep? || options.flush?
  reflectRedirectedUrl() # will change url if server redirected
  # ...
else
  document.location.href = crossOriginRedirect() or url.absolute # will change url

If change/keep/flush are set, issues arise in two cases. First, if processResponse() returns false, then the URL is going to change, but if it returns a valid document, then it won't...unless the second case happens, where the server has redirected. Then the URL will be changed by reflectRedirectedUrl(), which will actually use history.replaceState and overwrite the current state (which was supposed to be the state created by reflectNewUrl had it not been skipped).

@Thibaut
Copy link
Collaborator

Thibaut commented Mar 4, 2015

I agree Turbolinks.visit should always change the url, and Turbolinks.replace should never.
Also agree with @reed that a redirect_to url, change: :foo should push a state, not replace the current one.

@kristianpd what was your reasoning behind reflectNewUrl url unless options.change?
https://github.com/rails/turbolinks/blob/34a426741f07eaac9fa59718c9e8219933f42dfe/lib/assets/javascripts/turbolinks.js.coffee#L69

It would be good to add some tests for these scenarios. I can work on that maybe tonight or this week-end.

@kristianpd
Copy link
Contributor Author

@Thibaut TBH It's from Turbograft but now that I think about it, the differentiator should really be whether you visit or replace. Since turbograft doesn't have the change option on .visit, it sort of implies that the only time you're doing a partial replace is when you're not changing the URL. Since Turbolinks may want to change the URL and keep things like the sidebar i propose:

Turbolinks.visit - Changes URL always (it may stay the same, but we remove that block)
Turbolinks.replace - Does not call reflectNewUrl

@Thibaut
Copy link
Collaborator

Thibaut commented Mar 4, 2015

@kristianpd that makes sense 👍

@reed
Copy link
Collaborator

reed commented Mar 4, 2015

Made the change: 7387a96

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Partial replacement of new pages
8 participants