Avoiding repetition of javascript version numbers in Rails manifest file - ruby-on-rails

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.

Related

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

How to load assets in rails

I am new to rails; and I implement a new rails app with front view and admin view. I need to load assets based on the selected view means when I view admin section it only loads admin required assets.
By default rails build a application.js, I created a admin.js and place the code like in application.js and also add my custom assets which are placed in vendor folder but it not loaded any assets
This the code what actually I have
#application.js
//= require jquery
//= require jquery_ujs
//= require turbolinks
//= require morris/morris (custom file placed in vendor folder)
//= require_tree .
#admin.js
//= require jquery
//= require jquery_ujs
//= require turbolinks
//= require morris/morris (custom file placed in vendor folder)
//= require_tree .
The main problem is the custom file is loaded only when loads the application.js file
Sprockets needs to know which files to compile. Add this to config/application.rb:
config.assets.precompile += ['admin.js']

Bootstrap Datepicker gem not formatting in rails

I know this type of question has come up before on SO, and I have tried every solution I could find, but nothing seems to work. The javascript is working fine, but for some reason, I can't get the datepicker window to go in the right spot or format correctly. After testing multiple gems, I keep getting this:
There are no errors in my console. Here is what my related gems look like in my Gemfile:
gem 'jquery-rails', "~> 2.3.0"
gem 'bootstrap-sass'
gem 'bootstrap-datepicker-rails'
And here is my application.js
//= require jquery
//= require jquery_ujs
//= require turbolinks
//= require bootstrap
//= require bootstrap-datepicker
//= require_self
And my application.css has:
*= require bootstrap-datepicker
As for the actual html file, it looks like this (application#index.html)
<input type="text" data-behaviour='datepicker' >
<script type="text/javascript">
$(document).ready(function(){
$('[data-behaviour~=datepicker]').datepicker();
})
</script>
Any and all ideas are welcome.
UPDATE:
It seems like my bootstrap css files aren't loading at all. Do I need to use css.scss files? I can't seem to find a straightforward answer online. Manually inserting the css into my application.css file results in this:
Just for a sanity check give the standard jquery datepicker a shot. I generally use it with bootstrap.
app/assets/javascripts/application.js
//= require jquery
//= require jquery_ujs
//= require twitter/bootstrap
//= require jquery.ui.datepicker
//= require jquery.timepicker.js
//= require_tree .
app/assets/stylesheets/application.css
*= require jquery.ui.datepicker
*= require jquery.timepicker.css
*= require_self
*= require_tree .
app/assets/javascripts/your_model.js.coffee
jQuery ->
$("#div_id_here").datepicker dateFormat: "yy-mm-dd"
Since you're using bootstrap-sass, you can (and should) use #import statements instead of *= require statements for your css.scss files. This allows you to define and use variables, etc amongst all of your css.scss files, which allows for full customization of Bootstrap and its components. I'm not sure if there could be something else wrong with your configuration... but I'd suggest starting here anyway since none of your css is showing up. So your application.css.scss file would look like:
# #import any file that may contain variables you'd like to use in any libraries
# added below this point (e.g. `defines.css.css`)
#import "bootstrap_and_overrides";
#import "bootstrap-datepicker";
# #import "whatever other .css.scss files you have...";
Then in bootstrap.css.scss you'd individually import each of the desired bootstrap CSS components after "overriding" any variables. Here is what you need to start from:
variables (this is the basis your variable/style "overrides", placed at the tope of your bootstrap_and_overrides.css.scss file.)
bootstrap components (this is the core of your bootstrap_and_overrides.css.scss file.)

Twitter Bootstrap Rails Datetime picker

I would like to include the following datetime picker in my rails application.
http://www.malot.fr/bootstrap-datetimepicker/
I am using twitter bootstrap for rails, but can't get it to work.
I tried adding the .js file to the assets/javascripts directory and using //= require to include it in the application.js file.
The files are loading on the page, but I'm getting a response that
Uncaught TypeError: Object [object Object] has no method 'datetimepicker'
Any ideas? I've reverted all of my changes, so can start again from scratch.
application.js
//= require jquery
//= require jquery_ujs
//= require twitter/bootstrap
//= require bootstrap
//= require_tree .
I think the problem happened at //=require_tree. Yes you added that plugin but the plugin is loaded after your custom js which have method to call the plugin. That's why "Object has no method 'datetimepicker'".
I would suggest you to:
Move the plugin into vendor/assets/javascripts/. This is a better place for third party libs.
require the plugin explicitly in application, after bootstrap(it depends on bootstrap's dropdown. Like
//= require bootstrap
//= require datetime_picker_js_file_name
//= require_tree .
Side notes:
I don't quite know why there are two bootstrap js files required. Are they duplicate?
Besides, I would recommend to require Bootstrap js files only on need, like
//= require bootstrap-dropdown
//= require bootstrap-alert

Extending bootstrap typeahead with bootstrap-sass

I'm creating a rails site using the bootstrap-sass gem and it works fine.
I'm also successfully initializing the typeahead on my js.erb:
$container.find('.typeahead').typeahead({source: [<%= #cities %>], items:20});
But now I want to use an extended version of typeahead that uses an array of kvp objects instead of strings. This one from tcrosen seems just fine.
I added their bootstrap-typeahead.js to app/assests/javascripts folder. Changed the application.js to include that file:
...
//= require jquery
//= require jquery_ujs
//= require bootstrap
//= require bootstrap-typeahead
//= require_tree .
But it seems that he's using the typeahead function defined on bootstrap.min.js instead of the new one.
How can I point him to use the right file?
ps: I'm using other bootstrap javascripts plugins so I can't just delete bootstrap.min.js
Instead of specifying the global file
//= require bootstrap
you can separately require them :
//= require bootstrap-affix
//= require bootstrap-alert
//= require bootstrap-button
//= require bootstrap-carousel
//= require bootstrap-collapse
//= require bootstrap-dropdown
//= require bootstrap-modal
//= require bootstrap-scrollspy
//= require bootstrap-tab
//= require bootstrap-tooltip
//= require bootstrap-transition
and so don't include the last one //= require bootstrap-typeahead. With that you can require the bootstrap-typeahead javascript file from tcrosen (putting in your asset javascript directory and require it, but don't forget to rename it also, otherwise the old bootstrap typeahead will be use). Tested with bootstrap-sass and tcrosen/twitter-bootstrap-typeahead.

Resources