Last Updated
Viewed 24 Times

I am having a lot of trouble getting any javascripts to run in my Ruby application.

Currently my console is giving me one error message:

"Uncaught TypeError: Cannot read property 'clientWidth' of undefined"

This error is referencing this line in my application.js file:

const size = carouselImages[0].clientWidth;

I'm guessing it's saying it has no idea what clientWidth is? I was following along with this tutorial when I hit this roadblock. (He's not making a rails app, but his script loads fine.) The script also loaded fine for me when I created a regular index.html page not tied to my ruby app.

How do I define clientWidth/do I need to?

My Rails files:

Gem File

gem 'coffee-rails', '~> 4.2'

# Turbolinks makes navigating your web application faster. Read more: https://github.com/turbolinks/turbolinks
gem 'turbolinks', '~> 5'
# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
gem 'jbuilder', '~> 2.5'
# Use Redis adapter to run Action Cable in production
# gem 'redis', '~> 4.0'
# Use ActiveModel has_secure_password
# gem 'bcrypt', '~> 3.1.7'

gem 'jquery-rails', '~> 4.3', '>= 4.3.3'
gem 'rails-ujs', '~> 0.1.0'
gem 'jquery-ui-rails'

_header.html.erb

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Page Title</title>

<%= stylesheet_link_tag    'application', media: 'all', 'data-turbolinks-track': 'reload' %>
    <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>

<%= javascript_include_tag( 'slider.js' ) %>

</head>
<body> <!--Body and html tags are closed in my _footer.html.erb -->

application.js

//= require rails-ujs
//= require jquery 
//= require jquery_ujs 
//= require turbolinks


$(document).ready to $(document).on('turbolinks:load', function(main());

//image slider code
//
//

const carouselSlide = document.querySelector('.carousel-slide');

const carouselImages = document.querySelectorAll('.carousel-slide img');


//buttons

const prevBtn = document.querySelector('#prevBtn');
const nextBtn = document.querySelector('#nextBtn');


//Counter

let counter = 1;
const size = carouselImages[0].clientWidth;

carouselSlide.style.transform = 'translateX('+(-size * counter)+ 'px)';

slider.html.erb

<button id="prevBtn">Prev</button>
<button id="nextBtn">Next</button>

<br /><br />

<div class="carousel-container">
<div class="carousel-slide"> 
<%= image_tag("photo4.jpg", id: "lastClone") %> 
<!-- photo1.jpg is an image of a road at sunset should have the border around it and be the focus. Currently, it is not. -->
<%= image_tag("photo1.jpg") %> 
<%= image_tag("photo2.jpg") %>
<%= image_tag("photo3.jpg") %>
<%= image_tag("photo4.jpg") %>
<%= image_tag("photo1.jpg", id: "firstClone") %>
</div>
</div>

slider.scss

/* This is for a test slider */

.carousel-container {
  width: 1000px;
  border: 5px solid black;
}

.carousel-slide {
  display: flex;

  img{
    width: 1000px;
    height: auto;
  }
}

Here is an imgur link to see a screenshot of my ruby app vs. a regular .html file I created to compare/contrast what is going on: https://imgur.com/a/jVhjLd3

Here are the versions I am running of things:

Ruby: ruby 2.5.0p0 (2017-12-25 revision 61468) [x86_64-linux]

Node: v13.2.0

NPM: 6.13.1

I tried a few different suggestions found via google searches (a la 'get fixed quick'), so if anything is off or out of place, please point it out to me. If you require more info/code, I will be happy to provide.

Any help getting my Javascript to run would be greatly appreciated!

I'm using the Embedly API with this code:

$.embedly('http://www.youtube.com/watch?v=LfamTmY5REw',
       {maxWidth: 600,
           elems: $('#element'),
         success: function(oembed, dict){
                    alert(oembed.title);
                  });

Now my question is where should I put this code in my ruby on rails directory? In my application.js file? And how do I call this code when a url is submitted via a form?

I am building a Ruby on Rails app that lets a user create a workout for various durations (i.e. 30 minutes). A workout has_many exercises. Each exercise has a duration (i.e. 30 seconds). I want the workout to loop through a random array of exercises until the timer runs out.

I am trying to get an event to trigger when the timer (in JS) reaches 00:00 - so when the exercise reaches 0 seconds, it renders a new exercise and it's corresponding new countdown. When the workout.duration = 0, redirect to root_path.

I have the basic app up here: https://morning-garden-55692.herokuapp.com/workouts/3

This all is called from the WorkoutsController and takes place in the Workout#show view.

This is the ruby in the show view:

<% @exercises.each do |ex| %>
    <%= ex.name %> <br><br> <div id="exclock"> <span class="hours"></span> :
    <span class="minutes"></span> :
    <span class="seconds"></span>

This is the js that runs the clock:

<script>
function getTimeRemaining(endtime) {
  var t = Date.parse(endtime) - Date.parse(new Date());
  var seconds = Math.floor((t / 1000) % 60);
  var minutes = Math.floor((t / 1000 / 60) % 60);
  var hours = Math.floor((t / (1000 * 60 * 60)) % 24);
  return {
    'total': t,
    'hours': hours,
    'minutes': minutes,
    'seconds': seconds
  };
}

function initializeClock(id, endtime) {
  var clock = document.getElementById(id);
  var hoursSpan = clock.querySelector('.hours');
  var minutesSpan = clock.querySelector('.minutes');
  var secondsSpan = clock.querySelector('.seconds');

  function updateClock() {
    var t = getTimeRemaining(endtime);

    hoursSpan.innerHTML = ('0' + t.hours).slice(-2);
    minutesSpan.innerHTML = ('0' + t.minutes).slice(-2);
    secondsSpan.innerHTML = ('0' + t.seconds).slice(-2);

    if (t.total <= 0) {
      clearInterval(timeinterval);
    }
  }

  updateClock();
  var timeinterval = setInterval(updateClock, 1000);
}


var timeInSeconds = <% @exercises.each do |ex| %>
    <%= ex.duration %>; <% end %>
var currentTime = Date.parse(new Date());
var deadline = new Date(currentTime + timeInSeconds*1000);
initializeClock('exclock', deadline);
</script>

In the workouts controller:

def show
        @exercises = Exercise.limit(1).order("RANDOM()")

    end

I think in the js I need to just include some

until: +Exercise.duration == 0, onExpiry: nextEx

Any help in triggering a redirect upon expiry or rendering another exercise?

I have a semantic_form_for in my view that sets up a search filter, and more filters are added with a button that, through JavaScript, adds more filters.

 <%= semantic_form_for current_coach, :remote => true, :html => { :class => "custom-form rb-form", :id => "filter", :'data-url' => "#{roster_builder_coach_index_path}" } do |f| %>
  <div class="filter_parent_container">
    <% @search.conditions.each do |condition| %>
        <%= render "filter", :condition => condition %>
    <% end %>
  </div>

  <div class="bottom-info">
    <div class="count">
      <p class="num"><%= @athletes.count %></p>
      <p>identified with this filter set</p>
    </div>
    <input type="submit" class="send-request" id="search-button" value="" />
    <input type="button" class="add_filter" value="Add Another Filter" />
  </div>
  <div class="cl">&nbsp;</div>
<% end %>

I need the form to submit via ajax, but it isn't. I'm checking the params in the controller and they are:

{"action"=>"roster_builder", "controller"=>"coach"}

Here's the controller (logger is checking the params):

def roster_builder
authorize! :access_roster_builder, current_coach

logger.info("**************");
logger.info("**************");
logger.info("**************");
logger.info("**************");
logger.info("**************");
logger.info(params);
@search = Search.new(sport: current_coach.primary_sport, conditions: params[:search])
@athletes = @search.query.page(params[:page]).per_page(8)

render "athletes" if request.format.js?
end

Here is the Ajax call:

$("#filter").submit(function(){
  $.ajax({
    url: $("#filter").attr("data-url"),
    type: 'POST',
    success: function(data) {
      $(".results")[0].parentNode.removeChild($(".results")[0]);
    }
  });
});

Before I used :remote => true, it was working, but I need persistence across the filters (including the ones added via JS), so I need Ajax to perform the search rather than doing a page refresh. Why isn't params working now that Ajax is sending the form data? I even tried sending the data via Ajax as serialized, to no avail, as follows:

$.ajax({
  url: $("#filter").attr("data-url"),
  type: 'POST',
  data: $("form#filter").serialize(),
  success: function(data) {
    $(".results")[0].parentNode.removeChild($(".results")[0]);
  }
});

Any help would be appreciated!

Similar Question 4 (1 solutions) : How do I output a Ruby hash as Javascript?

Similar Question 6 (2 solutions) : How can I feed ruby on rails data into d3.js?

cc