sixty4bit
sixty4bit

Reputation: 7956

.toggle() a `hidden` element without pushing other elements the wrong way (Rails, Bootstrap, jQuery)

I have 9 buttons arranged in a 3x3 square. A user should be able to click one button to cause a text_field to appear underneath. Here is what it looks like with all of the text_fields showing:

buttons with all fields showing

I'm giving each of the text fields a class that includes display: none so that on page load the set of buttons looks like this:

collapsed

I am trying to get the CSS/jQuery right so that clicking on one button causes its text field to drop down. This should cause the other two rows beneath to move down but unfortunately that's not happening at the moment.

Here is the Ruby/Haml code that is generating the buttons and text fields (row/column classes are Bootstrap):

.row
  - Category.all.each do |cat|
    .col-sm-4
      .btn.btn-default.category_button{:id => "#{cat.name}_button"}= cat.name.capitalize
      = f.text_area :categories, rows: '2', id: "#{cat.name}_input", class: "category_input"

Here is the CSS for the category_input class that controls the text_areas:

.category_input {
    width: 100%;
    resize: none;
    display: none;
}

Here is the jQuery that I'm using to hide and show (in progress, only meant to work for the "Moving" button right now:

:javascript
  $(document).ready(function(){
    $("#moving_button").click(function(){
      $("#moving_input").toggle();
    });
  });

When the text_area for "Moving" appears, it is pushing the Yard and Painting buttons to the side like this:

pushing to the side

There should be a text_area beneath Moving, empty space beneath Cleaning and Events, and the other 6 buttons from the bottom two rows should still be arranged as before underneath (except now 3x2).

I'm not sure whether I need to modify the Ruby, the CSS, or the jQuery to make this work. Thank you in advance for any help!

EDIT

Adding HTML output per request:

 <div class='row'>
                          <div class='col-sm-4'>
                            <div class='btn btn-default category_button' id='moving_button'>Moving</div>
                            <textarea class="category_input" cols="40" id="moving_input" name="worker[gender]" rows="2"></textarea>
                          </div>
                          <div class='col-sm-4'>
                            <div class='btn btn-default category_button' id='cleaning_button'>Cleaning</div>
                            <textarea class="category_input" cols="40" id="cleaning_input" name="worker[gender]" rows="2"></textarea>
                          </div>
                          <div class='col-sm-4'>
                            <div class='btn btn-default category_button' id='events_button'>Events</div>
                            <textarea class="category_input" cols="40" id="events_input" name="worker[gender]" rows="2"></textarea>
                          </div>
                          <div class='col-sm-4'>
                            <div class='btn btn-default category_button' id='yard_button'>Yard</div>
                            <textarea class="category_input" cols="40" id="yard_input" name="worker[gender]" rows="2"></textarea>
                          </div>
                          <div class='col-sm-4'>
                            <div class='btn btn-default category_button' id='organizing_button'>Organizing</div>
                            <textarea class="category_input" cols="40" id="organizing_input" name="worker[gender]" rows="2"></textarea>
                          </div>
                          <div class='col-sm-4'>
                            <div class='btn btn-default category_button' id='tutoring_button'>Tutoring</div>
                            <textarea class="category_input" cols="40" id="tutoring_input" name="worker[gender]" rows="2"></textarea>
                          </div>
                          <div class='col-sm-4'>
                            <div class='btn btn-default category_button' id='painting_button'>Painting</div>
                            <textarea class="category_input" cols="40" id="painting_input" name="worker[gender]" rows="2"></textarea>
                          </div>
                          <div class='col-sm-4'>
                            <div class='btn btn-default category_button' id='tech_button'>Tech</div>
                            <textarea class="category_input" cols="40" id="tech_input" name="worker[gender]" rows="2"></textarea>
                          </div>
                          <div class='col-sm-4'>
                            <div class='btn btn-default category_button' id='anything_button'>Anything</div>
                            <textarea class="category_input" cols="40" id="anything_input" name="worker[gender]" rows="2"></textarea>
                          </div>
                        </div>
                      </div>
                    </div>

Upvotes: 0

Views: 488

Answers (3)

Liam
Liam

Reputation: 2837

Correct, you need to use 3 different rows and manage the number of rows to show based on column count.

Got it working here

http://jsbin.com/hipoyusedeci/1/edit?html,css,js,output

http://jsbin.com/hipoyusedeci/1/

Upvotes: 1

jrproctor
jrproctor

Reputation: 61

If you want the items in each rows to line up, you need to arrange them in three rows like this:

<div class='row'>
    <div class='col-sm-4'>
        <div class='btn btn-default category_button' id='moving_button'>Moving</div>
        <textarea class="category_input" cols="40" id="moving_input" name="worker[gender]" rows="2"></textarea>
    </div>
    <div class='col-sm-4'>
        <div class='btn btn-default category_button' id='cleaning_button'>Cleaning</div>
        <textarea class="category_input" cols="40" id="cleaning_input" name="worker[gender]" rows="2"></textarea>
    </div>
    <div class='col-sm-4'>
        <div class='btn btn-default category_button' id='events_button'>Events</div>
        <textarea class="category_input" cols="40" id="events_input" name="worker[gender]" rows="2"></textarea>
    </div>
