Domanda

I have this jquery code that creates a more and less button to display more and less items in an unordered list id =grid which works but is a bit unreliable Objective: I always want the display to be appended with the list in a collapsed/reduced state with the more button showing to display more items in the list

However when new grids are appended to the newImg they are sometimes in the show all state opposed to the collapsed state is there a way of making this more reliable to always display the grid when appended in the reduced/collapsed state with teh more button showing

  newImg.appendChild(grid);

  $('#grid').each(function() {
   var $list = $(this);
    $list.before('<button class="more_less">More</button>');
  $list.find('.grid-item:gt(2)').hide();
  });


   $('.more_less').click(function() {
  var $btn = $(this);
  $btn.next().find('.grid-item:gt(2)').slideToggle();    
   $btn.text($btn.text() == 'More' ? 'Less' : 'More');    
  });

 }
È stato utile?

Soluzione

If you are adding more than one grid, make sure you are using class name instead of id(since id must be unique and shall not be used by another element), and create a reusable function that will append the grid to the container and will create the More/Less button on the fly.

//Here is a reusable function that takes two parameter:
//container: an element that will contain the ul list, in your case newImg
//grid: ul element
function createGrid(container, grid)
{
      $(container).append(grid);

      $(grid).before('<button class="more_less">More</button>');
      $(grid).find('.grid-item:gt(2)').hide();

      $('.more_less').click(function() {
         var $btn = $(this);
         $btn.next().find('.grid-item:gt(2)').slideToggle();    
         $btn.text($btn.text() == 'More' ? 'Less' : 'More');    
      });
}


$(body).ready(function(){
                            $(".grid").each(function(index, grid){ createGrid($("#newImg"), grid) });
                         });

//This  line of code will iterate for each element with class ".grid" and pass it to createGrid function

And for newly grids that are created after the previous code is executed, just use the function.

createGrid($("#newImg"), $("#new-grid");

Altri suggerimenti

Try using toggle()

Add a state var outside the functions.

var state = new Array(),
    moreLess = function(id){ // IDs are class names
    $('.' + id).toggle(function(){
         state[id] = true;
         // show all code
     },
     function(){
         state[id] = false;
         // hide code
    });
});

// ...

var elm = $('.example-class'),
    class = elm.attr('class'); // example of fetching state id from element
if ( state[ class ] == false )  { // you check with this before adding content
    moreLess( class );
}

Then if you alter the content refer to the state var, if its off, run the toggle function again before adding content.

I realize this should work on multiple targets, ill add more when I'm home on that subject. On my phone. :P

But basically you would add a var to the moreLess function to pass a id to it. Grab that element and then write a new array element to the state var which we set as a array instead of 'false'. Then by using that ID you can set a state for each target and refer to it.

Update: added a id system to it

https://api.jquery.com/toggle/

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top