how to use js files from Gem in rails 6 application - ruby-on-rails

So I have been using rails for quite a while. But with Rails 6 I have been really struggling to get moving. I have some custom gems I use for assets and things and I cannot figure out how to load the js files.
What I am used to
application.js
//= require activestorage
//= require jquery-3.3.1.min
//= require popper.min
//= require bootstrap
//= require mdb
//= require wysiwyg
//= require addons/pickr.min
//= require modules/buttons
//= require modules/cards
//= require modules/waves
//= require activestorage
//= require turbolinks
//= require_tree .
But this does not load in Rails 6 with Webpacker. I was unable to find a basic solution online for this that did not involve adding multiple js files and lines of code to the app to patch a solution together. What I did try was
app/javascript/packs/application.js
require("#rails/ujs").start()
require("turbolinks").start()
require ("jquery-3.3.1.min").start()
require ("popper.min").start()
require ("bootstrap").start()
require ("mdb").start()
require ("wysiwyg").start()
require ("addons/pickr.min").start()
require ("modules/buttons").start()
require ("modules/cards").start()
require ("modules/waves").start()
require("#rails/activestorage").start()
require("channels")
The assets are in the correct place inside the gem (so the first version in a rails 5 app does load everything as expected). I can add some of these with yarn, but I want to use the actual files from the gem, not just get bootstrap working, is there a straightforward solution to this? I also tried adjusting the path in the require but that did not work either.
Thanks for any help!

You need to import js files via gem. Maybe this can help you:
import jQuery from 'jquery'
<%= File.read(File.join(Gem.loaded_specs['bla_bla_gem'].full_gem_path, 'lib', 'assets', 'javascripts', 'bla_bla.js')) %>
Related issue comment

So to answer in rails 6 you will notice the use of the javascript folder app/javascript this means that anything you do with JS should be done from there. The reliance on gems for these is now minimal and replaced by yarn.
I will give you an example of my process for using js libraries. for the example i will call bootstrap using yarn. I have included the custom files to help you call each library.
this is a process I like to use which I have modified from something i read on medium a while back
# app/javascript/packs/application.js
import '../stylesheets/application'
# app/views/layouts/application.html.erb
<%= stylesheet_pack_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
<%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
in the console run
yarn add bootstrap#4.3.1 jquery popper.js
then
# config/webpack/environment.js
...
const webpack = require('webpack')
environment.plugins.append(
'Provide',
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
Popper: ['popper.js', 'default']
})
)
...
then
# app/javascript/packs/bootstrap_custom.js
import 'bootstrap/js/dist/alert'
import 'bootstrap/js/dist/button'
import 'bootstrap/js/dist/carousel'
import 'bootstrap/js/dist/collapse'
import 'bootstrap/js/dist/dropdown'
import 'bootstrap/js/dist/index'
import 'bootstrap/js/dist/modal'
import 'bootstrap/js/dist/popover'
import 'bootstrap/js/dist/scrollspy'
import 'bootstrap/js/dist/tab'
import 'bootstrap/js/dist/toast'
import 'bootstrap/js/dist/tooltip'
import 'bootstrap/js/dist/util'
And link it in your app/javascript/packs/application.js file.
# app/javascript/packs/application.js
import './bootstrap_custom.js'
then
# app/javascript/stylesheets/application.scss
#import './bootstrap_custom.scss'
then
# app/javascript/stylesheets/bootstrap_custom.scss
#import '~bootstrap/scss/_functions.scss';
#import '~bootstrap/scss/_variables.scss';
#import '~bootstrap/scss/_mixins.scss';
#import '~bootstrap/scss/_root.scss';
#import '~bootstrap/scss/_reboot.scss';
#import '~bootstrap/scss/_type.scss';
#import '~bootstrap/scss/_alert.scss';
#import '~bootstrap/scss/_badge';
#import '~bootstrap/scss/_breadcrumb';
#import '~bootstrap/scss/_button-group';
#import '~bootstrap/scss/_buttons';
#import '~bootstrap/scss/_buttons.scss';
#import '~bootstrap/scss/_card.scss';
#import '~bootstrap/scss/_carousel.scss';
#import '~bootstrap/scss/_close.scss';
#import '~bootstrap/scss/_code.scss';
#import '~bootstrap/scss/_custom-forms.scss';
#import '~bootstrap/scss/_dropdown.scss';
#import '~bootstrap/scss/_forms.scss';
#import '~bootstrap/scss/_grid.scss';
#import '~bootstrap/scss/_images.scss';
#import '~bootstrap/scss/_input-group.scss';
#import '~bootstrap/scss/_jumbotron.scss';
#import '~bootstrap/scss/_list-group.scss';
#import '~bootstrap/scss/_media.scss';
#import '~bootstrap/scss/_modal.scss';
#import '~bootstrap/scss/_nav.scss';
#import '~bootstrap/scss/_navbar.scss';
#import '~bootstrap/scss/_pagination.scss';
#import '~bootstrap/scss/_popover.scss';
#import '~bootstrap/scss/_print.scss';
#import '~bootstrap/scss/_progress.scss';
#import '~bootstrap/scss/_spinners.scss';
#import '~bootstrap/scss/_tables.scss';
#import '~bootstrap/scss/_toasts.scss';
#import '~bootstrap/scss/_tooltip.scss';
#import '~bootstrap/scss/_transitions.scss';
#import '~bootstrap/scss/_utilities.scss';
If you choose to follow this follow it precisely, do not change the scss lines etc it will mess it up

