wrong assets loaded rendering application layout - ruby-on-rails

I have a kind of strange problem with assets.
In application.html.erb trying to include controller specific assets this way
<%= javascript_include_tag "application", params[:controller] %>
application.js looks like this:
//= require jquery
//= require jquery_ujs
//= require twitter/bootstrap
//= require leaflet
//= require select2
//= require_tree ./general
//= require turbolinks
General folder contains some common JS files. Application uses 2 controllers: Index and Profiles (root route is "index#index"). At some moment Rails starts to load assets in wrong way: on index page profiles.js are loaded and index.js on /profiles/new. This problem only appears when I press index or create profile links in navbar. No problems seems to be opening this pages in separated tabs or just reloading page using Ctrl+R. So I assume that it's some turbolinks problem?

Related

Rails 5 assets pipeline not working as expected (Development)

am adding all my .js and .css files to precompile like this
Rails.application.config.assets.precompile = ['*.js', 'application.scss', '*.scss', '*.css.erb']
And including application.js in layout head section like this
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
<%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
even though some of the , js files not available at my views. I have a file called image-picker.js in that directory. which make a .imagepicker() function available at my views but it's throwing an error like this
Uncaught TypeError: $(...).imagepicker is not a function
But when i include that .js file for the page specifically using
<%= javascript_include_tag "image-picker" %>
it's working as expected. Why this is happening. Do I need to set anything else in the configuration? How to avoid including my assets at each page view??
Update
// 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, or any plugin's
// vendor/assets/javascripts directory 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. JavaScript code in this file should be added after the last require_* statement.
//
// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
// about supported directives.
//= require jquery
//= require jquery_ujs
//= require jquery-ui
//= require image-picker.js #tried but not working.
//= require_tree .
Update2
am using jquery-rails - 4.3.1 and jquery-ui-rails 6.0.1
which adding jquery-2.1.4.min.js to my assets. But when i use //= require jquery i think it's not including jquery to app.
When i tried adding it manually everything works properly,
//= require jquery
//= require jquery_ujs
//= require jquery-ui
//= require jquery-2.1.4.min #now everything working fine. it seems a dependency problem.
//= require image-picker.js #tried but not working.
//= require_tree .
I would like to know what is the reason for this. thanks.
Very similar question you can find - here
try to add image-picker.js in application.js
//= require jquery
//= require jquery_ujs
//= require jquery-ui
//= require image-picker
//= require_tree .

With Rails 4.2, how to load JavaScript specific to one ControllerMethod Articles#New

