Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Show only first 5 divs accross multiple columns with show more button using JQuery

Tags:

jquery

How do I use JQuery to only show the first 5 times on each column & a "more" & "less" link to show more results.

What I am after at is similar to hide all li elements and show the first 2 and toggle them by button - BUT I need the more & less links to show/hide all the time slots for each doctor (ie: the more/less links should show/hide all the times over the 7 columns for each doctor with one click).

--THIS IS WHAT THE TIMES CURRENTLY LOOK LIKE--

--THIS IS THE RESULTS THAT I AM LOOKING FOR--

--MY HTML CODE--

<div class="appointmentDetails">
  <div class="staffInfo">
    <div>Dr John Doe</div>
  </div>
  <div class="appointmentInfo">
    <ul>
      <li>
        <div></div>
      </li>
      <li class="timeSlots bg">
        <div><a href="#">08:00</a></div>
        <div><a href="#">09:00</a></div>
        <div><a href="#">10:00</a></div>
        <div><a href="#">11:00</a></div>
        <div><a href="#">12:00</a></div>
        <div><a href="#">13:00</a></div>
        <div><a href="#">14:00</a></div>
        <div><a href="#">15:00</a></div>
        <div><a href="#">16:00</a></div>
        <div><a href="#">17:00</a></div>
        <div><a href="#">18:00</a></div>
      </li>
      <li class="timeSlots">
        <div><a href="#">08:00</a></div>
        <div><a href="#">09:00</a></div>
        <div><a href="#">10:00</a></div>
        <div><a href="#">11:00</a></div>
        <div><a href="#">12:00</a></div>
        <div><a href="#">13:00</a></div>
        <div><a href="#">14:00</a></div>
        <div><a href="#">15:00</a></div>
        <div><a href="#">16:00</a></div>
        <div><a href="#">17:00</a></div>
        <div><a href="#">18:00</a></div>
      </li>
      <li class="timeSlots bg">
        <div><a href="#">08:00</a></div>
        <div><a href="#">09:00</a></div>
        <div><a href="#">10:00</a></div>
        <div><a href="#">11:00</a></div>
        <div><a href="#">12:00</a></div>
        <div><a href="#">13:00</a></div>
        <div><a href="#">14:00</a></div>
        <div><a href="#">15:00</a></div>
        <div><a href="#">16:00</a></div>
        <div><a href="#">17:00</a></div>
        <div><a href="#">18:00</a></div>
      </li>
      <li class="timeSlots">
        <div><a href="#">08:00</a></div>
      </li>
      <li class="timeSlots bg">
        <div><a href="#">09:00</a></div>
      </li>
      <li class="timeSlots">
        <div><a href="#">09:00</a></div>
      </li>
      <li class="timeSlots bg">
        <div><a href="#">08:00</a></div>
      </li>
      <li>
        <div></div>
      </li>
    </ul>
  </div>
</div>
<div class="appointmentDetails">
  <div class="staffInfo">
    <div>Dr Tom Smith</div>
  </div>
  <div class="appointmentInfo">
    <ul>
      <li>
        <div></div>
      </li>
      <li class="timeSlots bg">
        <div><a href="#">08:00</a></div>
        <div><a href="#">09:00</a></div>
        <div><a href="#">10:00</a></div>
        <div><a href="#">11:00</a></div>
        <div><a href="#">12:00</a></div>
        <div><a href="#">13:00</a></div>
        <div><a href="#">14:00</a></div>
        <div><a href="#">15:00</a></div>
        <div><a href="#">16:00</a></div>
        <div><a href="#">17:00</a></div>
        <div><a href="#">18:00</a></div>
      </li>
      <li class="timeSlots">
        <div><a href="#">08:00</a></div>
        <div><a href="#">09:00</a></div>
        <div><a href="#">10:00</a></div>
        <div><a href="#">11:00</a></div>
        <div><a href="#">12:00</a></div>
      </li>
      <li class="timeSlots bg">
        <div><a href="#">10:00</a></div>
      </li>
      <li class="timeSlots">
        <div><a href="#">10:00</a></div>
      </li>
      <li class="timeSlots bg">
        <div><a href="#">10:00</a></div>
      </li>
      <li class="timeSlots">
        <div><a href="#">10:00</a></div>
      </li>
      <li class="timeSlots bg">
        <div><a href="#">10:00</a></div>
      </li>
      <li>
        <div></div>
      </li>
    </ul>
  </div>
