Targeting dynamic class names in css/scss or JavaScript - ruby-on-rails

In my rails application I have two models, Users and Goals. A User can have Many Goals, and a Goal belongs to a User. I have a page that lists all of a users Goals in the users show page. This is done using a .each loop, and in this loop I have created a dynamic class name that puts the goal_id into the class name.
I want to be able to target these individual classes in my css/scss folder so that I can, for example, have only the first goal be highlighted when I hover over it.
app/views/users/show.html.erb
<div class="user-goals-mouse-events">
<% #user.goals.each do |goal| %>
<%= link_to goal_path(goal), class: "user-goals-hover-#{goal.id}" do %>
<div class="row">
<div class="col-md-4">
<h2 class="color-light-blue"><%= goal.name %></h2>
</div>
<div class="col-md-8 user-goals-description">
<h4><%= goal.description %></h4>
</div>
</div>
<h6 class="hide-username-<%= goal.id %>"><%= #user.username %></h6>
<% end %>
<% end %>
The Scss is not working currently but it may help show what i'm attempting to do.
app/assets/stylesheets/custom.css.scss
.user-goals-mouse-events > a {
border-bottom-style: solid;
border-bottom-color: black;
border-bottom-width: 1px;
//background-color: black;
&:hover {
background-color: #26AEFF;
color: gold;
}
}
.user-goals-mouse-events > div > h6 {
opacity: 0;
}
.color-light-blue {
color: #26AEFF;
&:hover {
color: white;
}
}
If a better solution to this problem is done a different way (e.g. with javascript) then please let me know as I want to do it the most efficient way.

Try to use the attribute-value-begins-with selector:
a[class^=user-goals-hover] {
border-bottom-style: solid;
border-bottom-color: black;
border-bottom-width: 1px;
//background-color: black;
&:hover {
background-color: #26AEFF;
color: gold;
}
}

#hashrocket answer is good, but I'd advise to be more explicit on your classes. It is a code smell when you need a class both for styling and for targeting.
Yes, there is such a thing as code smell in CSS too! :)
I would have a constant class for styling and a dynamic one or even a completely different attribute for targeting:
<%= link_to goal_path(goal), class: "user-goals", data: {goal_id: goal.id} do %>
which would render as
<a href="/goals/42" class="user-goals" data-goal-id="42">
and the css would just be
.user-goals {
//...
&:hover {
//...
}
}

Related

Rails/Bootstrap. Using .each falling to have a new Thumbnail next to the one before horizontally

Every cycle I get the new Thumbnail BUT under the previous one. Any suggestions how to solve that? How in each cycle add the new Thumbnail horizontally next to the previous one, until the space is fill and then move to the next line? Thanks.
From TO Picture
CODE
<% #employees.each do |em| %>
<div class="listTumbnail">
<% if em.user.imagepath %>
<div class = "user-image">
<img src="<%= em.user.imagepath%>" class="listimg">
</div>
<% else %>
<div>
<%= image_tag("icons/desconocido.jpg", :alt => "not found", :class => "listimg") %>
</div>
<% end %>
</div>
<% end %>
.user-image {
float: none;
padding-top: 127px;
margin-left: 193px;
padding-left: 6px;
border-left-style: solid;
border-left-color: #000;
border-left-width: 1px;
}
.listimg {
display: block;
max-width:80px;
max-height:100px;
width: auto;
height: auto;
margin: 0 auto;
border-radius: 40px;
}
.listTumbnail {
border: 2px solid #95989A;
border-radius: 3px;
color: #000;
height: 140px;
width: 110px;
margin: 5px;
}
try adding this to your stylesheet:
.listThumbnail {
display: block;
}
.user-image {
display: inline-block;
}
If for some reason you don't have a css file in your project, here's one basic way to add one:
Create a file named my_styles.css (or whatever you want to name it) & add the above css examples there.
Add the following link in the <head> of your application.html.erb file:
<link rel="stylesheet" type="text/css" href="my_styles.css">
This allows your html file to work with your css file/stylesheet.

microposts are not showing up in a ol (ordered list)

