Hack datepicker to make it work with Turbolinks 5.x

Patch extracted from here the comments on turbolinks issue 253 and
converted to vanilla javascript.

The hide action over datepickers ensures us that opened datepickers
will be closed before leving the page. Previously if you open any
datepicker and then move to previous page you will keep seeing the
datepicker in the restored page.
This commit is contained in:
Senén Rodero Rodríguez
2020-07-02 12:24:32 +02:00
parent 6bb9ebf12f
commit da658f3d8c
3 changed files with 61 additions and 0 deletions

View File

@@ -111,6 +111,7 @@
//= require cookies
//= require columns_selector
//= require budget_edit_associations
//= require datepicker
var initialize_modules = function() {
"use strict";
@@ -169,6 +170,7 @@ var initialize_modules = function() {
var destroy_non_idempotent_modules = function() {
"use strict";
App.Datepicker.destroy();
App.HTMLEditor.destroy();
};

View File

@@ -0,0 +1,31 @@
// Based on code by Javan Makhmali
// https://github.com/turbolinks/turbolinks/issues/253#issuecomment-289101048
// The jQuery UI date picker widget appends a shared element to the
// body which it expects will never leave the page, but Turbolinks
// removes that shared element when it rerenders. We satisfy that
// expectation by removing the shared element from the page before
// Turbolinks caches the page, and appending it again before
// Turbolinks swaps the new body in during rendering.
//
// Additionally, returning to the cached version of a page that
// previously had date picker elements would result in those date
// pickers not being initialized again. We fix this issue by finding
// all initialized date picker inputs on the page and calling the
// date picker's destroy method before Turbolinks caches the page.
(function() {
"use strict";
App.Datepicker = {
destroy: function() {
$.datepicker.dpDiv.remove();
document.querySelectorAll("input.hasDatepicker").forEach(function(input) {
$(input).datepicker("hide");
$(input).datepicker("destroy");
});
}
};
document.addEventListener("turbolinks:before-render", function(event) {
$.datepicker.dpDiv.appendTo(event.data.newBody);
});
}).call(this);

View File

@@ -190,6 +190,34 @@ describe "Admin banners magement" do
expect(page).to have_field "Post started at", with: "22/02/2002"
end
scenario "when date picker is opened and click on browser history back datepicker is closed", :js do
banner = create(:banner)
visit admin_banners_path(banner)
click_link "Edit banner"
find_field("Post started at").click
expect(page).to have_css "#ui-datepicker-div"
go_back
expect(page).to have_content("Banners")
expect(page).not_to have_css "#ui-datepicker-div"
end
scenario "date picker works after using the browser back button", :js do
banner = create(:banner)
visit edit_admin_banner_path(banner)
click_link "Manage banners"
expect(page).to have_link "Edit banner"
go_back
find_field("Post started at").click
expect(page).to have_css "#ui-datepicker-div"
end
scenario "Delete a banner" do
create(:banner, title: "Ugly banner",
description: "Bad text",