Ant100
Ant100

Reputation: 403

Custom event firing multiple times in Jquery

I have looked everywhere for similar questions, but adding off(), one() etc. is not fixing it, which is the given solution in other SO questions.

I have a table to which you can add or edit data. If you want to edit data, the table row data is loaded in a select box and when you click 'add' it should delete previews row and add a new one with modified data.

Problem is after first edit, since the modified row is dinamically added, it no longer works. For this my solution is to trigger a custom event where I can use the 'delegate propagate'.

So far I'm trying to trigger my custom event, problem is when it is called it fires from 3 to 4 times. I don't know why.

Here is my code for the add button:

$("#addButton").click(function(e){

      // bunch of code where i get the info from select boxes

      // Here I loop through the table to see if any of the rows ids match current id, 
      // if it does it should delete that row so I call my custom event
      $.each(table, function(index, value) {
         var sid = $(value).children("td:nth-child(1)").data('sitioId');

         // if this matches it means that there already exists a row, so we edit it
         if(sid == sitioId) {
           editRol_id = $(value).children("td:nth-child(4)").children().first().attr('id');
           $(table).trigger('testEvent');
           return false;
      }
});

And here is my custom event:

$(table).one('testEvent',function(e, eventInfo) {
  e.preventDefault();
  alert('test');

});

For now it only has an alert because I'm just trying to get it called properly, but the alert fires multiple times.

If you need any more info or anything please let me know. Thank you for your time.

Edit: Here is my html also

This is the table where data is

<div class="panel">
   <div class="col-sm-3"></div>
      <div class="panel-body col-sm-6">
          <div class="table-responsive">
             <table class="table table-hover nomargin" id="relacionRol">
                <thead>
                  <tr>
                    <th>Sitio</th>
                    <th>Rol</th>
                    <th>Categoría</th>
                    <th></th>
                  </tr>
                </thead>
                <tbody>
                   <!-- start foreach -->
                   <tr>
                     <td class="sitio_id" data-sitio-id="id" >name</td>
                     <td class="rol_id" data-rol-id="id" >name</td>
                     <td class="categoria_id" data-categoria-id="id1, id2"> name</td>
                     <td>
                        <a href="#" id="editRol<?php echo $i;?>" class="edit"><span class="fa fa-edit"></span></a>
                        <a href="#" id="deleteRol<?php echo $i;?>" class="del"><span class="fa fa-trash"></span></a>
                     </td>
                   </tr>
                   <!-- end foreach -->
                </tbody>
            </table>
        </div><!-- table-responsive -->
    </div>
</div>

And this are the select boxes used to edit data:

<div class="form-group" id="rolSitio1">
    <label class="col-sm-3 control-label">Sitio</label>
    <div class="col-sm-2">
        <select id="sitios1" class="select2 sitio" name="sitio_id" style="width: 100%" data-placeholder="Elegir un sitio">
             <option value="">&nbsp;</option>
             <!-- php for other options -->
         </select>
    </div>
    <label class="col-sm-1 control-label">Rol</label>
    <div class="col-sm-2">
          <select id="roles1" class="select2 rol" name="rol_id" style="width: 100%" data-placeholder="Elegir un rol">
             <option value="">&nbsp;</option>
             <!-- php for other options -->
          </select>
    </div>
    <div id="categoriaWrapper">
       <label class="col-sm-1 control-label">Categoría</label>
       <div class="col-sm-2">
          <select name="categoria_id" style="width: 100%" id="categorias1" class="select2 form-control categoria" multiple>
          <!-- this data is loaded with ajax -->
          </select>
       </div>
    </div>
    <button id="addButton" class="btn"><i class="fa fa-arrow-up"></i></button>
</div>

Upvotes: 0

Views: 746

Answers (2)

trynahelp
trynahelp

Reputation: 11

Looks like you already got your answer, but here's a jsfiddle that solves your problem (doesn't trigger on 'table' inside the loop) that you might find interesting anyways and juggles events nicely when dealing with data from parent/child elements

https://jsfiddle.net/sd6fvae7/2/

<input type='text' id='sitio_id_check'/>
<button id='addRecord'>Add record</button>

<table id="relacionRol">
  <tr id='row1' >
    <td class="sitio_id" data-sitio-id="id1">sitio_id id1</td>
  </tr>
  <tr id='row2'>
    <td class="sitio_id" data-sitio-id="id2">sitio_id id2</td>
  </tr>
  <tr id='row3'>
    <td class="sitio_id" data-sitio-id="id3">sitio_id id3</td>
  </tr>
</table>

<div id='output1'>
</div>

$('#relacionRol').on('testEvent', function(e, someParameter){
    $('#output1').append("Event fired on: #" + $(e.target).attr('id') + "<br />");
    $('#output1').append("someParameter: " + someParameter);
});

$('#addRecord').on('click', function(e){
    // Look for matching records and trigger event on table if match is found
  // Or you could do this on the table row if you prefer
  $('#relacionRol tr').each(function(){
    if($(this).find('.sitio_id').data('sitio-id') == $('#sitio_id_check').val()){
        $('#output1').append("Match in: #" + $(this).attr('id') + "<br />");
      $('#relacionRol').trigger('testEvent', 'value passed to event handler');
    }
  });
});

Upvotes: 1

ahwayakchih
ahwayakchih

Reputation: 2371

You seem to have some table variable somewhere.

$.each(table, function(index, value) {

It looks like there are multiple items in table, since you call each on it. And then:

$(table).one('testEvent'

If table resolves to multiple items/nodes, then each of them will receive your custom event, thus you will see multiple alerts as if event was called multiple times.

Upvotes: 1

Related Questions