Не удается найти элемент в DOM после загрузки его с помощью ajax (хотите связать его с jquery)

Итак, у меня есть 2 html-страницы. 1, который функционирует как контейнер и 1, который функционирует как контент. Когда я загружаю страницу содержимого в таблицу, я могу использовать перетаскивание.

Но когда я перехожу на мою страницу с контейнером и загружаю страницу контента в div с помощью ajax, перетаскивание перестает работать. Все остальные функции javascript внутри страницы контента все еще работают. Как связать плагин jquery dnd с таблицей, загруженной с помощью ajax?

Я использую drag and drop с этим в качестве учебника http://isocra.com/2008/02/table-drag-and-drop-jquery-plugin/

мой код выглядит следующим образом:

$(window).load(function()
{   if(temp == 0)
    { 
        DP("eerste keer")
        load_table(); 
        temp = 1;
    }
} );

function load_table()
{    
    DP('load_table');
    $.ajax({
            //async: false,
            type: "POST",
            url: "/diagnose_hoofdpagina/table_diagnose/" + DosierID, // <== loads requested page
            success: function (data) {
                    $("#diagnoses_zelf").html(''); //<== clears current content of div
                    $("#diagnoses_zelf").append(data).trigger('create'); // <== appends requested page
                },
            error: function(){
                alert('error');
              } 
        }).done(function() {
        update_table(); 
        initialize_table();    // <== calls jquery plug in
        });

    return false;   
}


function initialize_table() 
{
    var tableid = $('#diagnoses_zelf table').attr('id'); //< this finds the correct table thanks to Fábio Batista => this option worked, rest didn't
    alert(tableid);
    $(tableid).tableDnD({    
        onDrop: function(table, row) {
        alert(table + "     "  +  row);

        },
        onDragStart: function(table,row){
        var tette = $(row).index;
        alert(tette);
        },
        dragHandle: ".dragHandle"
    });     
}

enter image description here

Как это возможно и что я могу с этим поделать? Может ли кто-нибудь помочь мне с этим, пожалуйста.

Очень короткий: Я хочу получить доступ к идентификатору таблицы, которую я загружаю на мою страницу контейнера, с помощью ajax и использовать на нем перетаскиватель jQuery.

ИЗМЕНИТЬ

Выводы:

Как-то моя таблица на странице контейнера переименовалась в pSqlaTable вместо идентификатора, который я дал ей на странице контроллера.

<table id="tableDiagnose" class="table table-hover">

Вот почему код не смог найти таблицу annymore. Исправлено этим кодом благодаря Fábio Batista:

$('#diagnoses_zelf table').tableDnD( ... );

но как я могу теперь использовать плагин dnd?

Теперь он находит таблицу, но я до сих пор не могу привязать к ней плагин dnd. Могу ли я подключить jquery-plug-in к загруженным таблицам ajax?

ИЗМЕНИТЬ

//drag & drop http://isocra.com/2008/02/table-drag-and-drop-jquery-plugin/
function initialize_table() 
{
    var tableid = $('#diagnoses_zelf table').attr('id');
    alert(tableid);
    $('#' + tableid).tableDnD({    
        onDrop: function(table, row) {
        alert(table + "     "  +  row);

        },
        onDragStart: function(table,row){
        alert('issemer?');
        },
        dragHandle: ".dragHandle"
    });    
} 

Это код, который я все еще придерживаюсь. tableid корректен, но инициализация jquery не является. Я не могу перетащить дрочки в таблицу. Является ли мой синтаксис неправильным?

ИЗМЕНИТЬ

Может быть, я не могу привязать jquery к таблице, потому что я динамически генерирую таблицу на другой странице с помощью ZPT (или javascript)?

Ответы

Ответ 1

Проблема с плагинами.

Вы смешиваете множество внешних библиотек и кода. Это приводит к возможным неправильным совпадениям между версиями и множеству черных ящиков в вашем коде.

Как разработчик, это должно заставить вас чувствовать себя очень непросто. Наличие кода, который вы не вполне понимаете в своей базе кода, может действительно расстраивать очень быстро.

Альтернатива.

Часто такие плагины обеспечивают функциональность, которую мы, как разработчики JavaScript, можем выполнить так же легко без них. Этот процесс разработки, в достаточно простых сценариях, позволяет нам создавать код, который мы понимаем, и иметь более легкое время. Мы не только изучаем этот процесс, но также создаем меньшие бит определенного кода. Решения на уровне сообщества очень хороши в целом, но важно помнить, что они не серебряная пуля. Часто вы застряли, используя не очень активный проект, который имеет ошибку для вашего конкретного случая, и вам нужно прорыть большую, незнакомую базу кода.

Ваш код

Итак, что делает этот плагин drag and drop?

Хорошо, я сломал бы это как:

  • Слушает событие mousedown в строках таблицы
  • Когда такое событие срабатывает, начните перемещать строку таблицы в соответствии с позицией мыши.
  • Когда mouseup происходит, обнаруживает это и завершает позицию.