You'll need to get them directly from the gem files.
Change your application.js to application.js.erb and follow demir solution. You can also use the next to import more than one file.
<% ['file_1', 'file_2'].each do |file| %>
import "<%= File.join(Gem.loaded_specs['my_gem'].full_gem_path, 'app', 'assets', 'javascripts', file) %>";
<% end %>

I think the location of file may be creating an issue for your case:
File should be in app/assets/javascripts/application.js while the your file is in
app/javascript/packs/application.js
Hope this will help you.

Related

how to implement jQuery Datepicker into Rails 5.1 app

I'm trying to implement jQuery Datepicker into my Rails 5.1.3 app, but I get this error message:
ActionView::Template::Error at /users/2/absences/new File to import
not found or unreadable: jquery-ui/widgets/datepicker. Load paths:
/Users/acandael/Sites/absence_registrator/app/assets/config
/Users/acandael/Sites/absence_registrator/app/assets/images
/Users/acandael/Sites/absence_registrator/app/assets/javascripts
/Users/acandael/Sites/absence_registrator/app/assets/stylesheets
I have added the jquery-ui-rails gem to the Gemfile
Then I configured the app/assets/javascripts/application.js file:
//= require jquery-ui/widgets/datepicker
and I also configured the app/assets/stylesheets/application.scss file:
#import "jquery-ui/widgets/datepicker";
finaly I configured the Datepicker in the view template:
<%= f.text_field :date, class: "form-control", id: "datepicker" %>
<script>
$(function() {
$( "#datepicker" ).datepicker();
});
</script>
Update
I made some progress by changing
//= require jquery-ui/widgets/datepicker
to
//= require jquery-ui/datepicker
in app/assets/javascripts/application.js
In app/assets/stylesheets/application.scss
I changed
#import "jquery-ui/widgets/datepicker";
to
/*
*= require jquery-ui/datepicker
*/
but the Datepicker that appears is not styled.
So my question now is how implement css styling for the Datepicker
Update
I fixed the styling issue by importing:
#import 'jquery-ui/datepicker.css';
into app/assets/stylesheets/application.scss
Thanks for your help,
Anthony
I tried your approach and several others. They all error'd out or didn't show the JS control where they should.
Ultimately I used this gem instead, and followed their pretty simple instructions and success! Rail 5.0.6.
https://github.com/TrevorS/bootstrap3-datetimepicker-rails

Rails: Font awesome icons not showing using font-awesome-rails gem

