SCSS Not Rendering - Agile Web Development With Rails 4 (Book) - ruby-on-rails

I've copied the raw text files from the book for the tutorial that I'm working on, and the css is not being applied and I can't figure out why. The HTML content displays correctly though. Perhaps you will need more information from me that I'm unaware of at the moment, but I'm glad to bring it to the table if need be.
application.html.erb
<!DOCTYPE html>
<html>
<head>
<title>Depot</title>
<%= stylesheet_link_tag "application", media: "all",
"data-turbolinks-track" => true %>
<%= javascript_include_tag "application", "data-turbolinks-track" => true %>
<%= csrf_meta_tags %>
</head>
<!-- START_HIGHLIGHT -->
<body class='<%= controller.controller_name %>'>
<!-- END_HIGHLIGHT -->
<%= yield %>
</body>
</html>
products.css.scss
// Place all the styles related to the Products controller here.
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: http://sass-lang.com/
/* START_HIGHLIGHT */
.products {
table {
border-collapse: collapse;
}
table tr td {
padding: 5px;
vertical-align: top;
}
.list_image {
width: 60px;
height: 70px;
}
.list_description {
width: 60%;
dl {
margin: 0;
}
dt {
color: #244;
font-weight: bold;
font-size: larger;
}
dd {
margin: 0;
}
}
.list_actions {
font-size: x-small;
text-align: right;
padding-left: 1em;
}
.list_line_even {
background: #e0f8f8;
}
.list_line_odd {
background: #f8b0f8;
}
}
/* END_HIGHLIGHT */

Error
You fixed it - congrats!!
Something you may wish to consider is using SASS instead of SCSS. You only need to change the extension of your file to .css.sass - allowing you to get rid of a lot of superfluous brackets in SCSS:
#app/assets/stylesheets/application.css.sass
.products
table
border:
collapse: collapse
& tr td
padding: 5px
vertical:
align: top
--
Stylesheets
Instead of inline-styling your body tag, why not create applicable stylesheets for each controller, and styling the body from these?
Like this:
#app/views/layouts/application.html.erb
<%= stylesheet_link_tag "application", controller_name, media: "all","data-turbolinks-track" => true %>
This will allow you to keep default styling in your application.css.scss, and use things like a background image in your various [controller].css.scss files:
app
| - assets
| - stylesheets
- application.css.scss
- controller1.css.scss
- controller2.css.scss
You'll then need to remember to add these assets to your pre-compilation procedure:
Rails.application.config.assets.precompile += ['controller1.css', 'controller2.css']
This will make your styling a LOT DRYer & more versatile

Related

Rails 6: How to add jquery-ui through webpacker?

