简体   繁体   中英

Why doesn't the Ajax call work after a certain part of the code?

I have a code in PHP and JS, where I use Vis.js to create a timeline and AJAX to make requests to a page to get a page as a response and put it inside a Bootstrap Modal.

Each user has an ID (in the div where the photo is) that when clicked opens the modal along with the page that was brought by the AJAX request. Until then, everything is fine. All AJAX requests to users work, the problem is with the timeline items.

Each item should do the same thing as clicking on the user ID, but bring up a different page. Up to item 6 works perfectly, however, after that, when I click on item 7 onwards nothing happens. The number of users is also above 6, but one call works and the other does not.

Does anyone have any idea why?

This is the code:

<script>

var now = Date.now();

var options = {
  stack: true,
  maxHeight: 640,
  horizontalScroll: true,
  verticalScroll: true,
  zoomKey: "ctrlKey",
  start: '2022-01-01',
  end: '2022-12-31',
  orientation: {
    axis: "top",
    item: "top",
  },
};

var groups = new vis.DataSet();
var items = new vis.DataSet();

var count = 300;

<?php

$query_todos = 'SELECT * FROM booking';
$todos_booking = $conn->prepare($query_todos);
$todos_booking->execute();

$combined = array();
$i = 0;

function sort_by_name($a,$b)
{
    return $a["nome_social"] > $b["nome_social"];
}