Посмотрим, как мы можем сделать что-то подобное. Предположим, что таблица HTML выглядит примерно так:

<table>
    <tbody>
    <tr>
        <td> Hello 1</td>
    </tr><tr>
        <td> Hello 2</td>
    </tr>
    </tbody>
</table>

Вот скрипка с таблицей с примененным базовым стилем

Затем мы выслушаем события выбора. Мы добавим событие в строки таблицы для выбора и в документ, когда мышь встанет. jQuery имеет прослушиватели событий для таких событий. Поскольку мы хотим, чтобы эти события сохранялись даже после AJAX, мы будем использовать .on, который позволяет использовать делегированные события. .on означает, что даже если мы добавим контент в таблицу позже, это не имеет значения.

var selected; // currently selected row
$(document).on("mousedown","#MySpecialTable tr",function(){
   $("#textDiv").text(this.textContent); 
    selected = this;
});
$(document).on("mouseup",function(){
    $("#textDiv").text("Left "+selected.textContent); 
    selected = null;
});

Вот рабочая скрипка такого кода.

Теперь мы захотим на самом деле изменить drag & drop для работы, если, то есть обновить текущую позицию до той, которая отражает позицию мыши. Мы можем слушать события mousemove и обнаруживать элемент, в котором мы сейчас находимся. Что-то вроде

$(document).on("mousemove",function(e){
    $("#textDiv").text($(e.target).html());
});

Здесь вы можете увидеть рабочую скрипту

Это хорошо, но мы хотим изменить положение элемента. Поэтому нам нужно изменить структуру таблицы, чтобы это разрешить. Мы можем удалить элемент и добавить его в правильное положение. Мы проверим, есть ли у нас выделенный элемент, и если да, мы можем отслеживать его по сравнению с текущим элементом в событии mousemove. Мы можем для начинающих определить, нужно ли нам перетаскивать что-то вроде:

$(document).on("mousemove",function(e){
    if(selected !=null){// got an element selected
        if($("#MySpecialTable").has(e.target).length > 0){ //in the table
            $("#mousePos").text("DRAGGING");    
        }
    }else{
        $("#mousePos").text("NOT SELECTED");
    }
});

(Fiddle)

Теперь мы добавим фактический выбор, заменим элементы, когда цель не является нашим элементом, и мы находимся в таблице. Наш полный код должен выглядеть примерно так:

var selected;
$(document).on("mousedown","#MySpecialTable tr",function(e){
    e.preventDefault();//stop the text selection;
   $("#textDiv").text(this.textContent); 
    selected = $(this);
    selected.find("td").css("background-color","#999");
});
$(document).on("mouseup",function(){
    $("#textDiv").text("Left "+selected.text()); 
    selected.find("td").css("background-color","");
    selected = null;
});
$(document).on("mousemove",function(e){
    if(selected !=null){// got an element selected
        if($("#MySpecialTable").has(e.target).length > 0){ //in the table
            var el = $(e.target).closest("tr");//the tr element we're on
            el.before(selected);// replace the elements
        }
    }else{
        $("#mousePos").text("NOT SELECTED");
    }
});

$("#MySpecialTable").on('selectstart', false);//Don't let the user select the table

(Fiddle)

Теперь у нас есть только несколько строк кода, что хорошо, потому что мы точно знаем, что происходит, и не нужно использовать множество строк внешнего кода, которые мы не полностью понимаем.

Но будет ли это AJAX?

Позвольте загружать данные в таблицу с помощью AJAX и видеть! Мы будем моделировать ответ AJAX с помощью setTimeout, который позволит нам имитировать асинхронный запрос. Мы будем использовать

setTimeout(function(){
    $("#MySpecialTable").html("<tr><td> Hello 1</td></tr><tr><td> Hello 2</td></tr><tr><td> Hello 3</td></tr><tr><td> Hello 4</td></tr><tr><td> Hello 5</td></tr><tr><td> Hello 6</td></tr>");
},1000);

Это означает, что через одну секунду обновите HTML #MySpecialTable. Посмотрим, сработает ли это?

Так почему это работает? Итак, мы использовали делегированные события, что означает, что нам все равно, будут ли элементы, которые мы загружаем, прямо сейчас на экране. У нас было понимание этого, поскольку мы сами построили наш код и знали, какова была наша конечная цель. Осталось только немного очистить код.

