Closed ledermann closed 9 years ago
I tried your change but it didn't work for me on a page where the chart is part of the initial page, not loaded later via AJAX. My third-party JavaScripts are included at the bottom of the page so when the chart is written out in the middle of the page, and the initChart()
executes immediately, the Chart
variable hasn't yet been defined.
Maybe the we could listen for the page:load
and page:restore
events, but only once. I.e. the last line of the initChart()
function would unbind those listeners. I'm not sure, my JS isn't very good...
Please can you try this?
diff --git a/lib/chartjs/chart_helpers.rb b/lib/chartjs/chart_helpers.rb
index eb389f1..5419c00 100644
--- a/lib/chartjs/chart_helpers.rb
+++ b/lib/chartjs/chart_helpers.rb
@@ -55,15 +55,20 @@ module Chartjs
#{legend if generate_legend}
};
- /* W3C standard */
- if (window.addEventListener) {
- window.addEventListener("load", initChart, false);
- document.addEventListener("page:load", initChart, false);
+ if (typeof Chart !== "undefined" && Chart !== null) {
+ initChart();
}
- /* IE */
- else if (window.attachEvent) {
- window.attachEvent("onload", initChart);
- document.attachEvent("page:load", initChart);
+ else {
+ /* W3C standard */
+ if (window.addEventListener) {
+ window.addEventListener("load", initChart, false);
+ document.addEventListener("page:load", initChart, false);
+ }
+ /* IE */
+ else if (window.attachEvent) {
+ window.attachEvent("onload", initChart);
+ document.attachEvent("page:load", initChart);
+ }
}
})();
END
If Chart
is already defined it executes initChart()
immediately. This takes care of the AJAX case.
If Chart
isn't defined, it waits for the load
event before calling initChart()
. This takes care of normal page loads.
Ok, I've only tested my change in my app where Turbolinks is used, so the JavaScripts are loaded in the head, not in the bottom. You are right, loading the JS later in the <body>
will break my change.
I have tried your patch, it works fine in my app: It always executes the if-part, the else-part is never used.
I'm not sure if we need the page:load
listener anymore. It may be required if Turbolinks is used and the JS is loaded later in the <body>
, which should be avoided.
Good to hear the patch works for you.
I need the page:load
listener in my app which doesn't yet use Turbolinks and loads JS later on in the body. Without it, initChart()
is never called. Would you agree?
Hm, so far as I know, page:load
is an event triggered by Turbolinks. Without Turbolinks you need a listener for onload
only (which of course should not be removed).
Aha, you're right. I had forgotten that page:load
came from Turbolinks.
I'll release a new version of the gem with this change.
Great, thanks!
It's in v2.1.3. Thanks for all your help!
I can confirm this fixed my problem. (https://github.com/airblade/chartjs-ror/issues/18) Thanks so much guys!
There are two issues using the
chart
helper in conjunction with Turbolinks:page:restore
event instead ofpage:load
. Because there is no listener for this event, the charts on this pages are missing. Maybe this could be fixed by adding a listener forpage:restore
- but wait and look at the next issue.This PR fixes both issues by executing
initChart()
without event listener (like proposed by @glundgren in #5). Because #5 is some kind of stale, I open this one. What do you think?The right way of initializing a chart is asked in nnnick/Chart.js#929, but there is still no anwer.