Search code examples
javascripteventsevent-listener

addEventListener multiple times in a click event


I have a problem trying to catch a event in a javascript file. I need to handle some buttons when these are clicked. They have differente behaviour, for example, some add some elements, other can multiple add elements, or delete them.

I have 4 buttons in a panel (search, add, add+ and delete). To be precise, I'll explain the problem with the search button.

I have a function "search" that takes the button from de document, and link to a eventListener

btn_search = document.getElementById('searchBtn');
btn_search.addEventListener("click", search);

Then, after click over btn_search, a modal display with some inputs and a submit button. When I click over the button, the modal closes with the data that I need. In this situation the system works well, but when I want to operate with another functions (add, delete, or the same search), this last tasks execute but all the other previous operations executes too. It's as if repeat all the secuence together when a new operation it's coming.

This is the code that I use for search, its similar in the other operations

function search(event) {
event.stopPropagation();
buildModal(1);
$('#modal_gid').modal('show');

btn_modal_footer.addEventListener("click", search_elems); //button to attach function to "search button" in button

function search_elems(event) {
    event.preventDefault();
    let code = input_code.value;
    if (code != null && code != "")
        $.ajax({ 
            url: base_url.value + 'index.php/ajax_get_elems',
            method: 'post',
            dataType: "json",
            data: { "code": code },
            success: function (response) {
                success functions
            }
        });
    else
        handler_errores_code(2)
}

I tried with removeEventListener but not work. With a counter or flag variables too.

Thanks!


Solution

  • You should use "event delegation", which is where you set up a single event handler at a common ancestor of the elements that need to have events handled for them. Then, within that handler, you check to see which element was responsible for triggering the event in the first place (this is available via event.target) and then act accordingly.

    Here's a simplified example:

    // Set up one event handler on the common ancestor
    document.querySelector(".wrapper").addEventListener("click", function(event){
      // See if the event was triggered by an element we care to handle
      if(event.target.classList.contains("btn")){
        // Ok, we need to handle the event, but we need to now check
        // which element was clicked and handled appropriately
        if(event.target.classList.contains("foo")){
          foo();
        } else if(event.target.classList.contains("bar")) {
          bar();
        } else {
          // Only choice left is baz
          baz();
        }
      }
    });
    
    function foo(){
      // Do whatever foo requires
      console.log("foo");
    }
    
    function bar(){
      // Do whatever bar requires
      console.log("bar");
    }
    
    function baz(){
      // Do whatever baz requires
      console.log("baz");
    }
    <div class="wrapper">
      <button type="button" class="btn foo">Foo</button>
      <button type="button" class="btn bar">Bar</button>  
      <button type="button" class="btn baz">Baz</button>  
    </div>