while($todos = $todos_booking->fetch(PDO::FETCH_ASSOC)){

  $query_nome = 'SELECT nomesocial, foto, situacao FROM dados WHERE iddados =:id_funcionario';
  $nome = $conn->prepare($query_nome);
  $nome->bindParam(':id_funcionario', $todos['id_funcionario'], PDO::PARAM_STR);
  $nome->execute();

  $nome_social = $nome->fetch(PDO::FETCH_ASSOC);

  if(!empty($nome_social['foto'])){
    $img = $nome_social['foto'];
  }else{
    $img = '../img/avatar.png';
  }

    if( ( $key = array_search( $todos['id_funcionario'], array_column( $combined, 'id_funcionario') ) ) !== false )  {
      $combined[$key]['projeto'] .= '||'.$todos['projeto'];
      $combined[$key]['software'] .= '|||'.$todos['software'];
      $combined[$key]['data_inicio'] .= '||'.$todos['data_inicio'];
      $combined[$key]['data_fim'] .= '||'.$todos['data_fim'];
      $combined[$key]['confirmacao'] .= '||'.$todos['confirmacao'];
      $combined[$key]['img'] = $img;
      $combined[$key]['nome_social'] = $nome_social['nomesocial'];
      $combined[$key]['situacao'] = $nome_social['situacao'];
    } else {
      $todos['img'] = $img;
      $todos['nome_social'] = $nome_social['nomesocial'];
      $todos['situacao'] = $nome_social['situacao'];
      $combined[] = $todos;
    }
  }

  $combined_nome_social = $combined;

  uasort($combined,"sort_by_name");

  foreach($combined as $chave => $valor){
?>

<?php

  if(!empty($valor['projeto'])){

    ?>

  groups.add({
    id: <?php echo $i; ?>,
    content: "<div id='<?php echo str_replace(' ', '',$valor['nome_social']); ?>' class='row justify-content-center cursor'><img src='<?php echo $valor['img']; ?>' style='width: 100px; height: 80px; border-radius: 100%;'><div class='row justify-content-center'><?php echo $valor['nome_social']; ?></div></div>",
    order: <?php echo $i; ?>,
    <?php if($valor['situacao'] == '0'){
       echo "style: 'background-color: rgba(255, 0, 0, 0.2)',
        className: 'red'"; 
       } ?>
  });

  <?php }else{ ?>
groups.add({
    id: <?php echo $i; ?>,
    content: "<div id='<?php echo str_replace(' ', '',$valor['nome_social']); ?>' class='row justify-content-center cursor'><img src='<?php echo $valor['img']; ?>' style='width: 100px; height: 80px; border-radius: 100%;'><div class='row justify-content-center'><?php echo $valor['nome_social']; ?></div></div>",
    order: <?php echo $i; ?>,
    <?php if($valor['situacao'] == '0'){
       echo "style: 'background-color: rgba(255, 0, 0, 0.2)',
       className: 'red'"; 
       } ?>
  });

  <?php } ?>

  setTimeout(function(){

$(document).ready(function(){
  $("#<?php echo str_replace(' ', '',$valor['nome_social']); ?>").click(function(){
    $("#editar_funcionario").html('');
    $.ajax({
          url: '../utilities/modal_adicionar_booking.php?id_funcionario=<?php echo $valor['id_funcionario']; ?>',
          method: 'GET',
          cache: false,
          contentType: false,
          processData: false,
          success: function(resultado){
  $form = $("<form id='adicionar_funcionario_booking' method='POST' enctype='multipart/form-data'></form>");
  $("#editar_funcionario").append($form);
  $("#adicionar_funcionario_booking").html(resultado);
  $("#titulo_editar").html('Adicionar booking de <?php echo $valor['nome_social']; ?>');
  let el = document.getElementById('editar');
  let modal =new bootstrap.Modal(el);
  modal.show();

  let confirmacao = document.getElementById('confirmacao');

  confirmacao.addEventListener('click', ()=>{
  if(confirmacao.checked){
      document.getElementById('label_confirmacao').innerHTML = "Confirmado";
  }else{
      document.getElementById('label_confirmacao').innerHTML = "Não confirmado";
  }
})

$("#botao_salvar").click(function(){
    $('#botao_salvar').prop('disabled', true);
        $('#botao_salvar').html('');
        $('#botao_salvar').append('<img src="../img/loading.gif" style="width: 30px;"/>');
    var dados = new FormData(document.getElementById("adicionar_funcionario_booking"));
      $.ajax({
            url: '../utilities/adicionar_booking.php?id_funcionario=<?php echo $valor['id_funcionario']; ?>',
            method: 'POST',
            dataType: 'json',
            cache: false,
            contentType: false,
            processData: false,
            data: dados,
            success: function(resultado){
              let erros = ['erro_data_inicio', 'erro_data_fim'];
              let erros_select = ['erro_projeto', 'erro_software'];
              for (let i = 0; i < erros.length; i++) { 
                if((resultado[erros[i]]) && (resultado[erros[i]] != 'vazio')){
                $('#'+erros[i]).html(resultado[erros[i]]);
                $('#'+erros[i].replace('erro_', '')).removeClass();
                $('#'+erros[i].replace('erro_', '')).addClass('invalido form-control');

                $('#'+erros[i].replace('erro_', '')).on('input', ()=> {
                    $('#'+erros[i].replace('erro_', '')).removeClass();
                    $('#'+erros[i].replace('erro_', '')).addClass('form-control');
                    $('#'+erros[i]).html('');
                })
                }
              }
              for (let i = 0; i < erros_select.length; i++) {                 
                    if((resultado[erros_select[i]]) && (resultado[erros_select[i]] != 'vazio')){
                    $('#'+erros_select[i]).html(resultado[erros_select[i]]);
                    $('#'+erros_select[i].replace('erro_', '')+'_chosen').removeClass();
                    $('#'+erros_select[i].replace('erro_', '')+'_chosen').addClass('invalido chosen-container chosen-container-multi');
    
                    $('#'+erros_select[i].replace('erro_', '')).on('input', ()=> {
                        $('#'+erros_select[i].replace('erro_', '')+'_chosen').removeClass();
                        $('#'+erros_select[i].replace('erro_', '')+'_chosen').addClass('chosen-container chosen-container-multi');
                        $('#'+erros_select[i]).html('');
                    })
                    }
                    }
                    if(resultado.status){
                    modal.hide();
                    let status = document.createElement('div');
                    status.setAttribute("id", 'status');
                    document.body.appendChild(status);
                    $('#status').css({'position': 'fixed', 'top':'0', 'width':'100%', 'z-index':'100', 'text-align': 'center', 'color':'white', 'padding':'10px 10px 10px 10px', 
                    'font-size': '17px', 'background':'#0a5a0a'});
                    let progresso = document.createElement('span');
                    progresso.classList.add('progress-bar-fill');
                    progresso.style.cssText = 'width: 0%;';
                    $('#status').html(resultado.status);
                    document.getElementById('status').appendChild(progresso);
                    $('.progress-bar-fill').delay(50).queue(function () {
                        $(this).css('width', '100%')
                    });
                    setTimeout(() =>{
                        window.location.reload();
                    }, 1000);
                    $('#botao_salvar').remove();
                }
                $('#botao_salvar img:last-child').remove();
                $('#botao_salvar').html('Salvar alterações');
                $('#botao_salvar').prop('disabled', false);
            }
      })
    })

waitForElm('.chosen-select-software').then((elm) => {
      setTimeout(() =>{
    $.getScript('../bootstrap/_bootstrap/js/chosen_software.jquery.min.js', function() {
      console.debug('Script loaded.');
    });
    $.getScript('../bootstrap/_bootstrap/js/projeto_booking.js', function() {
      console.debug('Script loaded.');
    });
  }, 250);
});

}
})
})
})
}, 1000);

<?php
  $itens = explode('||', $valor['projeto']);
  $softwares = explode('|||', $valor['software']);
  $inicio = explode('||', $valor['data_inicio']);
  $fim = explode('||', $valor['data_fim']);
  $confirmacao = explode('||', $valor['confirmacao']);

  for($x = 0; $x < count($itens); $x++){

?>
  var start = '<?php echo $inicio[$x]; ?>';
  var end = '<?php echo $fim[$x]; ?>';

  <?php

  if(!empty($valor['projeto'])){

    ?>

  items.add({
    group: <?php echo $i; ?>,
    start: start,
    end: end,
    type: "range",
    content: "<div id='<?php $word = array_merge(range('a', 'z'), range('A', 'Z')); shuffle($word); $aleatorio = substr(implode($word), 0, 100); echo $aleatorio; ?>' title=' Projeto: <?php echo $itens[$x]; ?>&#10;Software: <?php echo str_replace('||', ', ', $softwares[$x]); ?>&#10;início: <?php echo date('d/m/Y', strtotime($inicio[$x])); ?>&#10;fim: <?php echo date('d/m/Y', strtotime($fim[$x])); ?>'><?php if($confirmacao[$x] == '0'){echo '<img src=\'../img/nao_confirmado.png\' style=\'width: 17px;\'><br>';}else{echo '<img src=\'../img/confirmado.png\' style=\'width: 17px;\'><br>';} ?><?php echo $itens[$x].'<br>'.str_replace('||', ', ', $softwares[$x]); ?></div>",
    className: '<?php echo $itens[$x]; ?>',
  });  


  $(document).ready(function(){
  setTimeout(function(){
    $("#<?php echo $aleatorio; ?>").click(function(){

      editarBooking();

    })

      function editarBooking(){
      $("#editar_funcionario").html('');
      $.ajax({
            url: '../utilities/modal_editar_booking.php?id_funcionario=<?php echo $valor['id_funcionario']; ?>&projeto=<?php echo $itens[$x]; ?>&data_inicio=<?php echo $inicio[$x]; ?>&data_fim=<?php echo $fim[$x]; ?>&software=<?php echo $softwares[$x]; ?>&confirmacao=<?php echo $confirmacao[$x]; ?>',
            method: 'GET',
            cache: false,
            contentType: false,
            processData: false,
            success: function(resultado){
    $form = $("<form id='editar_funcionario_booking' method='POST' enctype='multipart/form-data'></form>");
    $("#editar_funcionario").append($form);
    $("#editar_funcionario_booking").html(resultado);
    $("#titulo_editar").html('Editar booking de <?php echo $valor['nome_social']; ?>');
    let el = document.getElementById('editar');
    let modal =new bootstrap.Modal(el);
    modal.show();

    let confirmacao = document.getElementById('confirmacao');

    confirmacao.addEventListener('click', ()=>{
    if(confirmacao.checked){
        document.getElementById('label_confirmacao').innerHTML = "Confirmado";
    }else{
        document.getElementById('label_confirmacao').innerHTML = "Não confirmado";
    }
})

  $("#botao_salvar").click(function(){
    $('#botao_salvar').prop('disabled', true);
        $('#botao_salvar').html('');
        $('#botao_salvar').append('<img src="../img/loading.gif" style="width: 30px;"/>');
    var dados = new FormData(document.getElementById("editar_funcionario_booking"));
      $.ajax({
            url: '../utilities/editar_booking.php?id_funcionario=<?php echo $valor['id_funcionario']; ?>&projeto=<?php echo $itens[$x]; ?>&data_inicio=<?php echo $inicio[$x]; ?>&data_fim=<?php echo $fim[$x]; ?>&software=<?php echo $softwares[$x]; ?>&confirmacao=<?php echo $confirmacao[$x]; ?>',
            method: 'POST',
            dataType: 'json',
            cache: false,
            contentType: false,
            processData: false,
            data: dados,
            success: function(resultado){
              let erros = ['erro_data_inicio', 'erro_data_fim'];
              let erros_select = ['erro_projeto', 'erro_software'];
              for (let i = 0; i < erros.length; i++) { 
                if((resultado[erros[i]]) && (resultado[erros[i]] != 'vazio')){
                $('#'+erros[i]).html(resultado[erros[i]]);
                $('#'+erros[i].replace('erro_', '')).removeClass();
                $('#'+erros[i].replace('erro_', '')).addClass('invalido form-control');

                $('#'+erros[i].replace('erro_', '')).on('input', ()=> {
                    $('#'+erros[i].replace('erro_', '')).removeClass();
                    $('#'+erros[i].replace('erro_', '')).addClass('form-control');
                    $('#'+erros[i]).html('');
                })
                }
              }
              for (let i = 0; i < erros_select.length; i++) {                 
                    if((resultado[erros_select[i]]) && (resultado[erros_select[i]] != 'vazio')){
                    $('#'+erros_select[i]).html(resultado[erros_select[i]]);
                    $('#'+erros_select[i].replace('erro_', '')+'_chosen').removeClass();
                    $('#'+erros_select[i].replace('erro_', '')+'_chosen').addClass('invalido chosen-container chosen-container-multi');
    
                    $('#'+erros_select[i].replace('erro_', '')).on('input', ()=> {
                        $('#'+erros_select[i].replace('erro_', '')+'_chosen').removeClass();
                        $('#'+erros_select[i].replace('erro_', '')+'_chosen').addClass('chosen-container chosen-container-multi');
                        $('#'+erros_select[i]).html('');
                    })
                    }
                    }
                    if(resultado.status){
                    modal.hide();
                    let status = document.createElement('div');
                    status.setAttribute("id", 'status');
                    document.body.appendChild(status);
                    $('#status').css({'position': 'fixed', 'top':'0', 'width':'100%', 'z-index':'100', 'text-align': 'center', 'color':'white', 'padding':'10px 10px 10px 10px', 
                    'font-size': '17px', 'background':'#0a5a0a'});
                    let progresso = document.createElement('span');
                    progresso.classList.add('progress-bar-fill');
                    progresso.style.cssText = 'width: 0%;';
                    $('#status').html(resultado.status);
                    document.getElementById('status').appendChild(progresso);
                    $('.progress-bar-fill').delay(50).queue(function () {
                        $(this).css('width', '100%')
                    });
                    setTimeout(() =>{
                        window.location.reload();
                    }, 1000);
                    $('#botao_salvar').remove();
                }
                $('#botao_salvar img:last-child').remove();
                $('#botao_salvar').html('Salvar alterações');
                $('#botao_salvar').prop('disabled', false);
            }
      })
    })

    waitForElm('.chosen-select-software').then((elm) => {
      setTimeout(() =>{
    $.getScript('../bootstrap/_bootstrap/js/chosen_software.jquery.min.js', function() {
      console.debug('Script loaded.');
    });
    $.getScript('../bootstrap/_bootstrap/js/projeto_booking.js', function() {
      console.debug('Script loaded.');
    });
  }, 250);
});
    }
  })
}
})}, 1000);

<?php }else{ ?>

  items.add({
    group: <?php echo $i; ?>,
    start: '<?php echo  date('Y-m-d', strtotime('-4 month', strtotime(date('Y-m-d')))); ?>',
    end: '<?php echo  date('Y-m-d'); ?>',
    content: '<div class="row justify-content-center">NENHUMA INFORMAÇÃO DE BOOKING ENCONTRADA</div>',
  });  


<?php
}
}
$i++;
}
?>