</div>

--HERE IS A LIVE DEMO OF MY HTML/JAVASCRIPT/CSS--

http://jsfiddle.net/rR26n/

like image 949
MWD Avatar asked Nov 04 '22 03:11

MWD


2 Answers

Before we get to the "solution": Your markup is not very semantic. You are showing a list of times, so the times should be in a list, not DIVs. THose lists can be floated left or inline-blocked, and you can get rid of a lot of cruft in your markup.

Assuming you now have your times in lists like so:

<ul class="timeList">
   <li class="timeSlot">8:00</li>
   <li class="timeSlot">9:00</li>
   ...
   <li class="timeSlot">18:00</li>
</ul>

You want to do a few things:

  1. If a list has more than 5 slots, hide everything after #5, and add a MORE link.
  2. When a MORE link is clicked, show everything after #5, and change to a LESS link
  3. When a LESS link is clicked, hide everything after #5 and change back to a MORE link

I would suggest using jQuery if you are not already, as it makes things a great deal easier, so my suggestions on how to go about doing these things use it.

For number 1, you can hide elements after a certain index like so:

       jQuery(".someClass").children(":gt(4)").hide();

This will hide the 5th and further elements. However: this will hide all the other list's LI as well, because the above code puts all the children of every list in one big collection and then hides them ALL after the 5th element. So what you'll want to do is iterate over every list and hide only it's children.

I created an example of that here, turning them red instead of hiding them so you could visually see what is going on:

jQuery(function () {
    jQuery(".timeList").each(function () {
        jQuery(this).children(":gt(4)").css('color','red');
    });
});

You can see it in action here: http://jsfiddle.net/7PeVj/

For #2, you need to check if each list has more than 5, and add a MORE link. Since we are already iterating over each list, we can implement that code there. You can use the length of the children result to see if you had more than 5, and then use jQuery's append() function to add a button.

Here's an example of that. Notice we are now only asking for children that are timeSlots

    jQuery(".timeList").each(function () {
        // reference to the list
        var theList = jQuery(this);
        // reference to it's LIs that have .timeSlot
        var kids = theList.children(".timeSlot");
        // manipulate after element 5
        kids.filter(":gt(4)").css('color','red');
        //add a MORE link if we have more than 5
        if (kids.length > 5) {
            theList.append('<li class="slotMoreLess">MORE</li>');
        }
    });

Working example: http://jsfiddle.net/7PeVj/2/

Last you need to "hook up" the MORE / LESS to hide and show the items appropriately. You'll need to use jQuery's on() to attach handlers for these buttons, since they won't exist at page load.

Again, working example at: http://jsfiddle.net/7PeVj/4/

The hiding and showing you can do using what you saw in the above code. You can inspect and set the text() of the MORE list item to switch it back and forth between LESS and MORE and hide show as needed.

like image 52
veddermatic Avatar answered Nov 08 '22 06:11

veddermatic


Here you go : http://jsfiddle.net/eqmgy/

You need to add

            <div class="less"><a href="#">Less</a>
            </div>
            <div class="more"><a href="#">More</a>
            </div>

at the end of each <li class="timeSlots"></li>

and the js :

var showMore = function () {
    $(this).find('div').css('display', 'block');

    $(this).find('.more').css('display', 'none');
    $(this).find('.less').css('display', 'block');
    $(this).find('.less').click($.proxy(showLess, $(this)));

};

var showLess = function () {
    $(this).find('div').each(function(index, div) {
        if(index > 5) {
            $(div).css('display', 'none');
        }
    });

    $(this).find('.less').css('display', 'none');
    $(this).find('.more').css('display', 'block');

    $(this).find('.more').click($.proxy(showMore, $(this)));

};

$('.timeSlots').each(function (index, timeslot) {
    $.proxy(showLess, timeslot)();
});

EDIT :

Let's add the More/Less automatically instead, so it doesn't shoes up when number < 5 :

$('.timeSlots').each(function (index, timeslot) {
            if(timeslot.find('div').length > 5) {
                 timeslot.append('<div class="more"><a href="#">More</a></div>');
                 timeslot.append('<div class="less"><a href="#">Less</a></div>');
                 $.proxy(showLess, timeslot)();
            }
});
like image 26
Augustin Riedinger Avatar answered Nov 08 '22 04:11

Augustin Riedinger