Home > Enterprise >  Showing more card using slice() JS not working
Showing more card using slice() JS not working

Time:08-30

I have a section where I'm pulling blog posts and showcasing them all. By default, 13 .resourceCard's are show and then when clicking load more, 9 more should show.

However, when clicking the load more button, it only showcases the next 9, but not anything after that on subsequent click (doens't show cards 23 ).

Using hiddenCard.slice(x, 9) doesn't work either as only the console log appears.

Where is my logic falling apart?

Demo

$(function () {

  var loadmoreBtn = $('.resourceListing__loadmore');
  var hiddenCard = $('.insertCard:hidden');
  var x = 13;

  loadmoreBtn.on('click', function (e) {
    e.preventDefault();
    x = x   9;
    console.log("click");
    hiddenCard.slice(0, 9).fadeIn().addClass("insertCard--flex");
    if(hiddenCard.length == 0){
      loadmoreBtn.hide();
    }
  });

});
:root {
  --black: #000000;
  --white: #FFFFFF;
  --navy: #0E185F;
}

.placeholderCard,
.resourceCard {
  padding: 60px;
  border: 1px solid var(--black);
  margin-bottom: 30px;
  width: 100%;
}

.placeholderCard {
  background: var(--navy);
  color: var(--white);
  padding: 20px;
}

.resourceListing {
  padding: 80px 0;
}
.resourceListing__loadmore {
  display: flex;
  justify-content: center;
  align-items: center;
  margin: 60px 0;
  cursor: pointer;
}
.resourceListing .insertCard:nth-child(n 16) {
  display: none;
}

.insertCard {
  display: flex;
}
.insertCard--flex {
  display: flex !important;
}
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js" integrity="sha512-894YE6QWD5I59HgZOGReFYm4dnWc1Qt5NtvYSaNcOP u1T9qYdvdihz0PPSiiqn/ /3e7Jo4EaG7TubfWGUrMQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>

<main >
  <div >
    <div >

      <div >
        <div >Card 1</div>
      </div>

      <div >
        <div >Card 2</div>
      </div>

      <div >
        <div >This card is not part of the slice</div>
      </div>

      <div >
        <div >Card 3</div>
      </div>

      <div >
        <div >Card 4</div>
      </div>

      <div >
        <div >This card is not part of the slice</div>
      </div>

      <div >
        <div >Card 5</div>
      </div>

      <div >
        <div >Card 6</div>
      </div>

      <div >
        <div >Card 7</div>
      </div>

      <div >
        <div >Card 8</div>
      </div>

      <div >
        <div >Card 9</div>
      </div>

      <div >
        <div >Card 10</div>
      </div>

      <div >
        <div >Card 11</div>
      </div>

      <div >
        <div >Card 12</div>
      </div>

      <div >
        <div >Card 13</div>
      </div>

      <div >
        <div >Card 14</div>
      </div>

      <div >
        <div >Card 15</div>
      </div>

      <div >
        <div >Card 16</div>
      </div>

      <div >
        <div >Card 17</div>
      </div>

      <div >
        <div >Card 18</div>
      </div>

      <div >
        <div >Card 19</div>
      </div>

      <div >
        <div >Card 20</div>
      </div>

      <div >
        <div >Card 21</div>
      </div>

      <div >
        <div >Card 22</div>
      </div>
      
      <div >
        <div >Card 23</div>
      </div>

      <div >
        <div >Card 24</div>
      </div>

      <div >
        <div >Card 25</div>
      </div>

    </div>

    <div >
      <div >
        <a >Load more</a>
      </div>
    </div>

  </div>
</main>

CodePudding user response:

The issue here is that you get list of hidden cards once. Then process 9 items from that list without updating the list. So next time it processes the same 9 cards again.

To fix that you need update the list with:

hiddenCard = hiddenCard.slice(9);

$(function () {

  var loadmoreBtn = $('.resourceListing__loadmore');
  var hiddenCard = $('.insertCard:hidden');
  var x = 13;

  loadmoreBtn.on('click', function (e) {
    e.preventDefault();
    x = x   9;
    console.log("click", hiddenCard.length);
    hiddenCard.slice(0, 9).fadeIn().addClass("insertCard--flex")
    //update the list
    hiddenCard = hiddenCard.slice(9);
    if(hiddenCard.length == 0){
      loadmoreBtn.hide();
    }
  });

});
:root {
  --black: #000000;
  --white: #FFFFFF;
  --navy: #0E185F;
}

.placeholderCard,
.resourceCard {
  padding: 60px;
  border: 1px solid var(--black);
  margin-bottom: 30px;
  width: 100%;
}

.placeholderCard {
  background: var(--navy);
  color: var(--white);
  padding: 20px;
}

.resourceListing {
  padding: 80px 0;
}
.resourceListing__loadmore {
  display: flex;
  justify-content: center;
  align-items: center;
  margin: 60px 0;
  cursor: pointer;
}
.resourceListing .insertCard:nth-child(n 16) {
  display: none;
}

.insertCard {
  display: flex;
}
.insertCard--flex {
  display: flex !important;
}
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js" integrity="sha512-894YE6QWD5I59HgZOGReFYm4dnWc1Qt5NtvYSaNcOP u1T9qYdvdihz0PPSiiqn/ /3e7Jo4EaG7TubfWGUrMQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>

<main >
  <div >
    <div >

      <div >
        <div >Card 1</div>
      </div>

      <div >
        <div >Card 2</div>
      </div>

      <div >
        <div >This card is not part of the slice</div>
      </div>

      <div >
        <div >Card 3</div>
      </div>

      <div >
        <div >Card 4</div>
      </div>

      <div >
        <div >This card is not part of the slice</div>
      </div>

      <div >
        <div >Card 5</div>
      </div>

      <div >
        <div >Card 6</div>
      </div>

      <div >
        <div >Card 7</div>
      </div>

      <div >
        <div >Card 8</div>
      </div>

      <div >
        <div >Card 9</div>
      </div>

      <div >
        <div >Card 10</div>
      </div>

      <div >
        <div >Card 11</div>
      </div>

      <div >
        <div >Card 12</div>
      </div>

      <div >
        <div >Card 13</div>
      </div>

      <div >
        <div >Card 14</div>
      </div>

      <div >
        <div >Card 15</div>
      </div>

      <div >
        <div >Card 16</div>
      </div>

      <div >
        <div >Card 17</div>
      </div>

      <div >
        <div >Card 18</div>
      </div>

      <div >
        <div >Card 19</div>
      </div>

      <div >
        <div >Card 20</div>
      </div>

      <div >
        <div >Card 21</div>
      </div>

      <div >
        <div >Card 22</div>
      </div>
      
      <div >
        <div >Card 23</div>
      </div>

      <div >
        <div >Card 24</div>
      </div>

      <div >
        <div >Card 25</div>
      </div>

    </div>

    <div >
      <div >
        <a >Load more</a>
      </div>
    </div>

  </div>
</main>

Alternatively, you could move var hiddenCard = $('.insertCard:hidden'); into click function

P.S. You should use const and let instead of var

CodePudding user response:

After making a codepen of your code, I noticed you are not updating your 'hiddenCard' array after loading more. If you simply update the array, you code will work.

$(function () {
  var loadmoreBtn = $('.resourceListing__loadmore');
  var x = 13;

  loadmoreBtn.on('click', function (e) {
    e.preventDefault();
    x = x   9;
   var hiddenCard = $('.insertCard:hidden');
   hiddenCard.slice(0, 9).fadeIn().addClass("insertCard--flex");
   hiddenCard = $('.insertCard:hidden');

   if(!hiddenCard.length){
     loadmoreBtn.hide();
   }
  });

});
:root {
  --black: #000000;
  --white: #FFFFFF;
  --navy: #0E185F;
}

.placeholderCard,
.resourceCard {
  padding: 30px;
  border: 1px solid var(--black);
  margin-bottom: 15px;
  width: 100%;
}

.placeholderCard {
  background: var(--navy);
  color: var(--white);
  padding: 20px;
}

.resourceListing {
  padding: 80px 0;
}
.resourceListing__loadmore {
  display: flex;
  justify-content: center;
  align-items: center;
  margin: 60px 0;
  cursor: pointer;
}
.resourceListing .insertCard:nth-child(n 16) {
  display: none;
}

.insertCard {
  display: flex;
}
.insertCard--flex {
  display: flex !important;
}
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js" integrity="sha512-894YE6QWD5I59HgZOGReFYm4dnWc1Qt5NtvYSaNcOP u1T9qYdvdihz0PPSiiqn/ /3e7Jo4EaG7TubfWGUrMQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>

<main >
  <div >
    <div >

      <div >
        <div >Card 1</div>
      </div>

      <div >
        <div >Card 2</div>
      </div>

      <div >
        <div >This card is not part of the slice</div>
      </div>

      <div >
        <div >Card 3</div>
      </div>

      <div >
        <div >Card 4</div>
      </div>

      <div >
        <div >This card is not part of the slice</div>
      </div>

      <div >
        <div >Card 5</div>
      </div>

      <div >
        <div >Card 6</div>
      </div>

      <div >
        <div >Card 7</div>
      </div>

      <div >
        <div >Card 8</div>
      </div>

      <div >
        <div >Card 9</div>
      </div>

      <div >
        <div >Card 10</div>
      </div>

      <div >
        <div >Card 11</div>
      </div>

      <div >
        <div >Card 12</div>
      </div>

      <div >
        <div >Card 13</div>
      </div>

      <div >
        <div >Card 14</div>
      </div>

      <div >
        <div >Card 15</div>
      </div>

      <div >
        <div >Card 16</div>
      </div>

      <div >
        <div >Card 17</div>
      </div>

      <div >
        <div >Card 18</div>
      </div>

      <div >
        <div >Card 19</div>
      </div>

      <div >
        <div >Card 20</div>
      </div>

      <div >
        <div >Card 21</div>
      </div>

      <div >
        <div >Card 22</div>
      </div>
      
      <div >
        <div >Card 23</div>
      </div>

      <div >
        <div >Card 24</div>
      </div>

      <div >
        <div >Card 25</div>
      </div>

    </div>

    <div >
      <div >
        <a >Load more</a>
      </div>
    </div>

  </div>
</main>

CodePudding user response:

You can start by removing this line:

var x = 13;

because no need a counter! And then move this line:

var hiddenCard = $('.insertCard:hidden');

to beginning of click event after:

e.preventDefault();

Now with this changes, every time you click on Load More button, you create a new collection of remaining hidden cards and then make a slice of first 9 hidden cards.

Accourding to the jQuery documents:

..., the .slice() method constructs a new jQuery object containing a subset of the elements specified by the start and, optionally, end argument.


Update

After all these changes, to hide the Load Mode button, you need to update your if statement to something like this:

if(hiddenCard.slice(9).length == 0){
    loadmoreBtn.hide();
}

Good luck!

  • Related