// create a Timeline
var container = document.getElementById("booking");
timeline = new vis.Timeline(container, null, options);
timeline.setGroups(groups);
timeline.setItems(items);

function debounce(func, wait = 100) {
  let timeout;
  return function (...args) {
    clearTimeout(timeout);
    timeout = setTimeout(() => {
      func.apply(this, args);
    }, wait);
  };
}

function move(percentage) {
  var range = timeline.getWindow();
  var interval = range.end - range.start;

  timeline.setWindow({
    start: range.start.valueOf() - interval * percentage,
    end: range.end.valueOf() - interval * percentage,
  });
}

document.getElementById("zoomIn").onclick = function () {
  timeline.zoomIn(0.5);
};
document.getElementById("zoomOut").onclick = function () {
  timeline.zoomOut(0.5);
};
document.getElementById("moveLeft").onclick = function () {
  move(0.2);
};
document.getElementById("moveRight").onclick = function () {
  move(-0.2);
};

function waitForElm(selector) {
    return new Promise(resolve => {
        if (document.querySelector(selector)) {
            return resolve(document.querySelector(selector));
        }

        const observer = new MutationObserver(mutations => {
            if (document.querySelector(selector)) {
                resolve(document.querySelector(selector));
                observer.disconnect();
            }
        });

        observer.observe(document.body, {
            childList: true,
            subtree: true
        });
    });
}
</script>

This is the timeline:

timeline

In case someone needs it, I'll leave the solution here, even if I find it difficult for someone to need it.

After a lot of breaking my head doing tests, I realized the following:

Items are only created as the scroll goes down and the groups appear.

That is, when I put the events for items that are not visible on the screen, they were not created, so there is no way to call the event, because its ID does not exist yet.

The solution was to use the MutationObserver API to check when the element exists on the page and apply a function to it.

<script>
   function waitForElm(selector) {
    return new Promise(resolve => {
        if (document.querySelector(selector)) {
            return resolve(document.querySelector(selector));
        }

        const observer = new MutationObserver(mutations => {
            if (document.querySelector(selector)) {
                resolve(document.querySelector(selector));
                observer.disconnect();
            }
        });

        observer.observe(document.body, {
            childList: true,
            subtree: true
        });
    });
}
</script>

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