Не удается найти элемент в 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/
Я надеюсь, что это будет полезно для кого-то.