Currently, my application.js file includes:
//= require jquery
//= require tether
//= require bootstrap-sprockets
//= require jquery_ujs
//= require turbolinks
//= require ckeditor/init
//= require_tree .
The problem is ckeditor is being loaded on every page when I only need it on one admin like view Articles#New.
What is the correct way in Rails 4.2, to make ckeditor's JS only load on the Articles#New view?
Please follow some steps
Remove from application.js //= require ckeditor/init
at page articles/new.html.erb add following line
javascript_include_tag "ckeditor/init"
in config/initializers/assets.rb add following lines
Rails.application.config.assets.precompile += %w( ckeditor/* )
I think #Vijay's answer is exactly the right one.
The config.js not found problem is another problem. The url is probably hard coded in the init.js, because "ckeditor/config.js" seems not like normal precompiled filename which usually looks like config-7efjsdhfduey44xxxxxx.js.
The assets/ dir only has precompiled files in production so the config.js is not found.
You can:
change init.js to init.js.erb
change every path it uses in the file to "asset_path", ex:
'config.js to <%= asset_path 'ckeditor/config.js' %>
do 1,2 for every file under ckeditor/
When using Sprocket in production, the right filename is important.
or you can just include the ckeditor from CDN and forget all about this j/k

Where to put javascript that you don't always want to load?

I'm using RoR and jquery.ui.addresspicker.js
This jquery.ui.addresspicker.js requires that google is loaded before that library is loaded. I only need the addresspicker on a couple of pages in the application.
The google part that needs to be loaded before is this:
<script src="http://maps.google.com/maps/api/js?sensor=false"></script>
But this makes the page load slower so I don't want this on all my pages.
The application.js contains this:
//= require jquery
//= require jquery_ujs
//= require jquery.ui.all
//= require jquery.blockUI
//= require select2
//= require cocoon
//= require_tree .
Currently the jquery.ui.addresspicker.js file is in app/assets/javascripts and thus also loaded automatically all the time.
How can I handle this? Should I move the addresspicker.js out of the javascripts directory? Should I rewrite my application.js? Other suggestions?
You can replace
//= require_tree .
with an explicit list of the javascripts that you want included on each page. and just include jquery.ui.addresspicker on the pages that you need it.
I used Ian's idea to change the application.js
I created a new folder named sitewide and copied all the javascripts in there that I want to use on the whole site (so not the addresspicker).
I changed application.js like this:
//= require_tree ./sitewide
And in the page where I needed the addresspicker I put it using javascript_include_tag
This way I don't need to change the application.js file everytime I want to add a js file.
use a different layout on both pages or just remove the jquery.ui.addresspicker.js from the default_layout and just include in the pages where you need it
<%= include_javascripts "jquery.ui.addresspicker" %> or
javascript_include_tag "jquery.ui.addresspicker"
in the page where you need

Rails 3: Twitter-Bootstrap Tooltips Refuse to Work

This is driving me absolutely bonkers, and it seems like such a simple thing to implement. I can't get tooltips (or, for that matter, popovers) to work. I have the 'twitter-bootstrap-rails' gem installed, and I generated the appropriate .js and .css files.
I don't think it's a JQuery issue because I have other JQuery functionality on my site that works perfectly.
Here's some relevant code.
application.js
//= require jquery
//= require jquery_ujs
//= require twitter/bootstrap
//= require bootstrap-tooltip
//= require bootstrap-popover
//= require prototype
//= require prototype_ujs
//= require effects
//= require dragdrop
//= require controls
//= require_tree .
$('a').tooltip();
application.css
*= require_self
*= require_tree .
*= reqire_twitter/bootstrap
Code I'd like to get to work for tooltips
test
The above code, when hovered over, just shows Chrome's normal tooltip. I'm getting the same behavior in Safari, so I doubt it's browser-specific.
I'm using Rails 3.2.7, adding Bootstrap manually. Everything works just fine.
application.css
*= require style
*= require bootstrap.min
*= require bootstrap-responsive.min
*= require_tree .
application.js
//= require jquery
//= require jquery_ujs
//= require bootstrap.min
$(document).ready(function(){
$('a').tooltip();
});
//= require_tree .
and layout/application.html.erb
<head>
<%= stylesheet_link_tag("application", :media => "all") %>
</head>
<body>
<%= yield %>
<!-- scripts concatenated and minified via build script -->
<%= javascript_include_tag "application" %>
<!-- end scripts -->
</body>
</html>
Your application.js code will be executed before your web page is fully loaded into the browser, so your line of code will not find any element prior to the page load.
You will need to execute when the DOM is fully loaded:
$(document).ready(function () {
$('a').tooltip();
});
The solution to this was two-fold.
Change the $ in the code to jQuery. This got rid of the "Object # has no method 'ready'" error.
I had a bootstrap.js.coffee file that had irrelevant code. When I deleted the file, everything began working again. This got rid of the "Uncaught TypeError: Cannot call method 'tooltip' of null" error.
After much fighting, in order to get it working properly with Rails 3.2 I had to do the following:
in application.js:
//= require bootstrap
in the view template where I want the tooltip, include the rel='tooltip' attribute:
= link_to "Link text", title: 'Click to reveal tracks', 'data-placement' => 'top', rel: :tooltip
or if you're not using HAML:
Link text
in any of the coffeescript files (I created a new one) put this:
jQuery ->
$('[rel="tooltip"]').tooltip()
This works, though the styling for the tooltips are not working, I can't figure out why, but the javascript seems to be working at least.
Hopefully this will help someome else.
As someone commented already, bootstrap-sass includes a coffeescript file which has this in it:
jQuery ->
$("a[rel=popover]").popover()
$(".tooltip").tooltip()
$("a[rel=tooltip]").tooltip()
If you call this file there is no need to include the other coffeescript file above since this one does the same thing. In my case I already have bootstrap.js called from application.js so this one wasn't called (I removed require_tree so I can call the files I want in the order I want).

Avoiding repetition of javascript version numbers in Rails manifest file

We require a number of different manifest files in order to only serve up the appropriate JS files for various functional areas of our site, however I'm currently having to replicate the JS file name and version number in each file so our manifests look like:
libs.js
//= require json2
//= require underscore-1.3.1
//= require jquery
//= require jquery-ui-1.8.17.custom.min
//= require jquery_ujs
//= require farbtastic-1.3u.gizmos
//= require bootstrap-2.0.1
//= require highstock-1.1.4.src
//= require exporting-1.1.4.src
//= require modernizr-2.5.3
//= require application
//= require validation
//= require navigation
//= require styles
libs-embedded.js
//= require json2
//= require jquery
//= require highstock-1.1.4.src
//= require exporting-1.1.4.src
I've tried to fix this by changing these manifest files with these .js.erb equivalents:
libs.js
<%= ManifestHelper.require_json2%>
<%= ManifestHelper.require_underscore%>
<%= ManifestHelper.require_jquery%>
<%= ManifestHelper.require_jquery_ui%>
<%= ManifestHelper.require_jquery_ujs%>
<%= ManifestHelper.require_farbtastic%>
<%= ManifestHelper.require_bootstrap%>
<%= ManifestHelper.require_highstock%>
<%= ManifestHelper.require_exporting%>
<%= ManifestHelper.require_modernizr%>
<%= ManifestHelper.require_application%>
<%= ManifestHelper.require_validation%>
<%= ManifestHelper.require_navigation%>
<%= ManifestHelper.require_styles%>
libs-embedded.js
<%= ManifestHelper.require_json2%>
<%= ManifestHelper.require_jquery%>
<%= ManifestHelper.require_highstock%>
<%= ManifestHelper.require_exporting%>
The ManifestHelper class includes methods such as:
def self.require_underscore
'//= require underscore-1.3.1'
end
This is intended to allow me to manage the JS file and version numbers in one place even though they are used in many manifest files.
However, when I try to do this, my libs.js files looks like:
//= require json2
//= require underscore-1.3.1
//= require jquery
//= require jquery-ui-1.8.17.custom.min
//= require jquery_ujs
//= require farbtastic-1.3u.gizmos
//= require bootstrap-2.0.1
//= require highstock-1.1.4
//= require exporting-1.1.4
//= require modernizr-2.5.3
//= require application
//= require validation
//= require styles
//= require navigation;
There are two problems with this. Firstly a semicolon is introduced for some reason. The second is that the generated .js file is not being populated with the concatenated js files defined in the //= requires directives.... It appears that although the .erb substitution is happening in the .js.erb file, it appears to be happening after the manifest file has read through the directives.
My question is... Can anyone suggest a way to fix this problem or suggest an alternate solution for me to stop replicating the js file and version numbers in each of my manifests...
Thanks,
Ian
One possible workaround would be to move shared javascript files into a "shared" subdirectory, then from your manifest file, use the require_directory directive to pull in the shared files.
//= require_directory shared
One bonus of this method is that you only have to drop a javascript file into the "shared" directory for it to be available for all the parent manifests that have the require_directory statement. No updating manifests or helper files.
Only potential issue there is that you can't control the order of the loading of the shared files if you have load order dependencies for those files. But that can be sorted out with a little more effort using an index manifest in the subdirectory to statically list the order of the files, then point to the index manifest from the parent manifest.
We managed to use this problem by using gems that wrap up the javascript libraries, for example we've been using the following gems:
gem 'jquery-rails'
gem 'jquery-ui-rails'
gem 'twitter-bootstrap-rails'
gem 'select2-rails'
gem 'underscore-rails'
gem 'underscore-string-rails'
This then allows you to include the relevant javascript library in your manifest using just the name of the library. For example: //= require select2 instead of //= require select2-x.y.z
Obviously the gems do many good things like managing the asset pipeline integration but we didn't have the library version numbers all over the place which I liked.

Resources