I'm currently trying to implement a datepicker into my application, the problem is that there is no documentation on how to add the jquery-ui-rails gem through webpacker.
Probably there is another way to add gems or another gem that would fit my needs?
You no longer need to add javascript libraries as gems (which are managed by the bundler). Instead, you add them with yarn and they are managed by webpack (which is enabled by adding the webpacker gem to the Gemfile).
The following steps worked for me to get jquery-ui working in Rails 6:
On the terminal, inside your application type:
yarn add jquery-ui-dist
Your config/webpack/environment.js needs to look as follows:
const { environment } = require('#rails/webpacker')
const webpack = require('webpack')
environment.plugins.prepend('Provide',
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery'
})
);
const aliasConfig = {
'jquery': 'jquery-ui-dist/external/jquery/jquery.js',
'jquery-ui': 'jquery-ui-dist/jquery-ui.js'
};
environment.config.set('resolve.alias', aliasConfig);
module.exports = environment
Restart your rails server
In the application.html.erb, include the jquery-ui theme:
<!DOCTYPE html>
<html>
<head>
<title>Jquery UI Test</title>
<%= csrf_meta_tags %>
<%= csp_meta_tag %>
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
<%= stylesheet_link_tag '//ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/themes/le-frog/jquery-ui.min.css' %>
<%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
</head>
<body>
<%= yield %>
</body>
</html>
Now, in your app/javascript/packs/application.js, you can use jquery-ui:
NOTE: If you would like to use jQuery inside your views folder, make it available globally
require("#rails/ujs").start()
require("turbolinks").start()
require("#rails/activestorage").start()
require("channels")
// THIS IS MAKING jQuery AVAILABLE EVEN INSIDE Views FOLDER
global.$ = require("jquery")
require("jquery") // Don't really need to require this...
require("jquery-ui")
$(function(){
// Plain jquery
$('#fadeMe').fadeOut(5000);
// jquery-ui
const availableCities = ['Baltimore', 'New York'];
$('#cityField').autocomplete( { source: availableCities } );
$('#calendarField').datepicker( { dateFormat: 'yy-mm-dd' } );
})
This will work for a page that looks as follows:
<div id='fadeMe'>I will fade</div>
City: <input type='text' id='cityField' />
Calendar: <input type='text' id='calendarField' />
None of these answers quite worked for me. Here's how I ended up getting it implemented:
yarn add jquery
then
yarn add jquery-ui-dist
in your app/javascript/packs/application.js file:
// jquery
import $ from 'jquery';
global.$ = $
global.jQuery = $
require('jquery-ui');
// jquery-ui theme
require.context('file-loader?name=[path][name].[ext]&context=node_modules/jquery-ui-dist!jquery-ui-dist', true, /jquery-ui\.css/ );
require.context('file-loader?name=[path][name].[ext]&context=node_modules/jquery-ui-dist!jquery-ui-dist', true, /jquery-ui\.theme\.css/ );
and in config/webpack/environment.js:
const { environment } = require('#rails/webpacker');
const webpack = require('webpack');
// resolve-url-loader must be used before sass-loader
environment.loaders.get('sass').use.splice(-1, 0, {
loader: 'resolve-url-loader',
options: {
attempts: 1
}
});
// Add an additional plugin of your choosing : ProvidePlugin
environment.plugins.prepend('Provide', new webpack.ProvidePlugin({
$: 'jquery',
JQuery: 'jquery',
jquery: 'jquery',
'window.Tether': "tether",
Popper: ['popper.js', 'default'], // for Bootstrap 4
})
)
const aliasConfig = {
'jquery': 'jquery/src/jquery',
'jquery-ui': 'jquery-ui-dist/jquery-ui.js'
};
environment.config.set('resolve.alias', aliasConfig);
//
module.exports = environment;
A restart to my server got it working fine for me. Here is a link with details on webpacker that I used to get this to work:
https://gist.github.com/maxivak/2612fa987b9f9ed7cb53a88fcba247b3#jquery-jquery-ui
$ yarn add webpack-jquery-ui
and in application.js
require('webpack-jquery-ui');
require('webpack-jquery-ui/css');
did the job for me.
(I had setup jquery before which might need some additional config)
Weblink: https://www.npmjs.com/package/webpack-jquery-ui
(This is the same process as in Tushar Patil's answer yet with another package).
Kalman's answer worked for me, although not from the very beginning (I'm writing it in a separate answer as I don't have enough reputation to comment on the original answer yet :) )
So, beware that when you put require("jquery-ui") in app/javascript/packs/application.js, the functions provided by jquery-ui will not be available in your scripts loaded to individual views with javascript_pack_tag
The reason for that is that these individual scripts will load before application.js loads.
To make it work, I had to put require("jquery-ui") in one of these individual scripts that depended on jquery-ui
BTW, it works in Kalman's example, as he wrote his script directly in application.js, after requiring "jquery-ui"
Kalman's answer puts jQuery within the scope of the scripts in the app/javascript directory but not with any in-line javascript that you may have on your webpages.
If you want to access jQuery from the scope of the webpage, you could can put jQuery under the public directory then modify app/views/layouts/application.html.erb to link to it like this:
<!DOCTYPE html>
<html>
<head>
<title>JqueryTest</title>
<%= csrf_meta_tags %>
<%= csp_meta_tag %>
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
<%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
<script src="/jquery-3.4.1.js"></script>
<%= stylesheet_link_tag "/jquery-ui-1.12.1.custom/jquery-ui.min.css" %>
<script src="/jquery-ui-1.12.1.custom/jquery-ui.min.js"></script>
</head>
<body>
<%= yield %>
</body>
</html>
Above steps works fine, removed extra steps
The following steps worked for me to get jquery-ui working in Rails 6:
1) On the terminal, inside your application type:yarn add jquery-ui-dist
2) in app/javascript/packs/application.jsrequire("jquery-ui-dist/jquery-ui");
3) In the application.html.erb, include the jquery-ui theme
<%= stylesheet_link_tag '//ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/themes/le-frog/jquery-ui.min.css' %>
4) restart the rails server and webpack dev server.
For me a hybrid of several articles, and things worked and looked the most elegant
CLI:
yarn add jquery jquery-ui-dist
app/javascript/packs/application.js:
// ... SNIP ...
require("jquery")
require("jquery-ui")
config/webpack/environment.js:
const { environment } = require('#rails/webpacker')
const webpack = require('webpack')
environment.plugins.prepend('Provide',
new webpack.ProvidePlugin({
$: 'jquery/src/jquery',
jQuery: 'jquery/src/jquery'
})
)
const aliasConfig = {
'jquery': 'jquery/src/jquery',
'jquery-ui': 'jquery-ui-dist/jquery-ui.js'
};
environment.config.set('resolve.alias', aliasConfig);
module.exports = environment
app/views/layouts/application.html.erb
<%= stylesheet_link_tag '//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css' %>
Run on the terminal (CLI)
yarn add jquery jquery-ui-dist
Add to the config/webpack/environment.js
...
const webpack = require("webpack")
environment.plugins.append("Provide",
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery'
})
)
const aliasConfig = {
'jquery': 'jquery/src/jquery',
'jquery-ui': 'jquery-ui-dist/jquery-ui.js'
};
environment.config.set('resolve.alias', aliasConfig);
...
app/javascript/packs/application.js:
require("jquery-ui")
For the theme add code to any scss file. Do change according to your nee.
.ui-autocomplete {
position: absolute;
top: 100%;
left: 0;
z-index: 1000;
float: left;
display: none;
min-width: 160px;
padding: 4px 0;
margin: 0 0 10px 25px;
list-style: none;
background-color: #ffffff;
border-color: #ccc;
border-color: rgba(0, 0, 0, 0.2);
border-style: solid;
border-width: 1px;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
border-radius: 5px;
-webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
-moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
-webkit-background-clip: padding-box;
-moz-background-clip: padding;
background-clip: padding-box;
*border-right-width: 2px;
*border-bottom-width: 2px; }
.ui-menu-item > a.ui-corner-all {
display: block;
padding: 3px 15px;
clear: both;
font-weight: normal;
line-height: 18px;
color: #555555;
white-space: nowrap;
text-decoration: none; }
.ui-state-hover, .ui-state-active {
color: #ffffff;
text-decoration: none;
background-color: #0088cc;
border-radius: 0px;
-webkit-border-radius: 0px;
-moz-border-radius: 0px;
background-image: none; }

