I'm having a _form partial in oorder to create/edit posts. This form has a dropdown for setting the post status, so if the user sets the status as Scheduled
then the datetimepicker shows up in order to select a date, otherwise this is should be hidden by default (ie when status is "Draft" or "Published").
# app/views/posts/_form.html.haml
= simple_form_for ["admin", @post] do |f|
= f.input :title
= f.input :status, collection: ["Draft", "Published", "Scheduled"], selected: status_for(@post)
.published-field
= f.input :published_at, as: :date_time_picker
...
# app/helpers/posts_helper.rb
module PostsHelper
def status_for(post)
if post.published_at?
if post.published_at > Time.zone.now
"Scheduled"
else
"Published"
end
else
"Draft"
end
end
end
# app/assets/javascripts/posts.coffee
changeVisibility = (status) ->
if status == "Scheduled"
$(".published-field").show()
else
$(".published-field").hide()
jQuery ->
changeVisibility $("#post_status :selected").text()
$("#post_status").on "change", (e) ->
changeVisibility $(this).find(":selected").text()
The problem comes when user access the page for the first time, so the status
is set to Draft
by default (as expected), however the datetimepicker is visible which isn't supposed to (remeber? this should be visible only if user selects to schedule the post). If you refresh the page at this point when vieweing the fomr, then the datepicker disapears.
The original issue can also be found here https://gorails.com/episodes/scheduling-posts
This issue is probably caused because of turbolinks. I have also tried to use the jquery-turbolinks
gem, but didn't manage to solve the problem. Any ideas how to fix this issue?
If you want to use Turbolinks, its important to remember that it works by not having real page loads at all, it just does an XHR request then replaces the HTML within <body>
, while saving the old <body>
to implement the back button.
This means no scripts will get executed, you wont get any document load/ready events, etc. $(handler)
is the same as $.ready(handler) and is only run on page load once "page's Document Object Model (DOM) becomes safe to manipulate.".
Turbolinks fires turbolinks:load
on document
, so use $(document).on('turbolinks:load', handler)
for all such things.
You also need to be aware of the fact it kept a copy of your old <body>
DOM and anything scripts did, so any memory used by that, and any other JavaScript from the last "page" such as timeouts and animation frames, etc. keeps running. And you used it to implement the show/hide based on the CSS selector at load time.
This Rails guide has more information, as well as the Turbolinks library itself.