I have been working with Michael Hartl's tutorial and I am almost finished. However, I got near the end and am have a problem styling the micropost section of the "user/show/" page. I would like all the microposts to be under one another. Currently they are showing like this:
custom.css.scss
.microposts {
list-style: none;
padding: 0;
li {
padding: 10px 0;
border-top: 1px solid #e8e8e8;
}
.user {
margin-top: 5em;
padding-top: 0;
}
.content {
display: block;
margin-left: 60px;
img {
display: block;
padding: 5px 0;
}
}
.timestamp {
color: $gray-light;
display: block;
margin-left: 60px;
}
.gravatar {
float: left;
margin-right: 10px;
margin-top: 5px;
}
}
aside {
textarea {
height: 100px;
margin-bottom: 5px;
}
}
span.picture {
margin-top: 10px;
input {
border: 0;
}
}
microposts.html.erb
<li id="micropost-<%= micropost.id %>">
<%= link_to gravatar_for(micropost.user), micropost.user %>
<span class="user"><%= link_to micropost.user.name, micropost.user %></span>
<span class="content"><%= micropost.content %></span>
<span class="timestamp">
Posted <%= time_ago_in_words(micropost.created_at) %> ago.
</span>
</li>
show.html.erb
<% provide(:title, #user.name) %>
<div class="row">
<aside class="col-md-4">
<section class="user_info">
<h1>
<%= gravatar_for #user %>
<%= #user.name %>
</h1>
</section>
</aside>
<div class="col-md-8">
<% if #user.microposts.any? %>
<h3>Microposts (<%= #user.microposts.count %>)</h3>
<ol class="microposts">
<%= render #microposts %>
</ol>
<%= will_paginate #microposts %>
<% end %>
</div>
</div>
If someone could please help me, it would be highly appreciated. Thank you in advance!
You need to clear the floats. Try adding clear: both; to your .microposts .li SASS
.microposts {
list-style: none;
padding: 0;
li {
padding: 10px 0;
border-top: 1px solid #e8e8e8;
clear: both;
}
JSFIDDLE DEMO

Rails link_to tag tag with styled glyphicon

I am trying to use glyph icons that I have styled in my rails app.
I want to make the icon a link to another page, but can't use the standard bootstrap styling because I have customised the links for my page's style.
I keep getting a keyword class error - does anyone know why?
Thank you.
I have the following link in my view:
<li><%= link_to <span class="glyphicon glyphicon-comment"></span>, page_path('messages') %> </li>
I also have css as follows:
span.glyphicon-comment {
vertical-align:middle;
margin:auto;
padding:10px;
font-size: 2em;
text-align: right;
a:link {text-decoration:none; background-color:transparent; color:grey;};
a:visited {text-decoration:none;background-color:transparent; color:grey;};
a:hover {text-decoration:none;background-color:transparent; color:dark grey;};
a:active {text-decoration:none;background-color:transparent; color:grey;};
}
You have to use " around the string, also need to call html_safe method on it.
<%= link_to "<span class=\"glyphicon glyphicon-comment\"></span>".html_safe, page_path('messages') %>
but a better and cleaner way would be
<%= link_to page_path('messages') do %>
<span class="glyphicon glyphicon-comment"></span>
<% end %>
Your problem is that you are using a:visited {text-decoration:none; background-color:transparent; color:grey;}; on your glyphicon css but they should be on your link
Try this:
<%= link_to page_path('messages'), class: "comment_link" do %>
<span class="glyphicon glyphicon-comment"></span>
<% end %>
and then style your link, if you are using scss then:
.comment_link{
.glyphicon-comment{
vertical-align:middle;
margin:auto;
padding:10px;
font-size: 2em;
text-align: right;
}
&:hover, &:visited, &:active{
text-decoration:none;
background-color:transparent;
color:dark grey;
}
}

Show banner and menu navigation bar on all pages

I am new to Rails. I am using Aptana Studio 3 to write a small application.
In the Views folder, I added a new .html.erb page and added a jQuery navigation menu bar. This page also has a banner. I want to keep this as a base page (like Master Page in .NET) for all the other pages.
I want all the other pages to automatically show the banner and menu bar on top.
How to do this? I am using Rails 3.2.
Edited
Code of application.html.erb:
<!DOCTYPE html>
<html>
<head>
<title></title>
<%= stylesheet_link_tag "application", :media => "all" %>
<%= javascript_include_tag "application" %>
<%= csrf_meta_tags %>
<script type="text/javascript" src="..\Libraries\jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$('li.headlink').hover(
function() { $('ul', this).css('display', 'block'); },
function() { $('ul', this).css('display', 'none'); });
});
</script>
<style type="text/css" rel="stylesheet">
/* General */
#cssdropdown, #cssdropdown ul { list-style: none; }
#cssdropdown, #cssdropdown * { padding: 0; margin: 0; }
/* Head links */
#cssdropdown li.headlink { width: 220px; float: left; margin-left: -1px; border: 1px black solid; background-color: #e9e9e9; text-align: center; }
#cssdropdown li.headlink a { display: block; padding: 15px; }
/* Child lists and links */
#cssdropdown li.headlink ul { display: none; border-top: 1px black solid; text-align: left; }
#cssdropdown li.headlink:hover ul { display: block; }
#cssdropdown li.headlink ul li a { padding: 5px; height: 17px; }
#cssdropdown li.headlink ul li a:hover { background-color: LightBlue; color:Black }
/* Pretty styling */
body { font-family: verdana, arial, sans-serif; font-size: 0.8em;}
#cssdropdown a { color: white; } #cssdropdown ul li a:hover { text-decoration: none; }
#cssdropdown li.headlink { background-color: Blue;}
#cssdropdown li.headlink ul { background-position: bottom; padding-bottom: 10px; }
</style>
</head>
<body>
<%= yield %>
<div id="divMain">
<div id="divHeader">
<img src="..\Images\W.png">
</div>
<div id="divMenu">
<ul id="cssdropdown">
<li class="headlink">
Task
<ul>
<li>Add New</li>
</ul>
</li>
<li class="headlink">
Reports
<ul>
<li>Report</li>
</ul>
</li>
</ul>
</div>
</div>
<div id="content"><%= content_for?(:content) ? yield(:content) : yield %></div>
</body>
</html>
Code of Content.html.erb
<% content_for :stylesheets do %>
<div id="divLogin">
</div>
<% end %>
<% content_for :MainContent do %>
<div id="divMain">
</div>
<% end %>
<%= render :partial => "layouts\application.html.erb" %>
Rails uses layouts as master templates. As default will you have one master layout template called application, which you can find in app/views/layouts/application.html.erb. If you look at this file will you see something like:
# app/views/layouts/application.html.erb
<html>
<head>
...
</head>
<body>
...
<div id="content">
# Your page content will be inserted here:
<%= yield %>
</div>
...
</body>
</html>
As default will this be rendered for all pages, and the content of each page (fx your new.html.erb) would be rendered in the yield block.
This means that application.html.erb is the right place to but generel layout stuff, like menus and banners that should appear on all pages.
If you want to have something that varies a bit for each page (fx different banners) can you add a special <%= yield(:banner) if content_for?(:banner) %> in your application.html.erb file. You will then be able to add a block in each of your pages for a banner like this:
# app/views/some_resource/some_page.html.erb
<% content_for(:banner) do %>
# insert page specifik banner here
<% end %>
# normal content for page
...
I hope this answers your question?
You can also read more about layouts (fx how to use more then one layout) on http://guides.rubyonrails.org/layouts_and_rendering.html
Edit: correct way to implement content.html.erb
The content of content.html.erb should be:
# What is this? This has nothing to do with stylesheets?
<% content_for :stylesheets do %>
<div id="divLogin">
</div>
<% end %>
<div id="divMain">
</div>
So no content_for :MainContent block and don't render the ´application.html.erb´ layout template (it's not even a partial, so you can't do this).
You can use nested layouts as described here.
Watch from 5:18,
from what I've read I think thats kind of what you may be looking for.
Hope it helps.
Railscast #328
Also here is a link to Twitter's bootstrap navbar which you may want to look into. It will show a banner and navigation bar on all pages and is fairly easy to set up.
http://twitter.github.io/bootstrap/components.html#navbar
One of the best sources for this topic is the beginning of the book The Rails View. Here is the link: The Rails View
This really helps with the content_for helper method, which will become your friend instantly once you know how to use it.

