PlayHardGoPro PlayHardGoPro - 10 days ago 7
Ajax Question

Update script to new element injected into DOM

I have a list with sublists and a < select> box.

Everytime I change the select box, I need to RELOAD this list with the new

parameter (selected value).

I'm using ajax to get the new data, then I remove the list, and inject the new element (same list with new data) into DOM.

<script type="text/javascript">
$('#selectSemestres').change(function(obj){
var anoSemestre = $(this).val();
$.ajax({
type: 'GET',
url: '{{ route('professor') }}',
data: {anoSemestre: anoSemestre},
success: function(data){
var lista = $(data).find('#list-professores'); //Get only the new professor list and thier disciplines
$('#list-professores').remove(); //Remove old list
$('#professores').append(lista); //Append the new list where the old list was before.
load_js();
$('.prof-disciplinas').sortable({
connectWith: '.prof-disciplinas'});
}
});
});
</script>


The problem is: When you insert a new element to the dom, you need to "reload" your javascript so it would recognize the new element. That's what I do with
load_js()
method.

function load_js()
{
var head= document.getElementsByTagName('head')[0];
var script= document.createElement('script');
script.type = 'text/javascript';
script.src = 'js/script.js';
head.appendChild(script);
}


But I have another
<script > ... </script>
inside the same .php file that I need to RELOAD it so it would work with this new list:

Script that I need to reload and use Drag&Drop with the new list



<script type="text/javascript">
$(function(){
var oldTeacherId;
$('.prof-disciplinas').sortable({
connectWith: '.prof-disciplinas',

start: function (event, ui){
oldTeacherId = ui.item.parent().prev().prev().attr('data-id');
},
stop: function (event, ui){

$.ajax({
type: "POST",
url: '{{ URL::to("/professor") }}',
data: {
disciplina: ui.item.attr('data-id'),
professor: ui.item.parent().prev().prev().attr('data-id'),
old: oldTeacherId
},
success: function(data){
swal("Good job!", "You clicked the button!", "success");
//Atualizar tabela aqui
var evento = $('#calendario').fullCalendar('clientEvents', function(event){

return event.id == $(ui.item).attr('data-id');
});
evento[0].backgroundColor = '' + getCor( ui.item.parent().prev().prev().attr('data-id'));
$('#calendario').fullCalendar('updateEvent', evento[0]);
},
error: function(){

}

});
}
});
});
</script>


This Drag&Drop effect is not working after ajax.

How may I reload that piece of script ? Make it recognize and work with the new inserted list?

Answer

That's completely wrong way to achieve things in JavaScript.

Let's start with first example:

$('#selectSemestres').change(function(obj){...})

Could be replaced with:

$('body').on('change', '#selectSemestres', function(obj){...})

http://api.jquery.com/on/

As for your second piece of code, you can extract it into a separate function, and call it every time you need to reload your data:

var oldTeacherId;
function reloadTeachers() {
  $('.prof-disciplinas').sortable({
    connectWith: '.prof-disciplinas',

    start: function(event, ui) {
      oldTeacherId = ui.item.parent().prev().prev().attr('data-id');
    },
    stop: function(event, ui) {

      $.ajax({
        type: "POST",
        url: '{{ URL::to("/professor") }}',
        data: {
          disciplina: ui.item.attr('data-id'),
          professor: ui.item.parent().prev().prev().attr('data-id'),
          old: oldTeacherId
        },
        success: function(data) {
          swal("Good job!", "You clicked the button!", "success");
          //Atualizar tabela aqui
          var evento = $('#calendario').fullCalendar('clientEvents', function(event) {

            return event.id == $(ui.item).attr('data-id');
          });
          evento[0].backgroundColor = '' + getCor(ui.item.parent().prev().prev().attr('data-id'));
          $('#calendario').fullCalendar('updateEvent', evento[0]);
        },
        error: function() {

        }

      });
    }
  });
}

$(function() {
  reloadTeachers(oldTeacherId);
});

Note that using global variables is a bad practice, and oldTeacherId should be encapsulated in the final solution.