简体   繁体   中英

Is ajax running more than once in modal?

I am developing a feature that needs the Ajax request. First I open a modal by clicking a button that has the class '.open-email-modal' . And after that, it opens a modal where it has 2 fields to enter values for a register, and below it has a table. When opening the modal the first time, everything happens normally, the register with the call of the request Ajax goes through a controller and returns in response to the value registered with its respective token. Below are the codes I developed. (I'm using Laravel).

This is the modal code.

<div class="col-md-4">

    <div class="modal fade" id="emailModal" tabindex="-1" role="dialog" aria-labelledby="modal-form" aria-hidden="true">
  <div class="modal-dialog modal- modal-dialog-centered modal-lg" role="document">
      <div class="modal-content">

          <div class="modal-body p-0">


<div class="card bg-secondary shadow border-0">
  <div class="card-header bg-transparent pb-4">
      <div class="text-muted text-center mt-2 mb-3 text-uppercase"><h1>Adicionar Email</h1></div>
        <div class="text-center text-muted mb-4">
            <small> Preencha os campos dos emails </small>
        </div>
  </div>
  <div class="card-body px-lg-5 py-lg-5">
  <form  id="emailModalProspect" method="post" action="{{ route('prospectEmails.store') }}">

          @csrf
          {{ method_field('post') }}


          <input hidden name="prospect_id" id="prospect_id_email" type="text">

          <div class="form-group mb-3">
            <label class="form-control-label" for="prospect-email-name">{{ __('Nome') }}</label>
              <div class="input-group input-group-alternative">
                  <div class="input-group-prepend">
                      <span class="input-group-text"><i class="fas fa-user"></i></span>
                  </div>
                  <input class="form-control" id="prospect-email-name" name="name" placeholder="Digite o nome do proprietário do email" type="text" required>

              </div>
          </div>

          <div class="form-group mb-3">
              <label class="form-control-label" for="prospect-email-email">{{ __('Email') }}</label>
              <div class="input-group input-group-alternative">
                  <div class="input-group-prepend">
                      <span class="input-group-text"><i class="ni ni-email-83"></i></span>
                  </div>
                  <input class="form-control" id="prospect-email-email" name="email" placeholder="Digite o email da empresa/cliente" type="email">
              </div>
          </div>

          <div class="text-center">
              <button type="submit" id="save-email" class="btn btn-primary my-4 store-email text-uppercase">Cadastrar email</button>
          </div>

    </form>

          <div class="table-responsive ">

            <table class="table align-items-center table-flush  tablesorter-dropbox text-center" id="prospect-email-table">
                <thead class="thead-light text-center" >
                    <tr class="text-center">
                        <th scope="col" class="text-center col-sm-2"><b>{{ __('Nome') }}</b></th>
                        <th scope="col" class="text-center col-sm-2"><b>{{ __('Email') }}</b></th>
                        <th scope="col" class="text-center col-sm-2"><b>{{ __('Opção') }}</b></th>
                    </tr>
                </thead>
                <tbody class="text-center" id="received-emails">
                </tbody>
            </table>
        </div>

        <div class="text-center">
              <button type="button" class="btn btn-default my-4 text-uppercase" data-dismiss="modal">Fechar</button>
          </div>


  </div>
</div>
</div>
</div>
</div>
</div>
</div> 

This is the code in JQuery where it calls the Ajax request.

 $('.open-email-modal').on('click', function(e) {
       e.preventDefault();
       e.stopPropagation();

       $.ajaxSetup({
         headers: {
           'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
          }
        });

        let p = JSON.parse($(this).attr('data-entity'));

        let modal = $('#emailModal');
        let form = $('#emailModalProspect');

        $('#prospect_id_email').val(p.id).change();

        $('.store-email').on('click', function(b){
          b.stopPropagation();
          b.preventDefault();

          $.ajaxSetup({
            headers: {
              'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
            }
          });

          let url = '{{route("prospectEmails.store")}}';

          $.ajax({
            url: url,
            type: "POST",
            data : form.serialize(),
            async: false,
            headers: {
              'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
            },
            dataType: "json",
            success:function(response) {                  
              console.log(response);
              showEmails(p.id);  
            }               
          });

        });

        if(p.id){
          showEmails(p.id);
        }

        modal.modal({show : true});    
  });

This is my controller code.

public function store(Request $request){

ProspectEmails::create(array_merge($request->all(), ['company_id' => Auth::User()->company_id], ['prospect_id'=>$request->prospect_id], ['tag'=>false]));        
return Response()->json($request);
}

The problem is this, as soon as I open for the first time and register, everything works normally. But when I close the modal and open again and register, it is returned that register that I made 2x without any token. Close the modal again and open again and register, and return that register 3x, without any token again. showEmails is a function that shows the registration in the table normally and also shows the repeated values every time that registration. Even the database shows the repeated values, so I have confirmation that the main error is either in my modal or in the Ajax request with the POST method. Can someone give me a hand?

You are registering click each time you open the modal:

$('.store-email').on('click', ...

The first time you open it, you register a listener.

The second time you open it, you register a listener, and now you have 2, and so on.

Since you don't reload the page, the listeners do not go away. You should be removing your event listener when the modal closes or checking to see if you have added it already and not adding it again:

https://api.jquery.com/off/

An easy way to do it would be to call the off method right before registering the listener, guaranteeing you only have 1 listener attached:

    let modal = $('#emailModal');
    let form = $('#emailModalProspect');

    $('#prospect_id_email').val(p.id).change();

    // ADDED LINE
    $('.store-email').off('click');
    $('.store-email').on('click', function(b){

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