And you can shorten it slightly:

$('.main ul').each(function(){
        var lis = $(this).append($('<li>').text('More').click(function(){
                lis.toggle();
                $(this).text($(this).text() === 'More' ? 'Less' : 'More');
        })).find('li:gt(9):not(:last)').hide();
});

I had the $this left over from a different approach :P

On Jun 19, 3:59 pm, mkmanning <michaell...@gmail.com> wrote:
> Try this:
>
> $('.main ul').each(function(){
>         var $this = $(this), lis = $this.append($('<li>').text('More').click
> (function(){
>                 lis.toggle();
>                 $(this).text($(this).text() === 'More' ? 'Less' : 'More');
>         })).find('li:gt(9):not(:last)').hide();
>
> });
>
> Since you have more than one '.main ul' you'll need the .each you had
> to keep the li's separate. Using li:gt(9):not(:last) selects  any li's
> at index 10 or above (zero indexed) and hides them, excluding the last
> li which is the newly added link for more/less.
>
> Since the link doesn't go anywhere, you're not creating a usability
> problem by assigning the click event to the li itself (although you
> can add an anchor and adjust the script accordingly if desired).
>
> On Jun 19, 2:56 pm, bombaru <bomb...@gmail.com> wrote:
>
>
>
> > Thanks Karl... I'm not familiar with slice() but will definitely read
> > up on it.  The problem I'm having with this approach is that every LI
> > after the 10th one is being hidden.
>
> > Here's an example of what the HTML looks like without any JS applied
> > to it:
>
> > <ul id="narrow-search">
> >   <li class="main">
> >   Category
> >     <ul>
> >       <li>Category Name</li>
> >       <li>Category Name</li>
> >       <li>Category Name</li>
> >       <li>Category Name</li>
> >       <li>Category Name</li>
> >       <li>Category Name</li>
> >       <li>Category Name</li>
> >       <li>Category Name</li>
> >       <li>Category Name</li>
> >       <li>Category Name</li>
> >       <li>Category Name</li>
> >       <li>Category Name</li>
> >       <li>Category Name</li>
> >       <li>Category Name</li>
> >       <li>Category Name</li>
> >       <li>Category Name</li>
> >       <li>Category Name</li>
> >       <li>Category Name</li>
> >     </ul>
> >   </li>
> >   <li class="main">
> >   Brand
> >     <ul>
> >       <li>Brand Name</li>
> >       <li>Brand Name</li>
> >       <li>Brand Name</li>
> >       <li>Brand Name</li>
> >       <li>Brand Name</li>
> >       <li>Brand Name</li>
> >       <li>Brand Name</li>
> >       <li>Brand Name</li>
> >       <li>Brand Name</li>
> >       <li>Brand Name</li>
> >       <li>Brand Name</li>
> >       <li>Brand Name</li>
> >       <li>Brand Name</li>
> >       <li>Brand Name</li>
> >       <li>Brand Name</li>
> >       <li>Brand Name</li>
> >       <li>Brand Name</li>
> >       <li>Brand Name</li>
> >       <li>Brand Name</li>
> >       <li>Brand Name</li>
> >       <li>Brand Name</li>
> >       <li>Brand Name</li>
> >       <li>Brand Name</li>
> >       <li>Brand Name</li>
> >     </ul>
> >   </li>
> >   <li class="main">etc...</li>
> > </ul>
>
> > The HTML after your approach looks something like this:
>
> > <ul id="narrow-search">
> >      <li class="main">
> >       Category
> >       <ul>
> >         <li>Category Name</li>
> >         <li>Category Name</li>
> >         <li>Category Name</li>
> >         <li>Category Name</li>
> >         <li>Category Name</li>
> >         <li>Category Name</li>
> >         <li>Category Name</li>
> >         <li>Category Name</li>
> >         <li>Category Name</li>
> >         <li>Category Name</li>
> >       </ul>
> >       <ul style="display:none;">
> >         <li>Category Name</li>
> >         <li>Category Name</li>
> >         <li>Category Name</li>
> >         <li>Category Name</li>
> >         <li>Category Name</li>
> >         <li>Category Name</li>
> >         <li>Category Name</li>
> >         <li>Category Name</li>
> >       </ul>
> >       <a href="#">more</a>
> >   </li>
> >   <li class="main">
> >   Brand
> >   <ul/>
> >         <ul style="display:none;">
> >         <li>Brand Name</li>
> >       <li>Brand Name</li>
> >       <li>Brand Name</li>
> >       <li>Brand Name</li>
> >       <li>Brand Name</li>
> >       <li>Brand Name</li>
> >       <li>Brand Name</li>
> >       <li>Brand Name</li>
> >       <li>Brand Name</li>
> >       <li>Brand Name</li>
> >       <li>Brand Name</li>
> >       <li>Brand Name</li>
> >       <li>Brand Name</li>
> >       <li>Brand Name</li>
> >       <li>Brand Name</li>
> >       <li>Brand Name</li>
> >       <li>Brand Name</li>
> >       <li>Brand Name</li>
> >       <li>Brand Name</li>
> >       <li>Brand Name</li>
> >       <li>Brand Name</li>
> >       <li>Brand Name</li>
> >       <li>Brand Name</li>
> >       <li>Brand Name</li>
> >     </ul>
> >     <a href="#">more</a>
> >   </li>
> >   <li class="main">etc...</li>
> > </ul>
>
> > Something is getting screwed up.  The first group looks good (but the
> > toggle does not work).  From then on, the following LI groups are all
> > hidden and there's a strange <ul /> tag being inserted into the mix.
>
> > Any ideas?
>
> > On Jun 19, 5:18 pm, Karl Swedberg <k...@englishrules.com> wrote:
>
> > > I'd probably use .slice().
>
> > > Something like this should work:
>
> > >    $(document).ready(function() {
> > >      var $list = $('.main ul'),
> > >          $items = $list.find('li'),
> > >          $moreLink = $('<a href="#">more</a>');
>
> > >      if ($items.length > 10) {
> > >        $moreItems = $('<ul></ul>').append($items.slice(10)).hide();
> > >        $list.after($moreLink).after($moreItems);
> > >        $moreLink.click(function() {
> > >          $(this).text($(this).text() == 'more' ? 'less' : 'more');
> > >          $moreItems.slideToggle();
> > >          return false;
> > >        });
> > >      }
> > >    });
>
> > > --Karl
>
> > > ____________
> > > Karl Swedbergwww.englishrules.comwww.learningjquery.com
>
> > > On Jun 19, 2009, at 4:54 PM, bombaru wrote:
>
> > > > There has got to be a better way to write this?  Basically, I'm
> > > > returning a bunch of list item and after the 10th one, setting the
> > > > rest to display:none and adding a <more> link.  Clicking on the <more>
> > > > link removes the display:none and adds a <less> link at the bottom.
>
> > > > I think jQuery 1.3.2 is having some trouble with the nth-child
> > > > approach.  Can someone point me in the right direction on how to
> > > > improve this?
>
> > > > Thanks.
>
> > > > $(document).ready(function() {
> > > >            $('.main ul').each(function() {
> > > >                $('li', this).each(function(i) {
> > > >                    if (i > 9) {
> > > >                        if (i == 10) {
> > > >                            $(this).parent().append('<li id=\"toggleon
> > > > \" class=\"toggle\"><a href=\"#\">more >></a></li><li id=\"toggleoff\"
> > > > class=\"toggle\" style=\"display:none\"><a href=\"#\"><< less</a></
> > > > li>');
> > > >                        }
> > > >                        $(this).hide();
> > > >                    }
> > > >                });
> > > >            });
>
> > > >            $('li.toggle').click(function() {
> > > >                $(this).parent().find('li:nth-child(10) ~ li').toggle
> > > > ();
> > > >                $(this).find('#toggleon').toggle();
> > > >                $(this).find('#toggleoff').toggle();
> > > >                return false;
> > > >            });
> > > >        });

Reply via email to