Мы завершим наш код следующим, чтобы предотвратить $от проблемы в неконфликтном режиме (т.е. $уже сделан на странице:

(function($){

})(jQuery);

Далее мы добавим привязку для нашего события таблицы:

$.GertVDragTable = function(elementSelector){ // rest of code.

В конце концов, наш код может выглядеть примерно так.

Используя это, было бы просто $.GertVDragTable("#MySpecialTable");, в качестве альтернативы, мы можем поместить его на $.fn и позволить каждой функции вызывать его. Это вопрос вкуса.

Никаких копий-макарон пожалуйста:) Я был бы признателен, если бы вы остановились на каждом этапе и подумали, почему был сделан следующий шаг.

Ответ 2

Вам не нужно использовать идентификатор в качестве селектора, вы можете использовать любое выражение, которое может найти вашу таблицу.

Если в результирующем вызове $.ajax имеется только одна таблица, вы можете искать "таблицу внутри контейнера", используя идентификатор контейнера, который не изменится:

$('#diagnoses_zelf table').tableDnD( ... );

Если имеется более одной таблицы, используйте идентификатор другого типа, а не идентификатор. Класс CSS отлично работает:

$('table.table-diagnose').tableDnD( ... );

Значит, атрибут data-:

$("table[data-diagnose]").tableDnD( ... );

Ответ 3

Попробуйте добавить title к своей таблице, например:

<table id = "tableDiagnose" class = "table table-hover" title = "table-content">

Затем используйте селектор атрибутов jQuery , чтобы найти эту таблицу, а не найти ее id.

$('table[title="table-content"]').tableDnD({ 
// the rest of your code

Ответ 4

Если ваш идентификатор меняется, вы не должны использовать идентификатор:

<table class="tableDiagnose table table-hover">

Plugin

function initialize_table() 
{
    $('.tableDiagnose.table').tableDnD({    
        onDrop: function(table, row) {
        alert(table + "     "  +  row);
        },
        dragHandle: ".dragHandle"
    });   
    DP('nee');  
}

EDIT: ajax является асинхронным:

function load_table()
{    
    DP('load_table');
    $.ajax({
            //async: false,
            type: "POST",
            url: "/diagnose_hoofdpagina/table_diagnose/" + DosierID, // <== loads requested page
            success: function (data) {
                    $("#diagnoses_zelf").html(''); //<== clears current content of div
                    $("#diagnoses_zelf").append(data).trigger('create'); // <== appends requested page
                    update_table(); 
                    initialize_table();    // <== calls jquery plug in
                },
            error: function(){
                alert('error');
              } 
        });
        //removed .done as you already have a success option in ajax


    return false;   
}

РЕДАКТИРОВАТЬ: нашел вашу ошибку........ вы извлекаете идентификатор таблицы и выбираете его в $(tableid), но вы пропустили #

function initialize_table() 
{
    /*
    var tableid = $('#diagnoses_zelf table').attr('id'); //< this finds the correct table thanks to Fábio Batista => this option worked, rest didn't
    alert(tableid);
    // but you really should limit the use of variables when you don't need them*/
    //$('#'+tableid).tableDnD({            
    //like this directly
    $('#diagnoses_zelf table').tableDnD({    
        onDrop: function(table, row) {
        alert(table + "     "  +  row);

        },
        onDragStart: function(table,row){
        var tette = $(row).index;
        //alert(tette);
        },
        dragHandle: ".dragHandle"
    });     
}

Смотрите демо здесь

ИЗМЕНИТЬ

Ответ 5

Включите ли вы файл script на странице контейнера или на странице содержимого? Возможно, вы захотите загрузить его при вызове dnd-плагина с помощью getScript:

...
$.getScript('pathTotableDnDlib').done(function(){
    $(tableid).tableDnD({    
    onDrop: function(table, row) {
    alert(table + "     "  +  row);

    },
    onDragStart: function(table,row){
    var tette = $(row).index;
    alert(tette);
    },
    dragHandle: ".dragHandle"
});});
...

подробнее о getscript: здесь

Ответ 6

@BenjaminGruenbaum Привет, много для учебника, я немного изменил код, чтобы заблокировать перетаскивание n'drop на заголовках таблицы и улучшить текучесть движений в направлении мыши.

var old_y = 0;
(function ($) {
    $.GertVDragTable = function (tableName) {
        var selected;
        $(document).on("mousedown", tableName+" tr",function (e) {
            e.preventDefault(); //stop the text selection;
            if (($(this).find('th').length)== 0){   //prevent dragging on tr containing th
            selected = $(this);
            selected.find("td").css("background-color", "black");
            selected.find("td").css("color", "white");
            }
        });

        $(document).on("mouseup", function () {
            selected.find("td").css("background-color", "");
            selected.find("td").css("color", "");
            selected = null;
        });
        $(document).on("mousemove", function (e) {
            if (selected != null ) { // got an element selected
                if ($(tableName).has(e.target).length > 0) { //in the table
                    var el = $(e.target).closest("tr"); //the tr element we're on
                    if (el.find('th').length==0){ //prevent dropping on headers row

                    if (e.pageY > old_y){       //**
                    el.after(selected);}else{   //**-->more fluid dragging based on mouse direction
                        el.before(selected);    //**
                    }

                }
                }
                old_y = e.pageY;
            }
        });

        $(tableName).on('selectstart', false); //Don't let the user select the table
    }
})(jQuery);

здесь скрипка http://jsfiddle.net/59rdq/

Я надеюсь, что это будет полезно для кого-то.