SCSS animation doesn't work

It is my sccs code:
#logo{
animation: zoomIn, 4s;
}
#mixin keyframes($name) {
#keyframes #{$name} {
#content;
}
}
// use of keyframes mixin
#include keyframes(zoomIn) {
0% {
opacity: 0;
transform: scale3d(.3, .3, .3);
}
50% {
opacity: 1;
}
}
And this is my HTML code:
<!DOCTYPE html>
<html>
<head>
<title>Dako</title>
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %>
<%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
<%= csrf_meta_tags %>
</head>
<body class='<%= controller.controller_name %>'>
<div id="top"><%= image_tag('dako.png', id:'logo') %></div>
...
Why it doesn't animate? I was trying add the prefix webkit- but it didn't help me.
There's a few issues with your scss code;
You need to add the -webkit prefix in front of both keyframes and animation
Make sure you declare the keyframes before using them (at the moment #logo is looking for animation: zoomIn but it doesn't exist yet)
You shouldn't have commas in your animation statement
Your final code should look something like this
//Keyframe Mixin
#mixin keyframes($name) {
#keyframes #{$name} {
#content;
}
#-webkit-keyframes #{$name} {
#content;
}
}
// Create Keyframes
#include keyframes(zoomIn) {
0% {
opacity: 0;
transform: scale3d(.3, .3, .3);
}
50% {
opacity: 1;
}
}
//Use Animation
#logo{
animation: zoomIn 3s;
-webkit-animation: zoomIn 3s;
}

