Ruby field_with_errors doesn't @extend .contro

2019-02-12 11:09发布

问题:

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. :/

回答1:

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>


回答2:

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.



回答3:

Upgrading your code as per 3.x should work

.field_with_errors {
  @extend .has-error;
}


回答4:

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.



回答5:

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



回答6:

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;
}


回答7:

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.