How to Refresh a Page with Turbolinks

Rails 5 Turbolinks appears to reload page

Make sure that you have the Turbolinks js loaded in the page. If you are using webpacker and removed the default application js that used the asset pipeline you will probably need to use Turbolinks from npm, import it and then call Turbolinks.start() in your entry file.

Rails with turbolinks Javascript loads correctly only on a page refresh

I found the solution. The JavaScript(bolus_rechner.js) was the Problem, especialy assigning the function to show the time in a global variable.
When using turbolinks the JS is cached in the global namespace of the website/application and everytime another site of the app loads the script is executed because of the event listener with turbolinks:load. The function zeit() and its return value is assigned to uhrZeit. uhrZeit() is executed by time() and time by timefakt().

let uhrZeit = function zeit() {
if (h < 10) { h = '0' + h; }
if (m < 10) { m = '0' + m; }
return (h + ":" + m + " Uhr");
}

That means, when the script is executed the first time, and the actual time is 8h 7m, the time is displayed as 08:07. The next time a site of the app is called, 8 and respectively 7 is compared with ten again and it is still smaller than ten. Then another zero is added to the returned string and so on. Also there are numerous errors because on sites other than bolus.html.erb the html elements withe the respective ids do not exist which causes numerous reference and type errors.

The Solution is to eliminate the global variables and to create the time with helper functions and use them inside the other functions

The new script looks like this:

function currentMinutes(){
let date = new Date();
return date.getMinutes();
}
function currentHours(){
let date = new Date();
return date.getHours();
}
function time() {
let hours = currentHours()
let minutes = currentMinutes()
if (hours < 10) { hours = '0' + hours; }
if (minutes < 10) { minutes = '0' + minutes; }
return (hours + ":" + minutes + "Uhr");
}

function showTime(){
let uHr = document.getElementById("Uhrzeit");
//checking if the id exists on the page
if (uHr === null){return}
uHr.innerHTML = "Es ist " + time() + ".";
}
// Displaying the Timebased carbohydrate Faktor (BE-Faktor) and the actual time inside the form and html
function timeFakt() {
showTime();
let hours = currentHours()
let beFactorNight = 0.5;
let beFactorMorning = 1.3;
let beFactorNoon = 0.8;
let beFactorEvening = 0.5;

let beFactor = document.getElementById("faktor");
//checking if the id exists on the page
if (beFactor === null){return}
if (hours > 20 || hours < 6) {
beFactor.value = beFactorNight;

}
else if (hours >= 6 && hours < 11) {
beFactor.value = beFactorMorning;

}

else if (hours >= 11 && hours < 18) {
beFactor.value = beFactorNoon;

}
else if (hours >= 18 && hours <= 20) {
beFactor.value = beFactorEvening;

}

};
document.addEventListener("turbolinks:load", timeFakt);

// Calculation of the needed insulin for the amount of carbohydrates eaten

function insulinBerechnen() {
//Form validation and checking if the ids exist on the page
let eat = document.getElementById("be").value;
if( eat <= 0){
alert("If the carbs you ate are zero or below you don't need any insulin");
return};
let beFaktor = document.getElementById("faktor");
if (beFaktor === null){return};
if( beFaktor.value <= 0){
alert("Enter a Valid factor bigger than 0");
return};

let uLin = document.getElementById("insulin");

//calculating the Insulin according to the time of day
let hours = currentHours()
if (hours > 20 || hours < 6) {
if (beFaktor.value === ""){beFactorNight = 0.5}
else {beFactorNight = beFaktor.value};
uLin.innerHTML = (eat * beFactorNight).toFixed(2).toString();
}
else if (hours >= 6 && hours < 11) {
if (beFaktor.value === ""){beFactorMorning = 1.3}
else {beFactorMorning = beFaktor.value};
uLin.innerHTML = (eat * beFactorMorning).toFixed(2).toString();
}

else if (hours >= 11 && hours < 18) {
if (beFaktor.value === ""){beFactorNoon = 0.8}
else {beFactorNoon = beFaktor.value};
uLin.innerHTML = (eat * beFactorNoon).toFixed(2).toString();
}
else if (hours >= 18 && hours <= 20) {
if (beFaktor.value === ""){beFactorEvening = 0.8}
else {beFactorEvening = beFaktor.value};
uLin.innerHTML = (eat * beFactorEvening).toFixed(2).toString();
};

};

I also added a kind of form validation to check for values of 0 and below.
That was some hard work but I learned an important lesson from it.

Maybe this post can help other newbie programmers to solve their Javascript issues with turbolinks and to understand better how JavaScript works in the context of RoR5 App.

Cheers Sebastian

Turbolinks load event not working on with page refresh

With help from uzaif's comment, the following worked

  ready = ->
if $('body').attr('data-loaded') == 'T'
return
# code goes here
$('body').attr('data-loaded','T')
$(document).ready(ready)
$(document).on('turbolinks:load', ready)

The $('body').attr('data-loaded') lines are to prevent the code loading twice.

This approach is using event delegation, as recommended by the turbolinks instructions. It is not clear why it is still necessary to use the $(document).ready(ready) as the turbolink:load is meant to cover this.

Turbolinks causes a link with href=# to trigger page refresh

Use data-no-turbolink attribute on that link the error should be gone

<a href="#" data-no-turbolink>My link</a>


Related Topics



Leave a reply



Submit