Conflict between scripts in my html file

0

I am creating a web application where the main page is a timeline, and this timeline should update its content automatically. I'm using the setTimeOut function of JQuery to update the timeline every x seconds.

But I also have another JavaScript code that serves to show hidden elements of that item by clicking on the div.

The two code work perfectly when alone, except when I try to use both on the page. The error is as follows After the timeline is updated by setTimeOut, the second code (clicking on the div to show / hide elements) no longer works. I tried to solve it in several ways and I could not and also I did not find solutions. Does anyone know what can it be? I also accept tips on how to upgrade my timeline, such as updating only when there are new item registrations, instead of every x seconds.

setTimeout("my_function();", 9000);
    function my_function() {
      $('#timeline').load(location.href + ' #timeline')
    }
    
$(document).ready(function () {
      var itemsDivs = document.querySelectorAll('.timeline-item');
      itemsDivs.forEach(function (itemsDiv) {

        itemsDiv.addEventListener('click', function () {
          var itemId = this.getAttribute('item-id')
          var display = document.getElementById('comment-form-' + itemId).style.display
          if (display == 'none')
            document.getElementById('comment-form-' + itemId).style.display = 'block'
          else
            document.getElementById('comment-form-' + itemId).style.display = 'none'
        })
      })
    })
<div class="container-fluid">
    <div class="row example-basic">
      <div class="col-xs-10 col-xs-offset-1 col-sm-8 col-sm-offset-2">
        <ul class="timeline" id="timeline">
          {% for item in items %}
          <li item-id={{item.id}} class="timeline-item">
            <div class="timeline-info">
              <span>{{item.data.strftime('%c')}}</span>
            </div>
            <div class="timeline-marker"></div>
            <div class="timeline-content">
              <h3 class="timeline-title">{{item.analista}} recomenda {{item.ativo}} a R${{item.preco}}.</h3>
              <p>Fonte:{{item.fonte}}</p>
            </div>
            <div id="comment-form-{{ item.id }}" style="display: none;">
              {{item.coments}} <br><span id='dataalvo'>Data Alvo: {{item.dataalvo}}</span>
            </div>
          </li>
          {% endfor %}
          <li class="timeline-item period">
            <div class="timeline-info"></div>
            <div class="timeline-marker"></div>
          </li>
        </ul>
      </div>
    </div>

OBS: I have a unique page to register new items to the database, the timeline returns the items in the DB.

    
asked by anonymous 10.12.2018 / 00:05

1 answer

0

The reason for the behavior is because you only bind EventListener to page load ... so the elements that were added later do not receive this assignment, you can highlight those new elements that did not receive them or simply remove them and add them again to each load.

setTimeout(() => {
  $('#timeline').load(location.href + ' #timeline', () => {
    updateBindings();
  });
}, 9000);

let updateBindings = function() {
  var itemsDivs = document.querySelectorAll('.timeline-item');
  itemsDivs.forEach(function(itemsDiv) {

    itemsDiv.addEventListener('click', function() {
      var itemId = this.getAttribute('item-id')
      var display = document.getElementById('comment-form-' + itemId).style.display
      if (display == 'none')
        document.getElementById('comment-form-' + itemId).style.display = 'block'
      else
        document.getElementById('comment-form-' + itemId).style.display = 'none'
    })
  })
};


$(document).ready(function() {
  updateBindings();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script><divclass="container-fluid">
  <div class="row example-basic">
    <div class="col-xs-10 col-xs-offset-1 col-sm-8 col-sm-offset-2">
      <ul class="timeline" id="timeline">
        {% for item in items %}
        <li item-id={{item.id}} class="timeline-item">
          <div class="timeline-info">
            <span>{{item.data.strftime('%c')}}</span>
          </div>
          <div class="timeline-marker"></div>
          <div class="timeline-content">
            <h3 class="timeline-title">{{item.analista}} recomenda {{item.ativo}} a R${{item.preco}}.</h3>
            <p>Fonte:{{item.fonte}}</p>
          </div>
          <div id="comment-form-{{ item.id }}" style="display: none;">
            {{item.coments}} <br><span id='dataalvo'>Data Alvo: {{item.dataalvo}}</span>
          </div>
        </li>
        {% endfor %}
        <li class="timeline-item period">
          <div class="timeline-info"></div>
          <div class="timeline-marker"></div>
        </li>
      </ul>
    </div>
  </div>
Also, as mentioned in the comments, another point of attention is the content that you are loading in the load() method ... if your backend is not prepared to return only items you would be loading content again content of the entire page of <ul id="timeline"> .

    
10.12.2018 / 16:00