I can't seem to find an answer that works for me.
The icon shows up as a box: 
I'm using:
font-awesome-rails (4.6.2.0)
rails (4.2.3)
I imported font-awesome-rails in my application.scss file using:
#import "font-awesome";
and here is what I wrote for the view:
<i class="quote-left fa fa-quote-left"></i>
I've tried including it before and after bootstrap.
I also tried manually adding the font folder to the pipeline in application.rb
config.assets.paths << Rails.root.join("app", "assets", "fonts")
Clearing the tmp folder didn't seem to do anything either.
I spent way too much time on this, please help :(
I had this issue when working with Rails 6 and Bootstrap 4 in Ubuntu 20.04.
I had set up Fontawesome this way:
First I added Font Awesome to my package.json file:
yarn add #fortawesome/fontawesome-free
Next, I imported it into my app/javascript/packs/application.js file:
require("#fortawesome/fontawesome-free")
Next, I imported it into my app/assets/stylesheets/application.scss file:
$fa-font-path: '#fortawesome/fontawesome-free/webfonts';
#import '#fortawesome/fontawesome-free/scss/fontawesome';
#import '#fortawesome/fontawesome-free/scss/brands';
#import '#fortawesome/fontawesome-free/scss/solid';
#import '#fortawesome/fontawesome-free/scss/regular';
#import '#fortawesome/fontawesome-free/scss/v4-shims';
I also added the Font Awesome 5 Rails gem to my Gemfile:
gem 'font_awesome5_rails'
and installed it in my project:
bundle install
And finally I modified where my fontawesome icons were called from this format:
<i class="fas fa-camera-retro"></i>
to this format
fa_icon('camera-retro')
But the issue was that the icons were displaying fine in development but not in production.
Here's how I fixed it:
The issue was that I needed to import the FontAwesome 5 fonts into the app/assets/stylesheets/application.scss file. So I imported this to it:
#import 'font_awesome5_webfont';
So my fontawesome import to the app/assets/stylesheets/application.scss file looked like this finally:
#import 'font_awesome5_webfont';
$fa-font-path: '#fortawesome/fontawesome-free/webfonts';
#import '#fortawesome/fontawesome-free/scss/fontawesome';
#import '#fortawesome/fontawesome-free/scss/brands';
#import '#fortawesome/fontawesome-free/scss/solid';
#import '#fortawesome/fontawesome-free/scss/regular';
#import '#fortawesome/fontawesome-free/scss/v4-shims';
This time the icons displayed properly in development as well as production.
Note: Please ensure to re-compile your assets after making these changes and restart your server.
That's all.
I hope this helps
I moved my import of font-awesome below my font import and it solved it.
from this:
#import "font-awesome";
#import url("https://fonts.googleapis.com/css?family=Playfair+Display:700,900");
to this:
#import url("https://fonts.googleapis.com/css?family=Playfair+Display:700,900");
#import "font-awesome";
Try restarting your webserver, after adding #import 'font-awesome.css' to your application.scss.
Also read these, if you haven't yet,
https://github.com/bokmann/font-awesome-rails/issues/130#issuecomment-95308175
https://github.com/bokmann/font-awesome-rails/issues?q=is%3Aissue+is%3Aclosed
I solved this issue by explicitly declaring a font-family: FontAwesome; rule in my stylesheet because a global * style was overwriting the font-family attribute for the .fa class.

How to configure bootstrap-sass on rails

I'm building a Rails application and I decided to use bootstrap and sass.
I follow the guide on the github page:
https://github.com/twbs/bootstrap-sass
So, now i have my gem installed ('bootstrap-sass', 'sass-rails'), my application.css (now application.sass) looks like this:
1 #import "bootstrap-sprockets";
2 #import "bootstrap";
My application.js file looks like this:
1 // This is a manifest file that'll be compiled into application.js, which will include all the files
2 // listed below.
3 //
4 // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
5 // or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
6 //
7 // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
8 // compiled file.
9 //
10 // Read Sprockets README (https://github.com/sstephenson/sprockets#sprockets-directives) for details
11 // about supported directives.
12 //
13 //= require jquery
14 //= require jquery_ujs
15 //= require turbolinks
16 //= require bootstrap-sprockets
17 //= require_tree .
And then the guide pretty much ends.
The problem is that I don't have bootstrap in my application(I can't see it anywhere in the page by viewing the source) and I do not know how to use sass.
What should I do next? Did I miss something?
It sounds like it should all be ready to go but you will have to start writing some code that it can apply. Perhaps test it with this. In your application.html.erb file under body put the following:
<div id="container">
<div class="main">
<h1>Main Content</h1>
</div>
then in the css file try this
#container {
.main {
width:600px;
h1 {
color: $red;
}
}
Make sure you have restarted your server after the bundle install.
The list of bootstrap variables can be found here http://getbootstrap.com/customize/#less-variables
I found the error: I wrote all the import tag between the html
<title>
tag instead of the
<head>
tag.

