简体   繁体   中英

Javascript foreach loop calls ajax several times

So I am trying to create to do list with several boards. Each board have add item button. If I click add item button it opens modal where to insert task info. But if I click add item button several times and then insert info to modal and press save ajax fires as many times i clicked add item button. How can I prevent from that?

var addNewItems = document.querySelectorAll("#addNewItem");
var addNewSubmits = document.querySelectorAll("#listItemSave");
addNewItems.forEach(function(addNewItem) {
  addNewItem.addEventListener("click", function(e) {
    var newItemModal = this.nextElementSibling;
    newItemModal.classList.toggle("hidden");
    var addNewBtn = newItemModal.querySelector("#listItemSave");
    //current board
    var board = this.closest("div.list");
    //current list
    var list = board.querySelector(".todo--items");

    addNewBtn.addEventListener  ("click", function(e) {
      //current board id
      var boardId = board.dataset.boardid;
      //current title
      var title = newItemModal.querySelector("#listTitle");
      var titleValue = title.value;
      //current content
      var content = newItemModal.querySelector("#listTextarea");
      var contentValue = content.value;


      $.ajax({
        type: "POST",
        url: "add.php",
        data: { content: contentValue , title: titleValue , listid: boardId  },

        success: function(data, textStatus, jqXHR) {

        $("#todoItems-" + id + "").append(data);

       }
      });

    });
  });
});



You could use a variable, lets say busy , to validate that an AJAX request isn't already on going.

You could set this variable in the beforeSend callback of AJAx and then updated it back to false in the finally callbac :

var addNewItems = document.querySelectorAll("#addNewItem");
var addNewSubmits = document.querySelectorAll("#listItemSave");
addNewItems.forEach(function (addNewItem) {
    addNewItem.addEventListener("click", function (e) {
        var newItemModal = this.nextElementSibling;
        newItemModal.classList.toggle("hidden");
        var addNewBtn = newItemModal.querySelector("#listItemSave");
        //current board
        var board = this.closest("div.list");
        //current list
        var list = board.querySelector(".todo--items");

        var busy = false;

        addNewBtn.addEventListener("click", function (e) {
            //current board id
            var boardId = board.dataset.boardid;
            //current title
            var title = newItemModal.querySelector("#listTitle");
            var titleValue = title.value;
            //current content
            var content = newItemModal.querySelector("#listTextarea");
            var contentValue = content.value;

            if (!busy) {
                $.ajax({
                    type: "POST",
                    url: "add.php",
                    beforeSend: () => {
                        busy = true;
                    }
                    data: {
                        content: contentValue,
                        title: titleValue,
                        listid: boardId
                    },
                    success: function (data, textStatus, jqXHR) {
                        $("#todoItems-" + id + "").append(data);
                    },
                    complete: () => {
                        busy = false;
                    }
                });
            }
        });
    });
});

This is a pretty simple solution but it works.

You can use addNewBtn.onclick = function () {} instead to overlap the previous listener in this case. But it's not recommended to register listeners inside another listener. Try to move it out of there.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM