Can't assign jQuery result to a variable - javascript

I'm developing a Ruby on Rails application and I want to use a dashboard called gentelella. This one https://github.com/puikinsh/gentelella
The template works just perfectly in simple HTML format. But when I transfer everything to my Rails app it becomes uninteractive. I mean I can't click the sidebar menu items.
And the problem is inside its custom.js file.
It assigns sidebar-menu to a variable like so
$SIDEBAR_MENU = $('#sidebar-menu')
And then attaches a 'click' event to it like this:
$SIDEBAR_MENU.find('a').on('click', function(ev) {
console.log('clicked - sidebar_menu');
}
The problem is that it never gets to 'clicked - sidebar_menu' console message if I leave it as is (in my Rails app), and thus the menu doesn't work at all.
But if I put log trace just before:
console.log($SIDEBAR_MENU);
$SIDEBAR_MENU.find('a').on('click', function(ev)
I get this in the output
jQuery.fn.init {context: document, selector: "#sidebar-menu"}
context
:
document
selector
:
"#sidebar-menu"
proto
:
Object(0)
So I'm sure it is actually assigned to a variable is is definitely not null
Then I replace all $SIDEBAR_MENU occurrences by $('#sidebar-menu')
to get this
$('#sidebar-menu').find('a').on('click', function(ev) {
alert('it works now!');
}
And it starts to work just fine. It's blowing up my mind already,
I just couldn't find any reasonable explanation for this. Can anybody, please, explain why it might happen?
p.s. I'm using Rails 5.0.2 with jQuery v1.12.4 (from Gems)
Sorry if some topic like this already exists, I had searched for the answer and couldn't find it
Here are the contents of application.js
//= require jquery
//= require jquery_ujs
//= require bootstrap
//= require turbolinks
//= require fastclick
//= require nprogress
//= require Chart.min
//= require gauge.min
//= require bootstrap/bootstrap-progressbar
//= require icheck.min
//= require skycons
//= require jquery.flot
//= require jquery.flot.pie
//= require jquery.flot.time
//= require jquery.flot.stack
//= require jquery.flot.resize
//= require jquery.flot.orderBars
//= require jquery.flot.spline.min
//= require curvedLines
//= require date-ru-RU
//= require jquery.vmap.min
//= require jquery.vmap.world
//= require jquery.vmap.sampledata
//= require moment.min
//= require bootstrap/daterangepicker
//= require custom

I've just found what was the reason of such a strange behavior.
After I took a detailed look at Gentelella's source I've noticed that all script tags are at the bottom of the page.
So I've changed my Rails template for the page the way that it also includes them after the body
<!DOCTYPE html>
<html>
<head>
<title>No Matter</title>
<meta name="viewport" content="width=device-width, initial-scale=1 maximum-scale=1, user-scalable=no">
<%= csrf_meta_tags %>
<%= stylesheet_link_tag 'dashboard', media: 'all', 'data-turbolinks-track': 'reload' %>
</head>
<body class="nav-md">
<%= yield %>
</body>
<%= javascript_include_tag 'dashboard', 'data-turbolinks-track': 'reload' %>
</html>
Now it all works fine. I'm not sure why this happens though, since there is a $(document).ready() callback in Gentelella's "custom.js" which initializes everything and the whole menu is there from the very beginning, nothing's loaded dynamically. I'd be grateful if somebody could explain why, since I myself am kind of newbie in web development

Related

Best way to call JS files?

Issue: I noticed my chartkick charts were not appearing and stuck on "loading..." within production.
I debugged and realized the reason is because i recently created a bunch of .js files under javascripts to cut down on <script></script> code within my views and instead using <%= javascript_include_tag "word" %>.
What the problem is, and the difference btween the charts showing and not showing is in my initializers/assets.rb folder is:
Rails.application.config.assets.precompile << '*.js'
Without this, it works, but also without it, i cannot load my independent JS files.
How can I load my JS files, under assets/javascripts/file_name.js and also have my charts working?
Is there a better way to call my JS files, without needing to use script tags?
Application.js:
//= require rails-ujs
//= require activestorage
//= require turbolinks
//= require popper
//= require bootstrap-sprockets
//= require jquery3 #i have this here and not over popper because if it isn't in this position, most of my javascript/jquery features under bootstrap do not work - i haven't figured this out yet. I will most likely use pure jquery/JS and remove all bootstrap JS if I cannot find this reason
//= require Chart.bundle
//= require chartkick
//= require_tree .

Rails 5 JavaScript asset pipeline issue

I'm trying to load some JavaScript in my rails application like so:
Application.html.erb (in the head)
<%= javascript_include_tag 'application' %>
Application.html.erb (before end of HTML)
<script>
$(document).ready(function() {
notie.alert(1, "It Works", 2);
});
</script>
Application.js
//= require rails-ujs
//= require turbolinks
//= require theme/jquery
//= require theme/bootstrap
//= require theme/select2
//= require theme/notie
//= require theme/plugins
//= require theme/app
//= require_tree .
With this set up, I'm getting the following errors:
TypeError: document.body is null
TypeError: notie is undefined
It seems to me that the error may be because of turbolinks and how the JS is loaded with the asset pipeline but for the life of me I can't figure out where it's going wrong. Any help is appreciated.
The problem seems to be that your Javascript is calling for a <body> tag before it exists in the DOM. That's why you're getting the error:
TypeError: document.body is null
For Javascript like that it's best to load it at the bottom of the page instead of the Head.

Rails asset pipeline - add only jquery to head

I have couple of js files and I put them into vendor/assets/js. Then I require them in the application js file as;
//= require jquery
//= require jquery_ujs
//= require dropzone
//= require jquery.cookie
//= require toastr
//VENDOR JS BEGINS
//= require pace/pace.min
//JQuery buraya gelecek sonra
//= require modernizr.custom
//= require jquery-ui/jquery-ui.min
//= require boostrapv3/js/bootstrap.min
//= require jquery/jquery-easy
//= require jquery-unveil/jquery.unveil.min
//= require jquery-bez/jquery.bez.min
//= require jquery-ios-list/jquery.ioslist.min
//= require jquery-actual/jquery.actual.min
//= require jquery-scrollbar/jquery.scrollbar.min
//= require bootstrap-select2/select2.min
//= require switchery/js/switchery.min
//= require imagesloaded/imagesloaded.pkgd.min
//= require jquery-isotope/isotope.pkgd.min
//= require classie/classie
//= require codrops-stepsform/js/stepsForm
//= require bootstrap-datepicker/js/bootstrap-datepicker
//= require bootstrap-datepicker/js/locales/bootstrap-datepicker.tr.js
//= require bootstrap-datepicker/js/locales/bootstrap-datepicker.en.js
//= require summernote/js/summernote.min
//= require moment/moment-with-locales.min
//= require bootstrap-daterangepicker/daterangepicker
//= require bootstrap-timepicker/bootstrap-timepicker.min
//= require codrops-dialogFx/dialogFx
//= require ion-slider/ion.rangeSlider.min
//= require owl-carousel/owl.carousel.min
//VENDOR JS ENDS
at the top of the page I require jquery and jquery_ujs belongs to jquery. Right now, I load the application js files as;
<%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
The thing is, I have couple of js codes inside ..html.erb files, which needs the page loads first. But I would like to merge them in a js file. What I would like to do is call only jquery in the head tag and call application js files in body. But if I remove jquery gem and call it as;
<%= javascript_include_tag 'jquery.min', 'data-turbolinks-track' => true %>
Rails gives an error about jquery_ujs. Ofcourse I can add jquery_ujs there as well. But what is the best practise?
The most rails-esque way to add page specific js code to your rails app (thus avoiding loading js in every page when a library or script is only needed in one page) is to add to the very bottom of your layouts/application.html.erb file right before the closing body tag:
<%= yield :javascript %>
</body>
</html>
Then on the view that you're looking to run some snippets of javascript you should put this at the very bottom of it after all html tags have been closed. Make sure it's not within some divs or anything in that view but at the very bottom of it.
Updated referencing Fred:
<%= content_for :javascript do %>
<script type="text/javascript">
$(document).on('page:load', function() {
all your code here..
});
</script>
<% end %>
This code will now be yielded to the bottom of your layout view only loading on the specific views you need instead of being concatenated along with all other assets in your assets/js folder. I do this with all custom js that isn't application wide and it's very easy to maintain/debug.

Rails - jQuery not working in production with Heroku

I'm deploying a website with Heroku, though really struggling to get the jQuery firing when it goes live. Locally, all works fine.
I've had a play and haven't found any solution - it's all loading in the asset pipeline, shows as a source on the live page (albeit without working) and I've tried all of the solutions I've found on the web.
I've performed rake assets:precompile, have config.assets.compile = true and, thinking it might be a problem due to Turbolinks, installed the jquery-turbolinks gem.
With every change I thought I'd have this running, though nothing has affected the site's behaviour yet. Here's some code:
Gemfile
...
gem 'bootstrap-will_paginate'
gem 'bootstrap-sass'
# Use jquery as the JavaScript library
gem 'jquery-rails'
gem 'jquery-ui-rails'
gem 'jquery-turbolinks'
# Turbolinks makes following links in your web application faster. Read more: https://github.com/rails/turbolinks
gem 'turbolinks'
...
Application.js
...
//= require bootstrap
//= require jquery
//= require jquery.turbolinks
//= require jquery_ujs
//= require jquery-ui
//= require turbolinks
//= require_tree .
...
Application.html.erb
<head>
<link href='http://fonts.googleapis.com/css?family=Slabo+27px' rel='stylesheet' type='text/css'>
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %>
<%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
<%= csrf_meta_tags %>
</head>
Home.js
var validBox = function(x, y){
...
});
};
var main = function(){
$('.toggle').click(function(){
$('.about-me').toggle();
});
//Carosel
$('.arrow-next').click(function(){
...
});
$('.arrow-prev').click(function(){
...
});
//Comments
$('.btn').click(function() {
...
});
$('.status-box').keyup(validBox('.status-box', '.name-box'));
$('.name-box').keyup(validBox('.name-box', '.status-box'));
$('.btn').addClass('disabled');
}
$(document).ready(main);
Could it be a problem with the $(document).ready(main); line? I've a feeling I've read somewhere jQuery doesn't always respond as the page isn't loading from scratch / 'ready' when using Turbolinks, though thought the addition of the relevant Gem would resolve this. I've also tried $(document).on('ready', 'page:change')(main); to run the function at other points, but to no avail.
Alternatively, I seem to remember there being some command line functions to better ensure the assets run when live though can't find anything relevant.
Any help would be GREATLY appreciated as I'm stumped with this one. I'm pretty new to this, so apologies if there are any glaring, amateur errors in amongst this (though that might mean a simple solution!).
Thanks in advance, Steve.
In my case, I found the answer here:
Bootstrap won't detect jQuery 1.11.0 - Uncaught Error: Bootstrap's JavaScript requires jQuery
The Java console was throwing up the error mentioned there, and after lord knows how much hunting, simply changing the order the js files were loaded made the difference.
Bootstrap after jQuery, everything works perfectly!!
//= require jquery
//= require jquery_ujs
//= require bootstrap
//= require turbolinks
//= require_tree .

Rails 3.2.13 Javascript Asset Pipeline

I am working on a Rails 3.2.13 app, and encountering the following problem:
The Javascript files I wrote in the app/assets/javascripts/ directory don't seem to be run.
I have JS code in a file called menu_list.js in the app/assets/javascripts/ directory, but it does not do anything. Whereas when I put the same code on the view page in a tag, it works.
<script>$("#sortable").sortable();</script>
Here's my application.js file:
//= require jquery
//= require jquery_ujs
//= require jquery.purr
//= require jquery-ui
//= require best_in_place
//= require bootstrap
//= require bootstrap-switch
//= require_tree .
my menu_list.js file:
$(function() {
$("#sortable").sortable();
});
It does not make sense to me, as I thought //= require_tree . would include all the javascript files in the directory. I tried other javascript files too, but they don't seem to have any effects.
$("#sortable").sortable();
If this truly is all you have in app/assets/javascripts/menu_list.js it will run as soon as the script is loaded, which is not what you want. You want to run the above code at least after the DOM has fully loaded into the page and not before.
$(function() {
$("#sortable").sortable();
});
If the environment you're running in is :development, and you properly have the following in your layout
<%= javascript_include_tag "application" %>
you will see a separate <script> tag for every Javascript file Sprockets is loading. The //= require_tree . will pick up your app/assets/javascripts/menu_list.js file.
I suggest also making sure you don't have any precompiled version of your assets in place by running the following in shell
rake assets:clean
You can also force debug mode (individual <script> tags for each file) by adding a :debug option to the above include tag
<%= javascript_include_tag "application", debug: true %>
Most common cause for this is that the call to javascript_include_tag that is on the default layout, then you create another layout, forget to add the include there and then nothing works in controllers where you use this new layout.

Categories

Resources