Welcome to the Treehouse Community

The Treehouse Community is a meeting place for developers, designers, and programmers of all backgrounds and skill levels to get support. Collaborate here on code errors or bugs that you need feedback on, or asking for an extra set of eyes on your latest project. Join thousands of Treehouse students and alumni in the community today. (Note: Only Treehouse students can comment or ask questions, but non-students are welcome to browse our conversations.)

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and a supportive community. Start your free trial today.

JavaScript

Brandon Stiles
Brandon Stiles
12,305 Points

Sliding paragraphs under icon row using jQuery (and Bootstrap)

I've tried this for over an hour, but can't figure out the best way to code it in jQuery:

SETUP: I have 8 clikckable icons. On bigger screens, they're grouped three in a row, three in a row, then 2 in a row. On mobile screens, the icons are one on top of the other, vertically. See this as an example: http://winter-construction.com/services/

PROBLEM: When I click an icon, I want a paragraph to toggle in explaining the icon. However, here's the catch: On mobile screens, I want the individual paragraph to toggle in below each individual icon. On bigger screens, I want the individual paragraph to toggle in below the row of icons, so they don't move around a lot.

How can I do this?? Would I append it to the icon in small screens, and append it to the row div in big screens? Code below:

HTML:

<!--------------- Services  ----------------------------->
<!----- ROW 1 ----->
    <div class="row col-xs-12">
    <!--- ICON 1 ----->
      <div class="col-sm-4 col-xs-12 text-xs-center m-b-2" id="serviceOption1">
        <a><i class="fa fa-laptop fa-5x m-b-1" aria-hidden="true"></i></a>
        <h5>Icon 1</h5>
      </div>
    <!--- ICON 2 ----->       
      <div class="col-sm-4 col-xs-12 text-xs-center m-b-2" id="serviceOption2">
        <a><i class="fa fa-laptop fa-5x m-b-1" aria-hidden="true"></i></a>
        <h5>Icon 2</h5>
      </div>
    <!--- ICON 3 ----->
      <div class="col-sm-4 col-xs-12 text-xs-center m-b-2" id="serviceOption3">
        <a><i class="fa fa-laptop fa-5x m-b-1" aria-hidden="true"></i></a>
        <h5>Icon 3</h5>
      </div>
    </div>

    <!--- ROW 2 ----->
    <div class="row col-xs-12">
    <!--- ICON 4 ----->
      <div class="col-sm-4 col-xs-12 text-xs-center m-b-2" id="serviceOption4">
        <a><i class="fa fa-laptop fa-5x m-b-1" aria-hidden="true"></i></a>
        <h5>Icon 4</h5>
      </div>
     <!--- ICON 5 ----->  
      <div class="col-sm-4 col-xs-12 text-xs-center m-b-2" id="serviceOption4">
        <a><i class="fa fa-laptop fa-5x m-b-1" aria-hidden="true"></i></a>
        <h5>Icon 5</h5>
      </div>
     <!--- ICON 6 ----->
      <div class="col-sm-4 col-xs-12 text-xs-center m-b-2" id="serviceOption4">
        <a><i class="fa fa-laptop fa-5x m-b-1" aria-hidden="true"></i></a>
        <h5>Icon 6</h5>
      </div>
    </div>

    <!----- ROW 3 ------->
    <div class="row">
    <!--- ICON 7 ----->
      <div class="col-sm-4 col-sm-offset-1 col-xs-12 text-xs-center m-b-2" id="serviceOption4">
        <a><i class="fa fa-laptop fa-5x m-b-1" aria-hidden="true"></i></a>
        <h5>Icon 7</h5>
      </div>
    <!--- ICON 8 ----->
      <div class="col-sm-4 col-sm-offset-1 col-xs-12 text-xs-center m-b-2" id="serviceOption4">
        <a><i class="fa fa-laptop fa-5x m-b-1" aria-hidden="true"></i></a>
        <h5>Icon 8</h5>
      </div>
    </div>

    <div id="iconParagraphs" class="col-xs-10 col-xs-offset-1 p-t-1">
        <div class="serviceOption1 text"> Text 1 </div>
        <div class="serviceOption2 text"> Text 2 </div>
        <div class="serviceOption3 text"> Text 3 </div>
        <div class="serviceOption4 text"> Text 4 </div>
        <div class="serviceOption5 text"> Text 5 </div>
        <div class="serviceOption6 text"> Text 6 </div>
        <div class="serviceOption7 text"> Text 7 </div>
        <div class="serviceOption8 text"> Text 8 </div>
    </div>

Here's the CSS (just hides the paragraphs):

.text{
   display: none;
 }

and my JQuery skeleton. This might not be the quickest way, so if there's something faster, let me know:

// When sceen is less than 544 px, or 'mobile':
// When icon is clicked,
$('a').click(function(){
    // Get div with matching class of this element's ID
    // Append that div after this anchor element
// When screen is 544px or greater:
// When icon is clicked,
    // Get div with matching class of this element's ID
    // Append it after this anchor element's row   
   }); // end SERVICES functiond

1 Answer

Steven Parker
Steven Parker
220,416 Points

This was a fun exercise!   :smile:   I have not done much DOM pruning and grafting before.

You mostly had everything in the commented pseudocode, I just implemented what you had specified (with minor differences). One change was moving the break point to 768, to match where the columns changed.

// When icon is clicked,
$('a').click(function(e) {
  e.preventDefault();
  // Get div with matching class of this element's ID
  var mydiv = $(this).parent();
  var mydivid = mydiv.get(0).id;
  var text = $('.' + mydivid);
  // When sceen is less than 768px:
  if ($(document).width() < 768) {
    // Append that div after this anchor element
    text.detach().appendTo(mydiv);
    // When screen is 768px or greater:
  } else {
    // Append it after this anchor element's row   
    var row = mydiv.parent();
    text.detach().appendTo(row);
  }
  text.toggle(); // now toggle the visibility
}); // end function

This is a very basic version. If you change the window size while a text paragraph is visible, it will be in the wrong place until you toggle it off and on again. Also, there's no "radio button" operation to make sure only one paragraph is "on" at a time. You could also check to see if visibility is going on or off, and only move it when going on. These are examples of things you may want to add later.

Brandon Stiles
Brandon Stiles
12,305 Points

Steven Parker , you old Javasript Jedi! You've done it again.

Looking at it from there, it's so easy. Dang.....

And I see what you're saying about not hiding the other divs when you click on a new button. I tried hiding the other siblings in '#iconParagraphs' when one was clicked so that I could hide them, but it wouldn't let me reclick them after I did so. How could I implement it so only one paragraph is on at a time?

Thanks again, man!

Steven Parker
Steven Parker
220,416 Points

Okay, now you have to see if it's on or not already. Replace text.toggle(); with this:

  // if it is hidden now
  if (text.css('display') == 'none') {
    $(".text").hide();  // hide the rest
    text.show();        // and show this one
  } else {
    $(".text").hide();  // just hide them all
  }

But now you could move all that other code inside this test, so DOM alteration is only done if you're about to make one visible.