Search code examples
javascripttogglelist.js

How correctly handle toggle effect in List.js list with pagination


I have an issue with the behavior of toggle on click when I include pagination management in List.js. The effect works properly first, but when I navigate to page 2 then back to page one, toggle effect is not responding. I have to click 2 times on the pagination link to restore the effect.

How can I correct this behavior? And more generally, what is the right strategy to debug this kind on problem?

Here is a codepen with the example, and bellow the js and html codes.

Thank you for your help!

var options = {
  valueNames: [
    'date',
    'conversions',
    'revenue',
    'cr'
  ],
  page: 3,
  pagination: true
};

var userList = new List('users', options);

function hide_and_toggle(userList){
  $('.row-toggle').hide();
  $(".list li").on('click', function(row){
    $(this).find('.row-toggle').toggle();
  });
}

$(function(){
  hide_and_toggle(userList);

  userList.on('updated', function(userList){
    hide_and_toggle(userList);
  });

});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/list.js/1.5.0/list.min.js"></script>

<div id="users">
    <input class="search" placeholder="Search" />

      <div class="row">
        <button class="sort col" data-sort="date">
          Sort by Date
        </button>
        <button class="sort col" data-sort="conversions">
          Sort by Conversion Count
        </button>
        <button class="sort col" data-sort="revenue">
          Sort by Revenues
        </button>
        <button class="sort col" data-sort="cr">
          Sort by CR
        </button>
      </div>

  <ul class="list">
    <li data-id="1">
      <div class="row">
        <div class="col text-center date">1</div>
        <div class="col text-center conversions">10</div>
        <div class="col text-center revenue">100</div>
        <div class="col text-center cr">1000</div>
      </div>
      <div class="row row-toggle"> 
        <div class="col">
          <span> Goals</span>
          <table class="table-sm">
          <tr>
            <td>Install</td>
            <td>20</td>
          </tr>
          <tr>
            <td>First listen</td>
            <td>3</td>
          </tr>
          <tr>
            <td>Purchase</td>
            <td>4</td>
          </tr>
        </table>
        </div>
        <div class="col">
          <span>Scrubed & Overdelivery</span>
          <table class="table-sm">
            <tr>
              <td>Scrubed</td>
              <td>30</td>
              <td>200</td>
            </tr>
            <tr>
              <td>Over Delivery</td>
              <td>40</td>
              <td>400</td>
            </tr>
          </table>
        </div>
      </div>
    </li>
    <li data-id="2">
      <div class="row">
        <div class="col text-center date">2</div>
        <div class="col text-center conversions">20</div>
        <div class="col text-center revenue">200</div>
        <div class="col text-center cr">2000</div>
      </div>

      <div class="row row-toggle"> 
        <div class="col">
          <table>
          <tr>
            <td>Hello</td>
            <td>World</td>
          </tr>
          <tr>
            <td>Hello</td>
            <td>World</td>
          </tr>
          <tr>
            <td>Hello</td>
            <td>World</td>
          </tr>
        </table>
        </div>
        <div class="col">
          Content On the side 2
        </div>
      </div>
    </li>
    <li data-id="3">
      <div class="row">
       <div class="col text-center date">3</div>
        <div class="col text-center conversions">30</div>
        <div class="col text-center revenue">300</div>
        <div class="col text-center cr">3000</div>
      </div>

      <div class="row row-toggle"> 
        <div class="col">
          <table>
          <tr>
            <td>Hello</td>
            <td>World</td>
          </tr>
          <tr>
            <td>Hello</td>
            <td>World</td>
          </tr>
          <tr>
            <td>Hello</td>
            <td>World</td>
          </tr>
        </table>
        </div>
        <div class="col">
          Content On the side 3
        </div>
      </div>
    </li>
    <li data-id="10">
      <div class="row">
        <div class="col text-center date">10</div>
        <div class="col text-center conversions">100</div>
        <div class="col text-center revenue">1000</div>
        <div class="col text-center cr">10000</div>
      </div>

       <div class="row row-toggle"> 
        <div class="col">
          <table>
          <tr>
            <td>Hello</td>
            <td>World</td>
          </tr>
          <tr>
            <td>Hello</td>
            <td>World</td>
          </tr>
          <tr>
            <td>Hello</td>
            <td>World</td>
          </tr>
        </table>
        </div>
        <div class="col">
          Content On the side 10
        </div>
      </div>
    </li>
  </ul>
  <ul class="pagination"></ul>
</div>