Rails 3.1 button Icon with css

How can I add an icon to a rails button with css?
My request is both for <% button_to %> and <% f.submit %>
Thanks for helping
Hello #jdc I've finally found the trick, I did not use your method, but it was helpul to find my way.Thanks a lot man.So thi is How i proceed :
1°) Change the html.erb code from :
<%= f.submit %>
to
<%= f.submit , :id => 'button' do -%>
<% end %>
2°) In the app/assets/stylesheets and put the following css code:
#button {
background-image: url(plus_8x8.png);
background-repeat:no-repeat;
display:block;
float:left;
margin:0 7px 0 0;
background-color:#f5f5f5;
border:1px solid #dedede;
border-top:1px solid #eee;
border-left:1px solid #eee;
font-family:"Lucida Grande", Tahoma, Arial, Verdana, sans-serif;
font-size:12px;
line-height:130%;
text-decoration:none;
font-weight:bold;
color:#565656;
cursor:pointer;
padding:5px 10px 6px 7px;; /* I put this here to move the text away on older IE junk */
}
Of course #button at the top of the css code is the :id name in <%= f.submit , :id => 'button' do -%> code in the html.erb file
I hope this will help you guys to style css button on rails 3 applications.
If I understand what you're asking, you could try something like this:
<% f.submit :html => { :class => 'imgbutton' } %>
then in your css:
background: url(someicon.gif);
border: none; /* If your icon IS the button */
color: transparent; /* If you don't want the button text to show up */
*padding-left: 9999px; /* I put this here to move the text away on older IE junk */
Might not work for some really ancient browsers to do it with CSS though.

Resources