Mark
Mark

Reputation: 163

How to display radio buttons as Bootstrap buttons that change color in Rails?

I am creating a simple survey app in Rails that displays a question and answers to select among (only one may be selected). I would like to:

I am able to display the radios as Bootstrap buttons and vertically:

buttons displaying correctly

Bootstrap offers data-toggle="button" to toggle button state. However, when I add "data-toggle: button" to the radio input tag, nothing happens. When I add it to the radio button's label tag, with a CSS selector on .btn.active to change the color, the button changes color but is no longer selected:

misbehaving buttons

How can I make the color highlighting and radio button work correctly? Thanks!

_form.html.erb excerpt:

  <% @question.answers.each do |a| %>
    <div class='answer-body form-group' data-toggle: "buttons">
        <%= f.radio_button :answer_id, a.id %>
        <%= f.label :answer_id, a.body, { value: a.id, class: 'btn btn-primary', "data-toggle": "button" } %>
    </div>
  <% end %>

SCSS

.btn.active {
  background-color: #5cb85c;
}

Generated HTML

<div class='answer-body form-group' data-toggle: "buttons">
    <input type="radio" value="5" name="user_response[answer_id]" id="user_response_answer_id_5" />
    <label class="btn btn-primary" data-toggle="button" for="user_response_answer_id_5">Arf! Love them.</label>
</div>

<div class='answer-body form-group' data-toggle: "buttons">
    <input type="radio" value="6" name="user_response[answer_id]" id="user_response_answer_id_6" />
    <label class="btn btn-primary" data-toggle="button" for="user_response_answer_id_6">They&#39;re okay</label>
</div>

<div class='answer-body form-group' data-toggle: "buttons">
    <input type="radio" value="7" name="user_response[answer_id]" id="user_response_answer_id_7" />
    <label class="btn btn-primary" data-toggle="button" for="user_response_answer_id_7">Bah humbug</label>
</div>

Upvotes: 1

Views: 1712

Answers (2)

Sia
Sia

Reputation: 9211

I'm going to attempt to answer your question with what I think you want.

First, I think you need to use the JavaScript button group from Bootstrap in order to get the behavior you want. You can change them to vertical, but you will have to manually add overriding style to put spaces between them.

Do you actually want the radios still showing or not? If not, this code might suffice (minus the CSS to change color of active state and increase spacing between buttons)

Rails html.erb

  <div class="field form-group">
    <%= f.label :answer_id %><br>
    <div class="btn-group-vertical" data-toggle="buttons">
      <%= f.label :answer_id, class: "btn btn-primary active" do %>
        <%= f.radio_button :answer_id, 5, checked: true %>
        Arf! Love them.
      <% end %>
      <%= f.label :answer_id, class: "btn btn-primary" do %>
        <%= f.radio_button :answer_id, 6 %>
        They're okay.
      <% end %>
      <%= f.label :answer_id, class: "btn btn-primary" do %>
        <%= f.radio_button :answer_id, 7 %>
        Bah humbug.
      <% end %>
    </div>
  </div>

Compiled html

  <div class="field form-group">
    <label for="user_response_answer_id">Answer</label><br>
    <div class="btn-group-vertical" data-toggle="buttons">
      <label class="btn btn-primary active" for="user_response_answer_id">
        <input type="radio" value="5" checked="checked" name="user_response[answer_id]" id="user_response_answer_id_5" />
        Arf! Love them.
</label>      <label class="btn btn-primary" for="user_response_answer_id">
        <input type="radio" value="6" name="user_response[answer_id]" id="user_response_answer_id_6" />
        They're okay.
</label>      <label class="btn btn-primary" for="user_response_answer_id">
        <input type="radio" value="7" name="user_response[answer_id]" id="user_response_answer_id_7" />
        Bah humbug.
</label>    </div>
  </div>

I don't have enough reputation points to post a screenshot! If you like my answer, I think I will have enough and then I can edit this to include the screenshot.

I apologize if there are any typos - I was using an existing app where the table is Locations and the field was distance, so if you see "location" or "distance" anywhere, just substitute "user_response" and "answer_id"

Upvotes: 3

shreyansh
shreyansh

Reputation: 1687

This may be helpful for you

<body>
<div class='answer-body form-group' >
    <input type="radio"  value="5" name="user_response[answer_id]" id="user_response_answer_id_5" />
    <label class="btn btn-primary" data-toggle="button" id="btn1" onclick="func(this.previousSibling.previousSibling.id, this.id)" for="user_response_answer_id_5">Arf! Love them.</label>
</div>

<div class='answer-body form-group' >
    <input type="radio" value="6" name="user_response[answer_id]" id="user_response_answer_id_6" />
    <label class="btn btn-primary" data-toggle="button" id="btn2" onclick="func(this.previousSibling.previousSibling.id, this.id)" for="user_response_answer_id_6">They&#39;re okay</label>
</div>

<div class='answer-body form-group' >
    <input type="radio" value="7" name="user_response[answer_id]" id="user_response_answer_id_7" />
    <label class="btn btn-primary" data-toggle="button" id="btn3" onclick="func(this.previousSibling.previousSibling.id, this.id)" for="user_response_answer_id_7">Bah humbug</label>
</div>
<script>
     function func(sender, obj)
    {

      document.getElementById(sender).checked=true;
      document.getElementById(obj).style.background='#5cb85c';

    }
    </script>
  </body>

Upvotes: 0

Related Questions