Rails 5 JavaScript asset pipeline issue - javascript

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.

Related

Can't assign jQuery result to a variable

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

rails: assets js manifest not picking up specific js file

I can't get my prints.js file to get picked up by the manifest (I presume that is the issue.)
this is in the appliction.js manifest:
//= require jquery
//= require jquery_ujs
//= require bootstrap
//= require turbolinks
//= require 'main'
//= require 'cards'
//= require 'prints'
//= require_tree .
the cards.js has a console log saying hello like this :
$(document).on('turbolinks:load', function() {
console.log('cards js file executed.')
...
});
When I do the same thing for cards.js like this:
$(document).on('turbolinks:load', function() {
console.log('Prints js file executed.');
});
the console only calls out the cards.js console log statement, but not prints.
I restarted rails server, and rebooted my local machine hoping that would pick it up. but no result.
(Rails 4.2)
EDIT
I am decided to use the application.js for hosting the function I need.
Though it works, it feels 'cheap' and if anybody has any suggestions of what could make a manifest not include files, that would be greatly appreciated. But I have a temporary solution.
try without quote like following. after change please restart server
//= require main
//= require cards
//= require prints

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-autocomplete Uncaught TypeError

I'm trying to use the rails-jquery-autocomplete gem but can't seem to get it working.
At first I thought it was the order that I was requiring it in the application.js but based on other posts on SO, I don't think this is the case. Here is that code anyway:
//= require jquery
//= require jquery_ujs
//= require autocomplete-rails
// require turbolinks
//= require bootstrap-sprockets
//= require bootstrap
//= require ckeditor/init
//= require social-share-button
//= require questions
// require_tree .
The error I am getting for it at the moment is:
Uncaught TypeError: undefined is not a function autocomplete-rails-81b10cb822d78b60a1415bace9e9714b.js?body=1:1
t.railsAutocomplete.fn.extend.initautocomplete-rails-81b10cb822d78b60a1415bace9e9714b.js?body=1:1
t.railsAutocompleteautocomplete-rails-81b10cb822d78b60a1415bace9e9714b.js?body=1:1
t.fn.railsAutocomplete.ejquery-87424c3c19e96d4fb033c10ebe21ec40.js?body=1:4666
jQuery.event.dispatchjquery-87424c3c19e96d4fb033c10ebe21ec40.js?body=1:4334
jQuery.event.add.elemData.handlejquery-87424c3c19e96d4fb033c10ebe21ec40.js?body=1:4575
jQuery.event.triggerjquery-87424c3c19e96d4fb033c10ebe21ec40.js?body=1:4902
jQuery.event.simulatejquery-87424c3c19e96d4fb033c10ebe21ec40.js?body=1:5165
jQuery.each.handler
Any ideas why it's not recognising it?
Thanks
first, have you run rails generate autocomplete:install in your project root?
Also you should include autocomplete-rails after jquery-ui which seems to be missing.
javascripts/application.js
//= require jquery
//= require jquery_ujs
//= require jquery-ui
//= require autocomplete-rails
....
If that does not help put this in the head of your application.haml/html:
layouts/application.html
....
javascript_include_tag "autocomplete-rails.js"
....
The Doc is quite clear on what you have to do, to get up and running. Good luck

Rails production: javascript not working

Recently I've got strange error on Rails production - some javascripts not working. Locally there is no problem - everything works perfectly, but production.
my application.js
//= require jquery
//= require jquery_ujs
//= require twitter/bootstrap
//= require moment
//= require bootstrap-datetimepicker
//= require pickers
//= require cocoon
//= require jquery.minicolors
//= require widget
//= require highcharts/highcharts
//= require highcharts/highcharts-more
//= require highcharts/highstock
//= require_tree .
scripts that not working - jquery.minicolors and widget(coffescript).
I've tried to add these scripts to
config.assets.precompile += %w( widget.js.coffee jquery.minicolors.js )
in production.rb, but that's doesn't work too
It's strange but if I remove
//= require highcharts/highcharts
//= require highcharts/highcharts-more
//= require highcharts/highstock
from application.js the rest scripts work fine
I understand this issue has been closed but I actually had the same issue recently. I fixed it by wrapping my jQuery code inside the following;
$(document).ready(
(custom JS goes here)
)
If you (or anyone in the future) has the same issue, I'd say it's cause of how Rails loads CSS/HTML and jQuery. Apparently jQuery is loaded as the head in a Rails app so it's loaded but can't be accessed after it's been loaded.
I've found a solution with help of question
I removed from application.js
//= require highcharts/highcharts
//= require highcharts/highcharts-more
and keep only
//= require highcharts/highstock
highstock.js keeps in /vendor/assets/javascripts and contains necessary scripts for highcharts working

Categories

Resources