1

I have a simple script to hide and show certain buttons, but the javascript doesn't run until a page is reloaded. How can I get it to run as soon as a user clicks that link? For example, have the page already hide certain divs the first time a user links to the page.

var array = [".section-1", ".section-2", ".section-3", ".section-4", ".section-5"];

var cnt = 0;

$(function() {
    for(var i = 0; i < 5; i++) {
        $(array[i]).hide();
    }
    $(array[cnt]).show();
    $(".previous").hide();
    $(".next").click(function () {
        if(cnt < 4){
            $(array[cnt]).hide();
            cnt++;
            $(array[cnt]).show();
        }
        if (cnt == 4) {
            $(".next").hide();
        }
        if(cnt > 0) {
            $(".previous").show();
        }

    });

    $(".previous").click(function (){

        if(cnt > 0) {
            $(array[cnt]).hide();
            cnt--;
            $(array[cnt]).show();
        }


        if(cnt < 4){
            $(".next").show();
        }
        if(cnt == 0){
            $(".previous").hide();
        }

    });
});

Here is the manifest file.

// This is a manifest file that'll be compiled into application.js, which will include all the files
// listed below.
//
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
// or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
//
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
// compiled file.
//
// Read Sprockets README (https://github.com/sstephenson/sprockets#sprockets-directives) for details
// about supported directives.
//
//= require jquery
//= require jquery_ujs
//= require turbolinks
//= require users
CPride
  • 95
  • 3
  • 11

2 Answers2

5

Your problem is with turbolinks

The issue is that Turbolinks prevents your JS from loading "normally" as it reloads the body of your page each time via ajax (breaking your JS as all your events won't be bound)

The two solutions to this are to code your JS to work with Turbolinks, or to use jquery-turbolinks to achieve a more natural solution

If you wanted to get your current code to work with Turbolinks, you could use this:

var ready = function(){

    var array = [".section-1", ".section-2", ".section-3", ".section-4", ".section-5"];
    var cnt = 0;

    for(var i = 0; i < 5; i++) {
        $(array[i]).hide();
    }
    $(array[cnt]).show();
    $(".previous").hide();
    $(".next").click(function () {
        if(cnt < 4){
            $(array[cnt]).hide();
            cnt++;
            $(array[cnt]).show();
        }
        if (cnt == 4) {
            $(".next").hide();
        }
        if(cnt > 0) {
            $(".previous").show();
        }

    });

    $(".previous").click(function (){

        if(cnt > 0) {
            $(array[cnt]).hide();
            cnt--;
            $(array[cnt]).show();
        }


        if(cnt < 4){
            $(".next").show();
        }
        if(cnt == 0){
            $(".previous").hide();
        }

    });
});

$(document).on("page:load ready", ready);
Richard Peck
  • 73,250
  • 8
  • 84
  • 139
0

This seems like a job for css. You can use css to set the display property on the divs to "none" before the page loads and then once the javascript starts running, you can decide to show them or not.

As a note for future reference, the reason the JS doesn't run until the page refreshes is because you have all your javascript in a $(function() {}) method which doesn't execute until the page is done loading.

You could also add a some lines of code outside of the ready function to execute the code immediately. This is less advisable though because broken javascript would prevent the loading of your page.

Pierre Tasci
  • 450
  • 2
  • 7