reveals.js : how to reduce space on top of slides?

I am new using reveal.js.
I did not manage to reduce the space on top of my slides. Could somebody help me ?
Note : I a am using pandoc to create my slideshow from Markdown sources. This is the command line I use :
pandoc -s -f markdown+tex_math_single_backslash \
--bibliography=bibliography.bib --filter pandoc-citeproc \
--slide-level 2 --toc --mathjax -i -t revealjs -V theme:beige \
-H mysettings.css mfront.md -o mfront.html
This is generated code:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="generator" content="pandoc">
<meta name="author" content="Thomas Helfer" />
<meta name="dcterms.date" content="2014-01-01" />
<title>MFront User Meeting: TFEL 2.0 and beyond</title>
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<link rel="stylesheet" href="reveal.js/css/reveal.min.css"/>
<style type="text/css">code{white-space: pre;}</style>
<style type="text/css">
table.sourceCode, tr.sourceCode, td.lineNumbers, td.sourceCode {
margin: 0; padding: 0; vertical-align: baseline; border: none; }
table.sourceCode { width: 100%; line-height: 100%; }
td.lineNumbers { text-align: right; padding-right: 4px; padding-left: 4px; color: #aaaaaa; border-right: 1px solid #aaaaaa; }
td.sourceCode { padding-left: 5px; }
code > span.kw { color: #007020; font-weight: bold; }
code > span.dt { color: #902000; }
code > span.dv { color: #40a070; }
code > span.bn { color: #40a070; }
code > span.fl { color: #40a070; }
code > span.ch { color: #4070a0; }
code > span.st { color: #4070a0; }
code > span.co { color: #60a0b0; font-style: italic; }
code > span.ot { color: #007020; }
code > span.al { color: #ff0000; font-weight: bold; }
code > span.fu { color: #06287e; }
code > span.er { color: #ff0000; font-weight: bold; }
</style>
<link rel="stylesheet" href="reveal.js/css/theme/simple.css" id="theme">
<!-- If the query includes 'print-pdf', include the PDF print sheet -->
<script>
if( window.location.search.match( /print-pdf/gi ) ) {
var link = document.createElement( 'link' );
link.rel = 'stylesheet';
link.type = 'text/css';
link.href = 'reveal.js/css/print/pdf.css';
document.getElementsByTagName( 'head' )[0].appendChild( link );
}
</script>
<!--[if lt IE 9]>
<script src="reveal.js/lib/js/html5shiv.js"></script>
<![endif]-->
<script src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML" type="text/javascript"></script>
<style type="text/css">
.reveal h1 { font-size: 2.5em; }
.reveal section img {
border: none;
box-shadow: none;
}
body {
background: url("images/background.svg") no-repeat fixed top left
}
</style>
</head>
<body>
<div class="reveal">
<div class="slides">
</section><section id="logarithmic-strains---principle" class="slide level2">
<h1>Logarithmic strains - Principle</h1>
<ul>
<li class="fragment"><span class="math">\({\underline{T}}\)</span> is the dual of the logarithmic strain <span class="math">\({\underline{\epsilon}^{\mathrm{to}}}{}_{\text{log}}\)</span>
<ul>
<li class="fragment"><span class="math">\(P={\underline{T}}\,\colon\,{\underline{\epsilon}^{\mathrm{to}}}{}_{\text{log}}={\underline{S}}\,\colon\,{\underline{\epsilon}^{\mathrm{to}}}{}_{\text{GL}}\)</span></li>
</ul></li>
<li class="fragment">if the small strain behaviour is <strong>thermodynamically consistent</strong>, so does the corresponding finite strain behaviour.</li>
<li class="fragment">the behaviour is <strong>objective</strong> due to its lagrangian nature.</li>
<li class="fragment"><strong>no restriction</strong> on the small strain behaviour (initial and induced <strong>orthotropy</strong> can be handled appropriately: application to Zircaloy ?)
<ul>
<li class="fragment">much more appealing than the hypoelastic Cast3M formulation</li>
</ul></li>
<li class="fragment"><em>drawbacks:</em> the pre- and post-processing stage are non trivial and may have a significant computation costs.</li>
<li class="fragment"><span class="math">\({\underline{T}}\)</span> is the dual of the logarithmic strain <span class="math">\({\underline{\epsilon}^{\mathrm{to}}}{}_{\text{log}}\)</span>
<ul>
<li class="fragment"><span class="math">\(P={\underline{T}}\,\colon\,{\underline{\epsilon}^{\mathrm{to}}}{}_{\text{log}}={\underline{S}}\,\colon\,{\underline{\epsilon}^{\mathrm{to}}}{}_{\text{GL}}\)</span></li>
</ul></li>
<li class="fragment"><span class="math">\({\underline{T}}\)</span> is the dual of the logarithmic strain <span class="math">\({\underline{\epsilon}^{\mathrm{to}}}{}_{\text{log}}\)</span>
<ul>
<li class="fragment"><span class="math">\(P={\underline{T}}\,\colon\,{\underline{\epsilon}^{\mathrm{to}}}{}_{\text{log}}={\underline{S}}\,\colon\,{\underline{\epsilon}^{\mathrm{to}}}{}_{\text{GL}}\)</span></li>
</ul></li>
</ul>
</section></section></section>
</div>
</div>
<script src="reveal.js/lib/js/head.min.js"></script>
<script src="reveal.js/js/reveal.min.js"></script>
<script>
// Full list of configuration options available here:
// https://github.com/hakimel/reveal.js#configuration
Reveal.initialize({
controls: true,
progress: true,
history: true,
center: true,
theme: 'beige', // available themes are in /css/theme
transition: Reveal.getQueryHash().transition || 'default', // default/cube/page/concave/zoom/linear/fade/none
// Optional libraries used to extend on reveal.js
dependencies: [
{ src: 'reveal.js/lib/js/classList.js', condition: function() { return !document.body.classList; } },
{ src: 'reveal.js/plugin/zoom-js/zoom.js', async: true, condition: function() { return !!document.body.classList; } },
{ src: 'reveal.js/plugin/notes/notes.js', async: true, condition: function() { return !!document.body.classList; } },
// { src: 'reveal.js/plugin/search/search.js', async: true, condition: function() { return !!document.body.classList; }, }
// { src: 'reveal.js/plugin/remotes/remotes.js', async: true, condition: function() { return !!document.body.classList; } }
]});
</script>
</body>
</html>
This leads to a slide title under a significant margin and parts of the slide hidden.
reveal.js has a "height" option that can be set when you call Reveal.initialize.
With pandoc, provided you have a recent templates/default.revealjs, you can set the "height" variable:
---
author: me
title my title
height: 800
...
my presentation

rake assets:precompile does not work compiling locally

I just ran this on my QA and production server and it went perfectly.
rake assets:precompile
But when I run it locally, the trace responds fine. I can tell it's accessing my database because of my .scss.erb file. And that something happened, but when I reboot my server, and inspect my css file, no changes were actually made.
Additional notes :
My application.rb has ->
config.assets.initialize_on_precompile = true
The contents of colors.scss.erb
<% Color.for_header.each do |color| %>
#super_header.color-<%= color.id %>, #eheader.color-<%= color.id %> {
background-color: #<%= color.code %>;
background-image: none;
}
<% end %>
<% Color.for_highlight.each do |color| %>
.lists-list.color-<%= color.id %> li {
&.current a {
&:before { background: url(/images/group-select-end-left/<%= color.image %>) no-repeat !important; }
&:after { background: url(/images/group-select-end-right/<%= color.image %>) no-repeat !important;}
}
&.active, &.current {
a {
background-color: #<%= color.code %> !important;
background-image: none !important;
}
&:before {
background: url(/images/group-select-end-left/<%= color.image %>) no-repeat !important;
left: -9px;
height: 39px;
width: 9px;
}
&:after {
background: url(/images/group-select-end-right/<%= color.image %>) no-repeat;
right: -10px;
width: 10px;
height: 30px;
top: 0;
}
}
}
<% end %>
Since rake loads all Rails stack, you probably need to add the environemnt:
RAILS_ENV=your_env_name bundle exec rake assets:precompile
It works on my staging server (no heroku) using capistrano.

How to change formatting of part of a sentence?

I have a line like this in my view:
<div class="contact">
<h6>#Model.Salutation</h6><h3>#Model.FirstName #Model.LastName</h3>
</div>
I am trying to achieve a Mr Tommy Jones, while Mr in a different formatting.
Such as below:
.contact h3 {
font-size: 1.1em;
}
.contact h6 {
font-size: 0.85em;
color: gray;
}
However I get a line break between Mr and rest, what do I have to do?
You have h6 tag followed by h3 tag. I'm thinking...is this a true header text? Are you using tags because of formatting instead of meaning?
Try to write:
<div class="contact">
<span class="title">#Model.Salutation</span><span class="name">#Model.FirstName #Model.LastName</span>
</div>
With following CSS (update to match required formatting):
.contact .title
{
font-size: 0.85em;
color: gray;
}
.contact .name
{
font-size: 0.85em;
font-weight: bold;
}
If you're using HTML 5 tags you may include microdata informations and use different tags too. Look this example (just updated with microdata):
<div class="contact" itemscope itemtype="http://schema.org/Person">
<span itemprop="title">#Model.Salutation</span>
<span itemprop="name">#Model.FirstName #Model.LastName</span>
</div>
Your CSS may be changed to:
div[itemtype="http://schema.org/Person"] > span[itemprop="title"]
{
font-size: 0.85em;
color: gray;
}
div[itemtype="http://schema.org/Person"] > span[itemprop="name"]
{
font-size: 0.85em;
font-weight: bold;
}
All h* are by default block elements, simply meaning that they will occupy a whole width of the container, pushing things to the left and right of it.
try adding display:inline to your h6 and h3
.contact h6, .contact h3 { display:inline }
h3 and h6 are both blocking elements, so either you change the display property of both to inline (which I don't recommend) or change your markup like this:
<div class="contact">
<h3><span class="salutation">#Model.Salutation</span> #Model.FirstName #Model.LastName</h3>
</div>
Styling only the span element.
Another possibility - if the information about «salutation» is not particular relevant in the context but it's just used to introduce the name for visualization purpose - is to use pseudoelements and place there that information like so:
<div class="contact">
<h3 data-salutation="#Model.Salutation">#Model.FirstName #Model.LastName</h3>
</div>
and the CSS
.contact h3 {
font-weight: bold;
}
.contact h3:before {
content: attr(data-salutation);
padding-right: 1em;
font-weight : normal;
}

Resources