New to rails, and am experimenting with changing default layouts.
It seems that the .field_with_errors class is always being added to my forms, when a field causes a validation error. The default scaffold CSS defined field_with_errors as:
.field_with_errors {
padding: 2px;
background-color: red;
display: table;
}
My question is: Why even use this .field_with_errors? Where is it even coming from? Same with a div with ID of notice to print success messages. Where is this coming from?... From my research both of these coming somewhere from ActionView::Helpers.
But what if I wanted to use my own custom styles for these? Do I have to write my own .fields_with_errors and notice classes in my application.css.scss file? I tried this and it works... But why do I have to jail myself to those class names? What if I wanted to call them something else? Can I do this?
Secondly, let's say I have my own custom CSS classes now (assuming it's possible -- which I hope it is)... What if I wanted to apply a bootstrap style to them? For example, bootstrap would use <div class="alert alert-success"> where Rails' scaffold would default to using <div id="#notice">... How can I make such changes in the most elegant way without simply making my own style with the same CSS code as Twitter's alert alert-success.... Isn't there a way in SASS (or through Rails somehow) to say, Success messages are printed with XYZ style and error fields are printed with ABC style... Like maybe in some config file?
Thanks!
Can I do this? yes.
The extra code is being added by ActionView::Base.field_error_proc. If you want to call something else and you're not using field_with_errors to style your form, You should override it in config/application.rb
config.action_view.field_error_proc = Proc.new { |html_tag, instance|
"<div class='your class'>#{html_tag}</div>".html_safe
}
Restart your server
Secondly, If you want to apply a bootstrap style to them, You can save your selection style on application_helper.rb
module ApplicationHelper
def flash_class(level)
case level
when :notice then "alert alert-info"
when :success then "alert alert-success"
when :error then "alert alert-error"
when :alert then "alert alert-error"
end
end
end
create file layouts/_flash_message.html.erb and paste this :
<div>
<% flash.each do |key, value| %>
<div class="<%= flash_class(key) %> fade in">
×
<%= value %>
</div>
<% end %>
</div>
and to call the flash you just render in view
<%= render 'layouts/flash_messages' %>
Example
On accounts_controller.rb create action
def create
#account = Account.new(params[:account])
if #account.save
# using :success if #account.save
flash[:success] = "Success."
redirect_to accounts_url
else
flash[:alert] = "Failed."
render :new
end
end
Put on top of accounts/index.html.erb and on top of form in accounts/_form.html.erb
<%= render 'layouts/flash_messages' %>
Result on index :
<div class="alert alert-success">
<button type="button" class="close" data-dismiss="alert">×</button>
Success.
</div>
Result on form :
<div class="alert alert-error">
<button type="button" class="close" data-dismiss="alert">×</button>
Failed.
</div>
#anonymousxxx answer seems to be correct in my opinion.
I would recommend you to use the twitter-bootstrap-rails gem (https://github.com/seyhunak/twitter-bootstrap-rails) for your css. check out the readme on github, this gem is really convenient.
Related
Is it possible to render a template, or even just a partial, from within the context passed to a top level template? It seems like this might require recursive rendering, but maybe I'm missing something.
The example below demonstrates this using Bootstrap.
Say this is my top level template:
<div class="panel">
<div class="panel-body">
{{{description}}}
</div>
</div>
And my context is:
{
description: "\
Some text before the warning.\
<div class=\"alert alert-warning\" role=\"alert\">\
<span class=\"glyphicon glyphicon-warning-sign\" aria-hidden=\"true\"> </span>\
My warning here.\
</div>\
Some text after the warning."
}
What I'd like to do is separate the alert into a partial for a number of reasons:
Arbitrary placement within surrounding text
Can make partials for types other than warning (danger, info, etc.)
Can add as many as needed interspersed in the context string
For these reasons, it seems like it's not possible to put it into the top level template.
The partial would look something like this:
<script id="partial-warning-template" type="text/x-handlebars-template">
<div class="alert alert-warning" role="alert">
<span class="glyphicon glyphicon-warning-sign" aria-hidden="true"> </span>
{{{warning-message}}}
</div>
</script>
Once this is in place, I would be able to use it like so:
{
description: "\
Some text before the warning.\
{{> partial-warning-template \"My warning here.\"}}\
Some text after the warning.\
{{> partial-warning-template \"Now adding a second warning.\"}}"
}
Maybe I'm missing something fundamental - is there a more idiomatic way of doing this?
You won't be able to include the partial blocks in the description value and expect them to be evaluated as partials by the top level template method; the entire description string will be spat out as a single literal string.
What you would need to do is to have the partials evaluated before you pass the context object with description to the top level template method.
If you have pre-compiled your partial in something like the following manner:
Handlebars.registerPartial('warn', Handlebars.compile(document.getElementById('partial-warning-template').innerHTML));
Then you will be able to call this partial when you construct your description string:
{
description: 'Some text before the warning.' +
Handlebars.partials.warn({ 'warning-message': 'My warning here.' }) +
'Some text after the warning.' +
Handlebars.partials.warn({ 'warning-message': 'Now adding a second warning.' })
}
How do i add some CSS to the Scala Helpers, and is it possible to remove the "Required" and "Numeric" text under the textfield?
#inputText(advForm("weeknr"))
#inputText(advForm("jaar"))
#inputText(advForm("datum"))
--------------------EDIT 1------------------
When I add my own CSS, im not getting the error warnings that i used to get when I try to upload an empty form, the text used to turn red. This is the code I changed
MyPlainFieldConstructor.scala.html(only 2 lines of code):
#(elements: helper.FieldElements)
#elements.input
advPlaatsen2.scala.html:
Added this line of code
#implicitField = #{ FieldConstructor(myPlainFieldConstructor.f) }
and this is how i placed the CSS(Foundation 5):
<div class="row collapse">
<div class="small-2 columns">
<span class="prefix">Email</span>
</div>
<div class="small-4 left columns">
#inputText(advForm("email"),
'id -> "right-label",
'placeholder -> "")
</div>
</div>
This way the forms looks how I want it to look but it doesnt show me errors and it doesnt even upload my files
but when i remove this line of code:(which is above the #import helper._)
#implicitField = #{ FieldConstructor(myPlainFieldConstructor.f) }
the form works as it should but looks really bad:
To customize the html and styles of a field you can write your own field constructor. Take a look to play docs here.
I'd like to know if it's possible to pass an array to a rails image tag. The array would include a series of png images and I'd like for the view to display those images on rotation.
Does anyone know how to do that?
This does not work.
<div class="img-circle"><%= image_tag ["researcher.png", "book.png"], size: "150x150" %></div>
I can't seem to find instructions (the rails guides suggest that you can pass an array to the video tag helper so I was wondering if there were a way to do the same thing with images).
Thank you very much.
To extend #Rich Peck's answer, what about creating a helper to do that, it's cleaner I think :
module ApplicationHelper
def images_tag(array_of_images, options={})
images = []
if array_of_images.is_a? Array
array_of_images.each do |image|
images << image_tag(image, size: options[:size], class: options[:class])
end
end
content_tag :div, images.join("\n").html_safe, class: "img-circle"
end
end
then, in your view :
<%= images_tag ["researcher.png", "book.png"], size: "150x150", class: "class-img" %>
will output :
<div class="img-circle">
<img alt="researcher" class="class-img" height="150" src="/assets/researcher.png" width="150">
<img alt="book" class="class-img" height="150" src="/assets/book.png" width="150">
</div>
Interesting - I think you're only able to use one image per image_tag currently
As you can see from the API, the method is a way to post the <img src=""> HTML tag, and I believe that it only does this once (does not replicate for multiple images)
A way to achieve what you want would be to use a loop, although it's kind of bloated for what you're looking for here:
<% images = %w(reearcher.png book.png) %>
<% for image in images do %>
<%= image_tag image, size: "150x150" %>
<% end %>
Ok. I can't figure this out. The problem is that #extend is not working in css. I have css:
#import "bootstrap";
.field_with_errors {
#extend .control-group;
#extend .error;
}
It doesn't highlight the fields that have div class .field_with_errors. I can't figure out why, it worked on other apps I made. If I write in CSS something like color: #f00; - this works. It just doesn't #extend for some reason. Any ideas?
Form:
<h1>Report</h1>
<div class="row">
<div class="span6 offset3">
<%= form_for(#problem) do |f| %>
<%= render 'shared/error_messages' %>
<%= f.label :name, raw("Your name:") %>
<%= f.text_field :name %>
<%= f.label :email, raw("E-mail address (for confirmation):") %>
<%= f.text_field :email %>
<%= f.label :description, raw("Enter a description of the problem:") %>
<%= f.text_area :description %>
<%= f.submit "Submit", class: "btn btn-large btn-primary" %>
<% end %>
</div>
</div>
Probably a dumb question, I must've missed something. I just don't know what it is and would really like this to work like it did before. Any help appreciated!
Edit:
After looking at bootstrap-sass files, I realized that I am able to #extend classes that are in the files there (#extend .form-control works for instance). So it must be that .error and .control-group is not there!! Where it went I still can't figure out, unless they just changed it like a week ago. :/
As the comment of 'soup' points out, the problem is caused by installing Bootstrap 3 and then calling Bootstrap 2 class names. The class names have changed (have a look here). The correct code is:
.field_with_errors {
#extend .has-error;
}
And accordingly the error message has to be wrapped in (also look here):
div class="alert alert-danger"
So in your app\views\shared\_error_messages.html.erb-partial (you're propably reusing code from Michael Hartl's Rails Tutorial) change div class="alert alert-error" to div class="alert alert-danger". Because your code is so far off, I give you a version adapted for Bootstrap 3:
<h1>Report</h1>
<div class="row">
<div class="col-md-6 col-md-offset-3">
<%= form_for(#problem) do |f| %>
<%= render 'shared/error_messages' %>
<div class="form-group">
<%= f.label :name, raw("Your name:") %>
<%= f.text_field :name, class: 'form-control' %>
</div>
<div class="form-group">
<%= f.label :email, raw("E-mail address (for confirmation):") %>
<%= f.text_field :email, class: 'form-control' %>
</div>
<div class="form-group">
<%= f.label :description, raw("Enter a description of the problem:") %>
<%= f.text_area :description, class: 'form-control' %>
</div>
<%= f.submit "Submit", class: "btn btn-lg btn-primary" %>
<% end %>
</div>
</div>
In case anyone lands on this (like I did) because it isn't working with LESS, here's what I had to do:
.field_with_errors .form-control {
&:extend(.has-error .form-control);
}
.field_with_errors .form-control:focus {
&:extend(.has-error .form-control:focus);
}
When I tried it with:
.field_with_errors {
&:extend(.has-error);
}
which is the equivalent of the recommended way I found to use the bootstrap 3 style for errors, LESS wasn't doing anything. It may have something to do with the fact that the selectors in bootstrap 3 that mention has-error always have it combined with something else, e.g.:
.has-error .form-control {
Anyway - the above solution worked for me so hopefully it helps someone else.
I figured it out. This has to do with Twitter-Bootstrap, which has a class .alert in it. That is the class responsible for showing errors with correct styling.
Bootstrap installs who knows where and is easiest to access through Developer Tools in browser (that sucks). I couldn't find where the source of the gem is located (it pointed me to folder that is not a folder). So I copied twitter css files from github directly into my app -> vendor/assets/stylesheets . Now I can deal with the problem.
I changed the style of .alert class inside one of bootstrap files (_alerts.scss) and added extra classes in my custom.css.scss file to make border around inputs red on errors.
Somehow this whole thing worked better in previous apps I made, I think this has to do with changes they made to bootstrap and possibly the fact that I messed with bootstrap's original design (like a full-width header).
The biggest thing that led me to solution was that the class is .alert and not .error like I thought. Also big thanks to browser developer tools, I couldn't find my files without you.
Edit:
Here's the download instructions on Bootstrap to get the files:
http://getbootstrap.com/getting-started/#download
Upgrading your code as per 3.x should work
.field_with_errors {
#extend .has-error;
}
This error causes because in application.scss there is the folowing line
*= require_tree .
and it is placed before the #import "bootstrap".
So, _custom.scss has been included before Bootstrap.
The easiest way to fix it -- what worked for me -- is to add !optional to both classes:
.field_with_errors {
#extend .control-group !optional;
#extend .error !optional;
}
OK, after chasing down this issue for a couple days, I figured out what the problem is.
You need to include bootstrap at the top your custom.css.scss file.
#import 'bootstrap';
My guess would be that this includes all the classes in the custom file so that you can reference them later. I assume if you use some bootstrap gem it will make them globally available, but if you do it vanilla like I did then you need to use the code above.
I want to define the width of a status bar dynamically.
First I define the variable:
<% target = (clicks/total_clicks)*100 %>
Then I try to embed the ruby code into a css width tag:
<div class="bar" style="width: <%= target %>%">
However, the html output looks like this
<div class="progress progress-striped">
<div class="bar" style="width: 0%"></div>
</div>
I tried to convert the target var as a string:
<% target = ((clicks/total_clicks)*100).to_s %>
I obviously also tried to assign a not-dynamic value as well:
<% target = 40.to_s %>
But with no success.
How can I embed a ruby var into a CSS style tag?
Thanks for any help.
You are getting 0 because of how you are using the numbers. You are using Integers. Do this:
<%= target = (Float(10)/Float(20))/100 %>
Using floats will allow you to get the percentage you are using. When you use Integers, it will generally round the number off. Hope this helps.
EDIT:
You can also use the .to_f method as well, instead of Float