Solution

  • The root cause:

    If userList.on('updated', function(userList){} is triggered, it will bind the $(".list li").on('click', function(row){} again and again.

    You can try to double click page 1, then you will find the toggle is not working (actually it is toggled twice, so it seems no toggle).

    When you click again, you will find the toggle is working again. (actually it is toggled three times).

    The solution is very easy, just unbind before bind $(".list li").on('click').

    var options = {
      valueNames: [
        'date',
        'conversions',
        'revenue',
        'cr'
      ],
      page: 3,
      pagination: true
    };
    
    var userList = new List('users', options);
    
    function hide_and_toggle(userList){
      $('.row-toggle').hide();
      $( ".list li").unbind( "click" ); //clear up event binding.
      $(".list li").on('click', function(row){
        $(this).find('.row-toggle').toggle();
      });
    }
    
    $(function(){
      hide_and_toggle(userList);
    
      userList.on('updated', function(userList){
        hide_and_toggle(userList);
      });
    
    });
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <script src="//cdnjs.cloudflare.com/ajax/libs/list.js/1.5.0/list.min.js"></script>
    
    <div id="users">
        <input class="search" placeholder="Search" />
    
          <div class="row">
            <button class="sort col" data-sort="date">
              Sort by Date
            </button>
            <button class="sort col" data-sort="conversions">
              Sort by Conversion Count
            </button>
            <button class="sort col" data-sort="revenue">
              Sort by Revenues
            </button>
            <button class="sort col" data-sort="cr">
              Sort by CR
            </button>
          </div>
    
      <ul class="list">
        <li data-id="1">
          <div class="row">
            <div class="col text-center date">1</div>
            <div class="col text-center conversions">10</div>
            <div class="col text-center revenue">100</div>
            <div class="col text-center cr">1000</div>
          </div>
          <div class="row row-toggle"> 
            <div class="col">
              <span> Goals</span>
              <table class="table-sm">
              <tr>
                <td>Install</td>
                <td>20</td>
              </tr>
              <tr>
                <td>First listen</td>
                <td>3</td>
              </tr>
              <tr>
                <td>Purchase</td>
                <td>4</td>
              </tr>
            </table>
            </div>
            <div class="col">
              <span>Scrubed & Overdelivery</span>
              <table class="table-sm">
                <tr>
                  <td>Scrubed</td>
                  <td>30</td>
                  <td>200</td>
                </tr>
                <tr>
                  <td>Over Delivery</td>
                  <td>40</td>
                  <td>400</td>
                </tr>
              </table>
            </div>
          </div>
        </li>
        <li data-id="2">
          <div class="row">
            <div class="col text-center date">2</div>
            <div class="col text-center conversions">20</div>
            <div class="col text-center revenue">200</div>
            <div class="col text-center cr">2000</div>
          </div>
    
          <div class="row row-toggle"> 
            <div class="col">
              <table>
              <tr>
                <td>Hello</td>
                <td>World</td>
              </tr>
              <tr>
                <td>Hello</td>
                <td>World</td>
              </tr>
              <tr>
                <td>Hello</td>
                <td>World</td>
              </tr>
            </table>
            </div>
            <div class="col">
              Content On the side 2
            </div>
          </div>
        </li>
        <li data-id="3">
          <div class="row">
           <div class="col text-center date">3</div>
            <div class="col text-center conversions">30</div>
            <div class="col text-center revenue">300</div>
            <div class="col text-center cr">3000</div>
          </div>
    
          <div class="row row-toggle"> 
            <div class="col">
              <table>
              <tr>
                <td>Hello</td>
                <td>World</td>
              </tr>
              <tr>
                <td>Hello</td>
                <td>World</td>
              </tr>
              <tr>
                <td>Hello</td>
                <td>World</td>
              </tr>
            </table>
            </div>
            <div class="col">
              Content On the side 3
            </div>
          </div>
        </li>
        <li data-id="10">
          <div class="row">
            <div class="col text-center date">10</div>
            <div class="col text-center conversions">100</div>
            <div class="col text-center revenue">1000</div>
            <div class="col text-center cr">10000</div>
          </div>
    
           <div class="row row-toggle"> 
            <div class="col">
              <table>
              <tr>
                <td>Hello</td>
                <td>World</td>
              </tr>
              <tr>
                <td>Hello</td>
                <td>World</td>
              </tr>
              <tr>
                <td>Hello</td>
                <td>World</td>
              </tr>
            </table>
            </div>
            <div class="col">
              Content On the side 10
            </div>
          </div>
        </li>
      </ul>
      <ul class="pagination"></ul>
    </div>