Why do I get an undefined Foundation variable error in this SASS file?

I have a Rails 4 app, using the foundation-rails v5.2.1.0 gem, and one custom SCSS file for my application layout. When I use a variable from the foundation_and_overrides.scss file, I get the following error:
Undefined variable: "$header-font-family"
I've included relevant code below. I can post more if needed. Anyone know what's going on here?
From application.css:
*
*= require foundation_and_overrides
*= require_self
*= require_tree .
*/
From foundation_and_overrides.scss:
// We use these to control header font styles
$header-font-family: "futura-pt", sans-serif;
$header-font-weight: 400;
// $header-font-style: normal;
From custom.css.scss:
$include-html-global-classes: false;
#import "foundation/components/global";
.
.
.
.footer {
background-color: black;
color: white;
height: 100px;
font-family: $header-font-family;
}
You are getting the error because foundation_and_overrides.scss is executing after custom.css.scss. Best way to do this is to define your variables in a partial and import it in your main stylesheet after foundation.
First change the file name from
foundation_and_overrides.scss to _foundation_and_overrides.scss
and then import it in custom.css.scss file after foundation with
#import 'foundation_and_overrides';
Update
Rename your application.css to application.css.scss and custom.css.scss to custom.scss
In your application.css.scss remove *= require_tree .
And then import your main stylesheet with
#import 'custom'
I hope this helps
The cleanest way is to add the line
#import "custom";
to your file foundation_and_overrides.scss before the line
#import "foundation";
There's no need to remove *= require_tree . from application.css.scss as stated in the accepted answer. There's also no need to add require foundation_and_overrides to application.css if you leave require_tree . in there.
According to the Rails Docs:
If you want to use multiple Sass files, you should generally use the Sass >#import rule instead of these Sprockets directives. When using Sprockets >directives, Sass files exist within their own scope, making variables or >mixins only available within the document they were defined in.
So in this case the order of the directives (the lines in application.css that start with *=) doesn't matter because each of those files lives in its own scope and you can't access their variables from another scss file. That's why you want to either #import foundation_and_overrides and then custom, or #import your custom stylesheet into foundation_and_overrides.

can't add a stylesheet with sass to a rails project

I'm using the bootstrap-sass gem. With these instructions https://github.com/twbs/bootstrap-sass#usage Things work ok except when I want to add a new stylesheet.
application.css.scss
#import "bourbon";
#import "custom";
#import "users";
#import "font-awesome";
#import "comments";
#import "animations";
directory structure
▾ stylesheets/
animations.css
application.css.scss
classifieds.css.scss
comments.css.scss
custom.css.scss
foo.css.scss
news.css.scss
relationships.css.scss
scaffolds.css.scss
users.css.scss
But if I add foo.css.scss to /stylesheets/ and add #import 'foo' to application.css.scss
I get a wrong number of arguments (2 for 1)
(in app/assets/stylesheets/application.css.scss) error
What could I be doing wrong?
it seems sass gem changed number of arguments of Sass::Importers::Base#public_url.
New version of sass-rails-source-maps should resolve this.

Resources