</div>

<div class="row">
    <div class='col-sm-4'>
        <div class='btn btn-default category_button' id='yard_button'>Yard</div>
        <textarea class="category_input" cols="40" id="yard_input" name="worker[gender]" rows="2"></textarea>
    </div>
    <div class='col-sm-4'>
        <div class='btn btn-default category_button' id='organizing_button'>Organizing</div>
        <textarea class="category_input" cols="40" id="organizing_input" name="worker[gender]" rows="2"></textarea>
    </div>
    <div class='col-sm-4'>
        <div class='btn btn-default category_button' id='tutoring_button'>Tutoring</div>
        <textarea class="category_input" cols="40" id="tutoring_input" name="worker[gender]" rows="2"></textarea>
    </div>
</div>

<div class="row">
    <div class='col-sm-4'>
        <div class='btn btn-default category_button' id='painting_button'>Painting</div>
        <textarea class="category_input" cols="40" id="painting_input" name="worker[gender]" rows="2"></textarea>
    </div>
    <div class='col-sm-4'>
        <div class='btn btn-default category_button' id='tech_button'>Tech</div>
        <textarea class="category_input" cols="40" id="tech_input" name="worker[gender]" rows="2"></textarea>
    </div>
    <div class='col-sm-4'>
        <div class='btn btn-default category_button' id='anything_button'>Anything</div>
        <textarea class="category_input" cols="40" id="anything_input" name="worker[gender]" rows="2"></textarea>
    </div>
</div>

If you want the columns to remain compact, and the items in each row don't need to line up, then arrange them in three columns like this:

<div class='row'>
    <div class='col-sm-4'>
        <div>
            <div class='btn btn-default category_button' id='moving_button'>Moving</div>
            <textarea class="category_input" cols="40" id="moving_input" name="worker[gender]" rows="2"></textarea>
        </div>
        <div>
            <div class='btn btn-default category_button' id='cleaning_button'>Cleaning</div>
            <textarea class="category_input" cols="40" id="cleaning_input" name="worker[gender]" rows="2"></textarea>
        </div>
        <div>
            <div class='btn btn-default category_button' id='events_button'>Events</div>
            <textarea class="category_input" cols="40" id="events_input" name="worker[gender]" rows="2"></textarea>
        </div>
    </div>

    <div class='col-sm-4'>
        <div>
            <div class='btn btn-default category_button' id='yard_button'>Yard</div>
            <textarea class="category_input" cols="40" id="yard_input" name="worker[gender]" rows="2"></textarea>
        </div>
        <div>
            <div class='btn btn-default category_button' id='organizing_button'>Organizing</div>
            <textarea class="category_input" cols="40" id="organizing_input" name="worker[gender]" rows="2"></textarea>
        </div>
        <div>
            <div class='btn btn-default category_button' id='tutoring_button'>Tutoring</div>
            <textarea class="category_input" cols="40" id="tutoring_input" name="worker[gender]" rows="2"></textarea>
        </div>
    </div>

    <div class='col-sm-4'>
        <div>
            <div class='btn btn-default category_button' id='painting_button'>Painting</div>
            <textarea class="category_input" cols="40" id="painting_input" name="worker[gender]" rows="2"></textarea>
        </div>
        <div>
            <div class='btn btn-default category_button' id='tech_button'>Tech</div>
            <textarea class="category_input" cols="40" id="tech_input" name="worker[gender]" rows="2"></textarea>
        </div>
        <div>
            <div class='btn btn-default category_button' id='anything_button'>Anything</div>
            <textarea class="category_input" cols="40" id="anything_input" name="worker[gender]" rows="2"></textarea>
        </div>
    </div>
</div>

Upvotes: 0

sixty4bit
sixty4bit

Reputation: 7956

I was able to grasp the conceptual problem thanks to the help in the comments. What I needed was a new Bootstrap .row to appear after every three buttons so that every horizontal grouping of three buttons would actually be in the same row in the code. This would cause clicking one button to push the entire row down. I was able to accomplish this by adding the following conditional statement in the Ruby code:

.row
  - Category.all.each do |cat|
    - if cat.id == 1 || cat.id == 4 || cat.id == 7  # Create new .row after every 3 buttons
      .row
    .col-sm-4
      .btn.btn-default.category_button{:id => "#{cat.name}_button"}= cat.name.capitalize
      = f.text_area :gender, rows: '2', id: "#{cat.name}_input", class: "category_input"

The only thing this is lacking is an elegant way to anticipate the addition of new categories.

Upvotes: 1

Related Questions