Rails4: How to create Image Links with Hover? - html

I have a Rails 4.0.1 app that shows a set of image links on the homepage. Rails gets the image names from the Industry model. Each image should show a hover image on mouseover.
I've tried this:
<% #industries.each_with_index do |i,n| %>
<li class="col-md-2 col-md-offset-1">
<%= link_to image_tag(i.img_full, alt: i.name, class: 'industry_thumb', mouseover: i.img_full_mo), companies_path(industry: i.name) %>
</li>
<% end %>
However, this results in this HTML:
<li class="col-md-2">
<a href="/companies?industry=Personalberatung">
<img alt="Personalberatung" class="industry_thumb" mouseover="branchen_personalber_mo.png" src="/assets/branchen_personalber.png">
</a>
</li>
When I was expecting the mouseover: to work like described here:
http://apidock.com/rails/ActionView/Helpers/AssetTagHelper/image_tag
I found not too many articles about this issue which is why I'm guessing there's an alternative way using CSS. However, how would I achieve the same effect with CSS if I want to dynamically generate the image links? Unfortunately, moving the default and the hover image into one image and using something like this:
.button-class {
border: 0;
background: url('../assets/images/button.png') no-repeat 0 0px;
}
.button-class:hover {
background: url('../assets/images/button.png') no-repeat 0 20px;
}
isn't possible in this case. Unless there's an automatic way to combine the two images during assets:precompile?
Many thanks for your help!

image_tag(class_door(student_class), onMouseover: "this.src='/assets/open_door.png';", onMouseout: "this.src='/assets/closed_door.png'" )
I have the above code is working for me , note that class_door(student_class) is a helper in my application
the mouse over method is onMouseover: not mouseover:

Try this.
.col-md-2 a img:hover{
/*Your hover values should be here*/
}
Hope this helps.

You should use something like this to be consistent with the asset pipeline way:
image_tag(class_door(student_class), onMouseover: "this.src='#{image_url("/assets/open_door.png")}';", onMouseout: "this.src='#{image_url("/assets/closed_door.png")}'" )

Related

Change a photo on page with ccs ( :hover )

I'm sure this is really freaking simple, but I must be overlooking some aspect. I have a static image that is displayed on a webpage when it is loaded. I have an unordered list with a few list items. I would like to change the displayed webpage image when the mouse hovers over one/each list item. I tried using the onmouseover HTML event, but could not figure that out and I would like to use CSS anyways so I tried using the :hover CSS selector but I can't seem to figure it out
<div class="responsive_right_side_block"><img class="responsive_image" height="214" src="images/axis.gif" width="145"></div>
<p class="p_not_1st">The three commonly referred to axis of rotation are:
<ul class="ul_first">
<li id="frontal">Frontal axis</li>
<li>Sagittal axis</li>
<li>Vertical axis</li>
</ul>
</p>
Here is the CSS block that I currently have
<style>
#frontal:hover .responsive_image {
display: "images/sagittal.gif";
}
</style>
since ".responsive image" is not apart of your unordered list, you don't need to mention it in CSS. and instead of using the display value, use background. For your CSS code I would just type.
<style>
#frontal:hover {
background: url("images/sagittal.gif") no-repeat;
}
</style>
You can use javascript to do what you want as follow :
<script>
window.onload = WinLoad;
function WinLoad() {
document.getElementById("frontal").addEventListener("mouseover", changeImage);
function changeImage() {
document.getElementById("responsive_image").src = "images/sagittal.gif";
}
}
</script>
Well .. your style says that
"on the hover of the li item ... select the image inside this item".
That's because #frontal:hover .responsive_image is Descendant combinator. I suggest you to have a look on those topics CSS selectors from MDN & CSS Selector Reference from W3schools.
In your HTML structure, I don't think there is a way to do what you want using CSS only because till now there is no supported selectors for parents and grand parents in CSS.
Second thing I want to add is: there's no way to use the display property to change the image itself. Because display property specifies the display behavior of an element itself ... so, more again I suggest you to have a look on this topic CSS display Property.
Now, For your code, I've 2 suggestions:
(1): By make changes to HTML / CSS code
.responsive_right_side_block {
width: 145px;
height: 214px;
background-image: url("https://via.placeholder.com/300/0000FF/808080");
background-repeat: no-repeat;
background-size: contain;
}
#frontal:hover ~ .responsive_right_side_block {
background-image: url("https://via.placeholder.com/300/000000/FFFFFF");
}
<p class="p_not_1st">The three commonly referred to axis of rotation are:
<ul class="ul_first">
<li id="frontal">Frontal axis</li>
<li>Sagittal axis</li>
<li>Vertical axis</li>
<div class="responsive_right_side_block"></div>
</ul>
</p>
And then, you can use css to style it as you want.
(2): Using JavaScript mouseover
// select the image using it's class --> it's html collection so we need to specify the first index
let img = document.getElementsByClassName('responsive_image')[0];
// on mouse over of the li element --> the image src will change
document.getElementById('frontal').onmouseover = function () {
img.setAttribute('src', 'https://via.placeholder.com/300/000000/FFFFFF');
}
// on mouse out of the li element --> the image src will return back to what is in html document
document.getElementById('frontal').onmouseout = function () {
img.setAttribute('src', 'https://via.placeholder.com/300/0000FF/808080');
}
<div class="responsive_right_side_block"><img class="responsive_image" height="214"
src="https://via.placeholder.com/300/0000FF/808080" width="145"></div>
<p class="p_not_1st">The three commonly referred to axis of rotation are:
<ul class="ul_first">
<li id="frontal">Frontal axis</li>
<li>Sagittal axis</li>
<li>Vertical axis</li>
</ul>
</p>

Unexplained behaviour with AJAX request including CSS classes

A page has a function to choose some values for CSS class attributes.
The rails application show view has a style block and a div using those styles:
<style>
#bg_<%= #promolayout.id %> {
background-color: <%= #background.first.background_color %>;
color: <%= #background.first.color %>;
border-radius: <%= #background.first.border_box_radius %>; }
</style>
<div class='grid-x grid-padding-x'>
<div class='cell small-3' id='bg_<%= #promolayout.id %>'>
[...]
</div>
<div class='cell small-3' id='bg_newrender'> </div>
</div>
Lower in the page are form_with forms to change individual attributes values of CSS items via AJAX. The process updates as expected. The relevant js file for the rendering has two lines, one to display the new value with the form, the other to render (what was expected) a new version of the block with the new attribute (thus creating a before-after view). The second line invokes:
$("#bg_newrender").html('<%=j (render 'promolayout') %>');
the promolayout partial invokes the same CSS classes
<style>
#bg_<%= #promocomponent.promolayout_id %> {
background-color: <%= #background.first.background_color %>;
color: <%= #background.first.color %>;
border-radius: <%= #background.first.border_box_radius %>;
}
</style>
and the div with the id='bg_newrender' renders with the updated CSS attributes as expected.
What was not expected was that the initial div with id='bg_<%= #promolayout.id %>' also renders with the new CSS attributes.
The classes have the same name, but the target div has different IDs.
Why is a differently IDed object on the page also being rendered with the updated class attributes?
If you want to add styling dynamically to a single element instead use inline styling.
Usually we frown upon the style attribute as the rule of thumb is to separate content and presentation. But if you are dynamically generating an inline CSS tag with ERB the separation of concerns went out the window a long time ago and your really just making a mess out of your view.
In your Rails app you'll want to write a helper or builder class that creates the div tag with a style attribute.
Which would look something like:
module PromoHelper
def promo_component_tag(promo, **opts, &block)
options = opts.reverse_merge(
class: 'promo-box', # or whatever
style: hash_to_inline_style({
background_color: promo.background_color,
border_box_radius : promo.border_box_radius,
color: promo.color
})
)
content_tag :div, options, &block
end
private
def hash_to_inline_style(hash)
hash.map do |k,v|
"#{k.to_s.dasherize}: #{v};"
end.join
end
end
This is an extremely simplified example and will need to be adapted to your use case.
And you then call it in your view:
<% #promotions.each do |p| %>
<%= promo_component_tag(promo) do %>
# ...
<% end %>
<% end %>
When it comes to handling the actual user interaction you can either submit the form and have Rails re-render the view and replace the contents in the DOM or you can use element.style or jQuery.css to change the styling optimistically on the fly and just send the AJAX call in the background to update the database values. The latter will give a much snappier feel and ties in nicely if you want to let users preview the change.

Can I put a Rails partial between two arrows?

So, I have a rails partial (an image of a car) that I want to put between two arrows ("<" and ">").
Here's my haml:
.col-sm-12
<
= render partial: 'vehicle_image', locals: { quotation_request: quotation_request }
>
The problem I'm having is that I can't get the two arrows to show up on the same row as the image.
Any ideas on how this can be fixed?
You could probably assign the arrows to some sort of element instead and lay things out like this
.row
.col-sm-1.text-right
<
.col-sm-10
= render partial: 'vehicle_image', locals: { quotation_request: quotation_request }
.col-sm-1.text-left
>
You may have to do a bit of CSS to reduce the paddings/margins so that it that arrows end up where you want them exactly.
I just attempted it on a personal project using:
.row
.col-lg-1
%h1
<
.col-lg-8
= link_to place_path(place) do
= image_tag place.main_image.url(:medium), class: 'img-responsive img-place', alt: place.name
.col-lg-1
%h1
>
And got roughly this result after a bit of margin tweaking:

Rails error messages break signup form

I'm following this tutorial: http://ruby.railstutorial.org/chapters/sign-up#top and I have a problem with styles for error messages from rails.
I want to accomplish this:
But instead of that my form breaks and I get this ugly form:
I checked a source code and there are nov div tags inserted instead of label and input:
How to override that behavior and accomplish that form is only highlighted like in the tutorial?
Thank you.
EDIT 1:
I found out where is the problem. I'm using Bootstrap 3.1.0 and extend is not working there. So, this is not working:
#error_explanation {
color: #f00;
ul {
list-style: none;
margin: 0 0 18px 0;
}
}
.field_with_errors {
#extend .control-group;
#extend .error;
}
And because of that this code doesn't work like it should:
<% if #user.errors.any? %>
<div id="error_explanation">
<div class="alert alert-error">
The form contains <%= pluralize(#user.errors.count, "error") %>.
</div>
<ul>
<% #user.errors.full_messages.each do |msg| %>
<li>* <%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
I can't find a way to make that extend working. Like control-group is not present...
EDIT 2:
Ok, when I add this code to config/environment.rb the form doesn't break but can't accomplish red lines around forms where is wrong input:
ActionView::Base.field_error_proc = Proc.new do |html_tag, instance|
html_tag.html_safe
Why are you using Bootstrap 3? The tutorial tells you to use
gem 'bootstrap-sass', '2.3.2.0'
in your gemfile. You really should do so, because the tutorial provides you with a whole lot of code that is meant to be used with Bootstrap 2. Of course, it breaks with Bootstrap 3. If you really want to use B3 you will have to change quite a few class names in your views. Among other changes do this:
change div class="alert alert-error" to div class="alert alert-danger"
apply form-group and form-control classes to your form fields (see example here).
in your CSS:
.field_with_errors {
#extend .has-error;
}
Then do all the other changes mentioned here.
This seems to be quite a common error - have you ever tried either of these:
Rails field_with_errors and Bootstrap form-horizontal
Ruby field_with_errors doesn't #extend .control-group .error
#extend documentation
Precompile
Failing that, you may wish to try asset precompiling:
#config/environments/production.rb
config.serve_static_assets = true
config.assets.compile = false
$ rake assets:precompile RAILS_ENV=production
Mixins
This won't fix it directly, but you could create a mixin for the styles, and include that like this:
#mixin error {
display: block;
etc
}
.field_with_errors {
#extend .control-group;
#extend .error;
}

Changing the look of textfields

How do I change my textfields so they look more like the Twitter login textfields or even the Title textfield for Stackoverflow when you post a new question.
I currently just use:
<%= text_field_tag 'name', #name, :size => 30 %>
Have a look here.
http://www.webcredible.co.uk/user-friendly-resources/css/css-forms.shtml
I think you need to add:
<%= text_field_tag 'name', #name, :size => 5, :class => "cssclassname" %>
...and then define a css class called 'cssclassname' (or whatever you want it to be) to style the css.
A nice css guide for text boxes:
http://www.cssportal.com/form-elements/text-box.htm
Firebug for CSS Inspection
Have you tried using the Firebug tool for FireFox?
You can inspect elements on web sites and see what styles have been used.
In the case of the StackOverflow title input, the following style has been used:
input {
margin:5px 0pt;
padding:3px;
}
input, select, button {
border:1px solid #999999;
font-family:Trebuchet MS,Helvetica,sans-serif;
font-size:100%;
}
The general principle to achieving what you want is to specify a thin border on the text fields in your CSS. To match the Stack Overflow Title text field, add this to your CSS file:
input {
border: 1px solid #999;
}