1

I want to show/hide the #undo button if the array is empty (where all of the original items have been restored from var removedItems = [];).

I am trying to simulate an undo UX where the user has the option to restore deleted items to the list.

$(document).ready(function() {
  function countElement(item, array) {
    var count = 0;
    $.each(array, function(i, v) {
      if (v === item) count++;
    });
    return count;
  }
  countdown = null;

  function timer() {
    var seconds = 10,
      el = $(".seconds");
    el.text(seconds);
    countdown = window.setInterval(function() {
      if (seconds > 0) {
        seconds--;
        el.text(seconds);
        box.show();
      } else {
        clearInterval(countdown);
        box.hide();
      }
    }, 1000);
  }
  var removedItems = [];
  var undo = $("#undo");
  var box = $(".seconds");
  undo.hide();

  var arrayCount = countElement(removedItems);

  $(".remove").on("click", function() {
    var removeItem = $(this)
      .closest(".item")
      .detach();
    removedItems.push(removeItem);
    undo.css("display", "flex");
    clearInterval(countdown);
    timer();
  });

  $("#undo").click(function() {
    if (removedItems.length) {
      var restoreItem = removedItems.shift();
      $(".list").append(restoreItem);
      clearInterval(countdown);
      timer();
    }
    /*if (arrayCount === 0) {
      undo.hide();
    } else {
      undo.show;
    }*/
  });
});
.seconds {
  border: 2px solid
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="list">
  <div class="item">
    Item 1
    <button class='remove'>Remove</button>
  </div>
  <div class="item">
    Item 2
    <button class='remove'>Remove</button>
  </div>
  <div class="item">
    Item 3
    <button class='remove'>Remove</button>
  </div>
</div>
<button id='undo'>Undo</button>
<div class="seconds"></div>

3
  • what is the problem ? Commented Dec 31, 2019 at 19:12
  • if (removedItems.length === 0) $(this).hide(); You wouldn't show the undo button in the undo click event handler because 1) the undo never adds elements, it only removes them; and 2) if it's hidden they couldn't have clicked it to begin with. Commented Dec 31, 2019 at 19:13
  • #undo should hide after items are restored to their original state Commented Dec 31, 2019 at 19:13

1 Answer 1

1

I've added a check for if (!removedItems.length) to the $('#undo') on click eventListener, and this seems to have solved your problem - arrayCount where it was wasn't being updated at the right time, but simply using .length works fine.

I've also cleaned up some of the other code so it's a little easier to read, such as moving your variable assignments higher and together, and hiding box at the start along with undo

There's a comment at the bottom showing also how to remove the box, if that's something you wanted to do.

$(document).ready(function() {
  function countElement(item, array) {
    var count = 0;
    $.each(array, function(i, v) {
      if (v === item) count++;
    });
    return count;
  }
  
  let countdown = null;
  var removedItems = [];
  var arrayCount = countElement(removedItems);
  var undo = $("#undo");
  var box = $(".seconds");
  
  undo.hide();
  box.hide(); // Hides the black line at the start

  function timer() {
    var seconds = 10,
        el = $(".seconds");
        
    el.text(seconds);
    countdown = window.setInterval(function() {
      if (seconds > 0) {
        seconds--;
        el.text(seconds);
        box.show();
      } else {
        clearInterval(countdown);
        box.hide();
      }
    }, 1000);
  }

  $(".remove").on("click", function() {
    var removeItem = $(this)
      .closest(".item")
      .detach();
    removedItems.push(removeItem);
    undo.css("display", "flex");
    clearInterval(countdown);
    timer();
  });

  $("#undo").click(function() {
    if (removedItems.length) {
      var restoreItem = removedItems.shift();
      $(".list").append(restoreItem);
      clearInterval(countdown);
      timer();
    }
    
    if (!removedItems.length) {
      undo.hide();
      
      // If you also want to remove the box;
      clearInterval(countdown);
      box.hide();
    }
  });
});
.seconds {
  border: 2px solid
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="list">
  <div class="item">
    Item 1
    <button class='remove'>Remove</button>
  </div>
  <div class="item">
    Item 2
    <button class='remove'>Remove</button>
  </div>
  <div class="item">
    Item 3
    <button class='remove'>Remove</button>
  </div>
</div>
<button id='undo'>Undo</button>
<div class="seconds"></div>

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.