Closed alexventuraio closed 7 years ago
If you uses turbolinks you can put the code in assets/application.js like this:
$(document).on('turbolinks:load', function() { $('select').material_select(); });
Thanks @oscartzgz I have done what you said but I still getting the same behavior when I go back and forward with out reloading the page. It seems to be creating components on the fly. Even though I'm using turbo links with the turbolinks:load
event handler.
try
<head>
...
<meta name="turbolinks-cache-control" content="no-preview">
</head>
see https://github.com/turbolinks/turbolinks#opting-out-of-caching
Same issue here. I initialize the select as you've indicated, on turbolinks:load
, and have tried adding the meta tag but to no effect.
If you use Turbolinks, you want to destroy the select before the page is cached by calling $('select').material_select('destroy');
(see Updating/Destroying Select in Forms).
The reason is that .material_select()
does a bunch of magic to create your beautiful selects. When you navigate away from the page, Turbolinks caches the whole page as is with all the magic. So when you load that page from cache later and run .material_select()
again, the magic is applied again and you end up with the nested selects that you have described. So what you want to do is to "undo" the Materialize magic before caching. You can do that by destroying the material select in Turbolink's before-cache hook.
# app/assets/javascripts/helpers/materialize.coffee
##############################################################
## Helper file to make Materialize work with Turbolinks ######
##############################################################
##############################################################
## ON LOAD ###################################################
## Actions to be executed on page load (first or history) ####
##############################################################
$(document).on 'turbolinks:load', ->
# bunch of stuff here (fixing tooltips, datepicker, etc...)
# initialize selects
$('select').material_select()
##############################################################
## BEFORE CACHE ##############################################
## Actions to be executed before Turbolinks caches the page ##
##############################################################
$(document).on 'turbolinks:before-cache', ->
# bunch of stuff here (fixing tooltips, datepicker, etc...)
# destroy selects
$('select').material_select('destroy')
PS: Make sure this file is loaded on every page (it will be if you have the line //= require_tree .
in app/assets/javascripts/application.js)
Yes! @fwoelm you're right. It has to see with the JS elements cached when loading pages. But I do something a little bit different and that's how I'm solving the issue right now. With Toast
elements I call another method which is actually not included in the Materialize documentation but in the jQuery docs .remove()
.
So, this is what I'm doing:
$(document).on("turbolinks:before-cache", function () {
// Destroy cached JS elements on turbolinks 'before-cache' to recreate new ones on 'load' event
$('select').material_select('destroy');
$('.toast').remove();
});
I tell jQuery to select all the HTML elements with the toast
class and then just remove them.
And it works like a charm! 😃 So, it is solved by the moment!
Hi there! As the docs says we need to call an initializer for some JS components like this.
My doubt is, where to put the initializers? because I put it at the end of my form view into a
script
html tag and it works fine but when I push the browser's back button and then the forward button without refreshing the page, it seems like to render nested JS components into itself. I mean, using the inspector, the html code looks like callbacks in JS.And it increases as many times you go back and forward until you refresh the page.
So where to put this JS initializer code in order to be executed only once or maybe how to force the browser to refresh the page on every back and forward action in order to show only one of the components?
This is my code: