simple_form checkbox does not generate sibling span for checkbox - ruby-on-rails

I am using simple form simple_form (v: 3.2.1) with bootstrap in my current rails application( other developer previously worked on this project).
For creating radio button from collection I use
= f.input :default_ship,
label: 'foo)',
collection: default_ship_options(#company),
as: :radio_buttons
That generate html like
<span class="radio radio radio"><label for="foo"><input class="radio_buttons required" required="required" aria-required="true" type="radio" value="company" name="purchasing_source[default_ship]" id="foo"><span></span>Test Shipping Address</label></span>
Look at here an empty span <span></span> is created that actually for showing checkbox.
My CSS code:
.radio, .checkbox {
position: relative;
display: block;
margin-top: 10px;
margin-bottom: 10px;
}
.radio label, .checkbox label {
min-height: 20px;
padding-left: 20px;
margin-bottom: 0;
font-weight: normal;
cursor: pointer;
}
label input[type=checkbox], label input[type=radio] {
display: none;
}
label input[type=checkbox] + span, label input[type=radio] + span {
display: inline-block;
width: 1.4em;
height: 1.4em;
margin-right: 0.5em;
vertical-align: middle;
cursor: pointer;
border: 1px solid #AAA;
}
Now My problem is simple form does not create extra span for checkbox element that's why no check box is shown for checkbox. Generated Html for checkbox is
<span class="checkbox"><label for="manufacturer_currencies_fr"><input class="check_boxes optional" type="checkbox" value="fr" name="manufacturer[currencies][]" id="manufacturer_currencies_fr">Euro</label></span>
How can I generate extra span also for checkbox?
(I do not want to change my css because it already used many places)
It's seem to me that I have to do something at simple_form_bootstrap.rb but not sure. It can also be that previous developer may override some method but I have no idea where I can find that.

Here is an example of wrapping check_boxes. They are treated in the same way, so you can use 'options' parameter to pass the necessary data with key "collection_wrapper_tag". You can go into class "form_builder" of simple_form and find it by yourself.
= f.collection_check_boxes :tariffs, #form.tariffs, :first, :last, {checked: #form.selected_tariffs, collection_wrapper_tag: 'span'}

Best solution I found was to overwrite the label_input method on simple form's BooleanInput.
Add the boolean_input file in app/inputs/boolean_input.rb:
class BooleanInput < SimpleForm::Inputs::BooleanInput
def label_input(wrapper_options = nil)
if options[:label] == false || inline_label?
input(wrapper_options)
elsif nested_boolean_style?
html_options = label_html_options.dup
html_options[:class] ||= []
html_options[:class].push(boolean_label_class) if boolean_label_class
merged_input_options = merge_wrapper_options(input_html_options, wrapper_options)
build_hidden_field_for_checkbox +
#builder.label(label_target, html_options) {
template.content_tag( :div, class: 'switch-checkbox') {
build_check_box_without_hidden_field(merged_input_options) +
content_tag(:span, '', class:'slider round')
} + label_text
}
else
input(wrapper_options) + label(wrapper_options)
end
end
end
Notice that I only added the sibbling span in case there is a label not inline and with nested_boolean_style? = true.
Most of the code in the method is copy pasted from the original in simple form.

Related

rails bootstrap and aligning checkboxes

I'm trying to horizontally align a checkbox and it's label in Rails. I'm using bootstrap as well. any help is appreciated.
<p>
<%= label_tag(:relo, "Willing to relocate:", class: "checkbox") %>
<%= check_box_tag :relo, value = "true", checked = false, class: "" %>
</p>
Vertical-align sometimes will require two inline elements next to each other to function correctly.
'nowrap' means that the whole label text always stays next to the checkbox.
in your css file...
.checkboxes label {
display: block;
float: left;
padding-right: 10px;
white-space: nowrap;
}
.checkboxes input {
vertical-align: middle;
}
.checkboxes label span {
vertical-align: middle;
}
in your view...
<form>
<div class="checkboxes">
<label for="x"><input type="checkbox" id="x" /> <span>Label text x</span></label>
<label for="y"><input type="checkbox" id="y" /> <span>Label text y</span></label>
<label for="z"><input type="checkbox" id="z" /> <span>Label text z</span></label>
</div>
</form>

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.

Targeting dynamic class names in css/scss or JavaScript

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 {
//...
}
}

Simple form builder checkbox collection custom html input

With simple_form_for, how should one go about building something like a color selector? Imagine a page where the user can pick a number of colors to work with by checking checkboxes. I would like to present a little box with the color in it and a checkbox next to it so the user can pick the color by checking the check box. Something like this
<input type="checkbox" name="colors[test]"><div style="background-color: red; width: 20px; height: 20px"></div>
<input type="checkbox" name="colors[test]"><div style="background-color: green; width: 20px; height: 20px""></div>
<input type="checkbox" name="colors[test]"><div style="background-color: blue; width: 20px; height: 20px""></div>
You can add the html tags to the collection and define classes for each of them. And then style them accordingly. I am assuming you have a simple_form_for #color or something similar.
<%= f.input :test, :label => 'Choose a Color:', :collection =>{'<div class="red colorbox"></div>'.html_safe => 'red', '<div class="green colorbox"></div>'.html_safe => 'green', '<div class="blue colorbox"></div>'.html_safe => 'blue' }, :as => :check_boxes %>
In your stylesheet:
/* The colorbox will be under a label with collection_check_boxes class.*/
.collection_check_boxes {
width: 30px;
height: 20px;
}
.colorbox {
width: 20px;
height: 20px;
}
.red {background: red;}
.green {background: green;}
.blue {background: blue;}

customising the look of f.file.field in rails

<div id="photo_attachment_container">
<%= f.file_field :photo %>
</div>
Currently this just looks like a button, how can I add some css and customise the look (e.g dimensions background etc) of this button? Thanks
The HTML file field has been, and remains, one of the most least customizable of the HTML form controls. The other problem is that it is rendered so differently between browsers and OSes. The best way to style these controls is to render the file control as a transparent element on top of another button or set of elements that is styled the way you want. The file control does not need to be visible to be activated with a user click, but it does need to be on the top most layer (sending it click or focus events doesn't work in my tests).
Here's some example HTML:
<div id="test">
<div class="wrapper">
<input type="file" />
</div>
<button>Select a file</button>
</div>
The CSS renders the wrapper div and button as absolutely positioned elements. The button is visible and styled while the wrapper which contains the file field is transparent. I've set the wrapper field to reduce transparency when you hover over it to illustrate its positioning relative to the styled button underneath.
#test {
position: relative;
}
#test .wrapper {
opacity: 0;
cursor: pointer;
position: absolute;
top: 0;
z-index: 2;
}
#test .wrapper:hover {
opacity: 0.5;
}
#test button {
background-color: #ccc;
border: none;
color: #666;
padding: 3px 5px;
border-radius: 5px;
position: relative;
top: 0;
z-index: 1;
}
Example on JS fiddle.
http://jsfiddle.net/JgDuh/
EDIT:
To answer the question you asked in your comment, you would structure the above answer in your Rails view template like this:
<div id="photo_attachment_container">
<div class="wrapper">
<%= f.file_field :photo %>
</div>
</div>
This would render as (Note that I used user as the substitute for whatever model you passed in form_for):
<div id="photo_attachment_container">
<div class="wrapper">
<input type="file" id="user_photo" name="user[photo]" />
</div>
</div>

Resources