2

Идея довольно проста и почти работает. Существует две таблицы, и пользователь имеет возможность перетаскивать строки между двумя таблицами. Когда строка перетаскивается из таблицы 1 в таблицу2, ajax используется для обновления базы данных данными, которые удаляются из таблицы 1, добавляется в таблицу2 и повторно отображает обе таблицы с новыми данными. То же самое работает, если информация перетаскивается из таблицы2 в таблицу1.Перетаскивание строк между столами

Вы можете увидеть образец кода here.

Вот отрывок кода Javascript для одной из таблиц:

var startTable = "table1"; 
var $tabs=$("#" + startTable); 
$("tbody.connectedSortable") 
.sortable({ 
    connectWith: ".connectedSortable", 
    items: "> tr:not(:first)", 
    appendTo: $tabs, 
    helper:"clone", 
    cursor:"move", 
    zIndex: 999990 
}) 
.disableSelection() 
; 
$($tabs).droppable({ 
    accept: ".connectedSortable tr", 
    hoverClass: "ui-state-hover", 
    drop:function(event, ui){ 
     var start= ui.draggable.attr("id"); 
     var desTable = $(this).attr("id"); 
     if(start != desTable){ 
      alert("The ajax should be called"); 
     } 
     return false; 
    } 
}); 

Он отлично работает только для одного случая, за исключением. Если строка перетаскивается из Таблицы 1 в Таблицу 2, она создает слот, чтобы показать, где строка будет вставлена ​​при отпускании строки. Другими словами, если пользователь перетаскивает строку из Таблицы 1 в последний элемент таблицы 2, она создает открытое место-держатель (под последней строкой в ​​таблице 2), чтобы отображать, куда будет идти строка при отпускании. Есть одна проблема с этим. Если создатель места создан, но строка затем перетаскивается за пределы таблицы и отпускается, строка по-прежнему переходит к владельцу места, но свойство перетаскивания никогда не вызывается.

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

Каждый пример, который я пробовал, который перетаскивает строки между двумя таблицами, имеет ту же проблему. Вы, ребята, имеете какой-либо способ вызвать droppable code, даже если строка выпадает за пределами таблицы? Или, может быть, есть лучший способ вызвать ajax, а не когда строка выпадает на стол? Любое понимание было бы весьма благодарным.

+0

вы можете использовать событие update в sortable вместо события drop. –

+0

Было бы замечательно, если бы все было так просто. Я буду работать над ним примерно через час и затем опубликую результаты. Благодарю. – Brian

+0

Событие обновления похоже на то, что я ищу. Я изменил свой код, чтобы использовать обновление, но я столкнулся с ошибкой.Обновление из таблицы 1 никогда не вызывается, вызывается только обновление из таблицы2. Кроме того, если я перетаскиваю из таблицы1 в таблицу2, обновление table2 вызывается дважды. Вот скрипка: http://jsfiddle.net/bhealy/t011juda/28/ Любая идея, что происходит? – Brian

ответ

4

Для инициирования Ajax запроса, когда строка удаляется из одной таблицы в другую можно использовать receive событие из sortable виджета.

Это событие срабатывает, когда элемент из связного списка сортировки уронили в другой список. Последним является цель события.

(курсив мой)

Updated Fiddle (Частичный результат, см ниже фрагмент кода для окончательного демо)

Внутри приема обратного вызова, вы можете получить доступ к отброшенной строку, используя item недвижимость второго аргумента (ui.item).

Если получение обратного вызова событие срабатывает, это означает, что ui.item был добавлен в таблице this ($(this).closest("table.mytable")) и удаляются из другой таблицы ($("table.mytable").not($(this).closest("table.mytable"))). Затем вы можете вызвать запрос (ы) ajax соответственно.

Делая это таким образом, вам не придется вручную проверить произошло ли падение в пределах одной таблицы или нет (Вы должны будете сделать это, если вы используете update события, как кто-то предложил).


На данный момент, вы излишне инициализация сортируется дважды:

$("tbody.connectedSortable").sortable({ 
    connectWith: ".connectedSortable", 
    items: "> tr:not(:first)", 
    appendTo: $tabs, 
    helper:"clone", 
    cursor:"move", 
    zIndex: 999990 
}) 

и

$("tbody.connectedSortable").sortable({ 
    connectWith: ".connectedSortable", 
    items: "> tr:not(:first)", 
    appendTo: $tabs2, 
    helper:"clone", 
    cursor:"move", 
    zIndex: 999990 
}); 

Селектор tbody.connectedSortable применим к обеим таблицам, следовательно, это будет просто переопределить предыдущую инициализацию. В результате вспомогательный клон всегда будет прикреплен ко второй таблице ($tabs2). Вероятно, это не то, что вы хотите - из того, что вы дважды инициализируете, просто добавляя клон соответствующему родительскому элементу. Значение по умолчанию appendTo - "parent", просто удаление его из инициализации выполнит эту работу.

Кроме того, это хорошая идея, чтобы переместить строки заголовка из <tbody> в <thead> элемента, так что вы можете не указывать items: "> tr:not(:first)": это более семантический, а также немного лучше для производительности, так как JQuery UI не нужно искать недопустимые элементы, если эта опция не указана.

И, наконец, у вас есть дубликат id, который недействителен. Для группировки набора элементов вместо этого используйте общий класс.


$(document).ready(function() { 
 
    $("tbody.connectedSortable").sortable({ 
 
    connectWith: ".connectedSortable", 
 
    helper: "clone", 
 
    cursor: "move", 
 
    zIndex: 99999, 
 
    receive: function(event, ui) { 
 
     /* here you can access the dragged row via ui.item 
 
     ui.item has been removed from the other table, and added to "this" table 
 
     */ 
 
     var addedTo = $(this).closest("table.mytable"), 
 
     removedFrom = $("table.mytable").not(addedTo); 
 
     alert("The ajax should be called for adding to " + addedTo.attr("id") + " and removing from " + removedFrom.attr("id")); 
 
    } 
 
    }); 
 
});
.mytable a:link, 
 
.mytable a:visited { 
 
    color: #fff; 
 
    font-weight: bold; 
 
    text-decoration: none; 
 
} 
 
.mytable a:active, 
 
.mytable a:hover { 
 
    color: #bd5a35; 
 
    text-decoration: underline; 
 
} 
 
table.mytable { 
 
    width: 90%; 
 
    font-family: Arial, Helvetica, sans-serif; 
 
    color: #666; 
 
    margin-left: auto; 
 
    margin-right: auto; 
 
    font-size: 12px; 
 
    background: #eaebec; 
 
    border: #ccc 1px solid; 
 
    -moz-border-radius: 3px; 
 
    -webkit-border-radius: 3px; 
 
    border-radius: 3px; 
 
    -moz-box-shadow: 10px 10px 5px #888; 
 
    -webkit-box-shadow: 10px 10px 5px #888; 
 
    box-shadow: 10px 10px 5px #888; 
 
} 
 
.mytable th { 
 
    color: #fff; 
 
    padding: 21px 25px 22px 25px; 
 
    border-top: 1px solid #fafafa; 
 
    border-bottom: 1px solid #e0e0e0; 
 
    background: #191970; 
 
} 
 
.mytable th:first-child { 
 
    text-align: center; 
 
    padding-left: 20px; 
 
} 
 
.mytable tr { 
 
    text-align: center; 
 
    padding-left: 20px; 
 
} 
 
.mytable tr td:first-child { 
 
    text-align: center; 
 
    padding-left: 20px; 
 
    border-left: 0; 
 
} 
 
.mytable tr td { 
 
    padding: 18px; 
 
    border-top: 1px solid #ffffff; 
 
    border-bottom: 1px solid #e0e0e0; 
 
    border-left: 1px solid #e0e0e0; 
 
    background: #fafafa; 
 
    background: -webkit-gradient(linear, left top, left bottom, from(#fbfbfb), to(#fafa fa)); 
 
    background: -moz-linear-gradient(top, #fbfbfb, #fafafa); 
 
} 
 
.mytable tr.even td { 
 
    background: #f6f6f6; 
 
    background: -webkit-gradient(linear, left top, left bottom, from(#f8f8f8), to(#f6f6 f6)); 
 
    background: -moz-linear-gradient(top, #f8f8f8, #f6f6f6); 
 
} 
 
.mytable tr:last-child td { 
 
    border-bottom: 0; 
 
} 
 
.mytable tr:last-child td:first-child { 
 
    -moz-border-radius-bottom-left: 3px; 
 
    -webkit-border-bottom-left-radius: 3px; 
 
    border-bottom-left-radius: 3px; 
 
} 
 
.mytable tr:last-child td:last-child { 
 
    -moz-border-radius-bottom-right: 3px; 
 
    -webkit-border-bottom-right-radius: 3px; 
 
    border-bottom-right-radius: 3px; 
 
} 
 
.mytable tr:hover td { 
 
    background: #f2f2f2; 
 
    transform: scale(1.01); 
 
    padding-left: 20px; 
 
    outline: 1px solid #191970; 
 
    -moz-box-shadow: 10px 10px 5px #888; 
 
    -webkit-box-shadow: 10px 10px 5px #888; 
 
    box-shadow: 10px 10px 5px #888; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<script src="http://code.jquery.com/ui/1.9.2/jquery-ui.js"></script> 
 
<table id='table1' class="mytable"> 
 
    <thead> 
 
    <tr class="table1"> 
 
     <th>col1</th> 
 
     <th>col2</th> 
 
     <th>col3</th> 
 
     <th>col4</th> 
 
    </tr> 
 
    </thead> 
 

 
    <tbody class="connectedSortable"> 
 

 
    <tr class="table1"> 
 
     <td>a</td> 
 
     <td>b</td> 
 
     <td>c</td> 
 
     <td>d</td> 
 
    </tr> 
 
    <tr class="table1"> 
 
     <td>e</td> 
 
     <td>f</td> 
 
     <td>g</td> 
 
     <td>h</td> 
 
    </tr> 
 
    </tbody> 
 
</table> 
 
<table id='table2' class="mytable"> 
 
    <thead> 
 
    <tr class="table2"> 
 
     <th>COL1</th> 
 
     <th>COL2</th> 
 
     <th>COL3</th> 
 
     <th>COL4</th> 
 
    </tr> 
 
    </thead> 
 
    <tbody class="connectedSortable"> 
 

 
    <tr class="table2"> 
 
     <td>1</td> 
 
     <td>2</td> 
 
     <td>3</td> 
 
     <td>4</td> 
 
    </tr> 
 
    <tr class="table2"> 
 
     <td>5</td> 
 
     <td>6</td> 
 
     <td>7</td> 
 
     <td>8</td> 
 
    </tr> 
 
    </tbody> 
 
</table>

Примечание стороны: я объединил аналогичные CSS классы

Метод disableselection() осуждается из JQuery UI 1.9+

+0

Мне очень нравится эта реализация и ценю усилия, которые вы вложили в нее, но я столкнулся с проблемой. То, как выполняется код, - это основной файл php, который ссылается на файлы ajax для создания таблиц: один на onload и другой onclick. Файлы ajax, похоже, не могут найти сортируемую функцию (которая была записана в основном файле), потому что таблицы не перетаскиваются. Но если таблицы были вручную созданы как html в основном файле (вместо использования какого-либо ajax), код работает. Есть идеи? – Brian

+0

@Brian Я действительно не понимаю, что вы подразумеваете под «ajax-файлами», но если вы динамически создаете совершенно новую таблицу, вы должны инициализировать их как сортировки после создания, тот факт, что вы инициализировали старые таблицы как сортируемые, будет не автоматически создавать новую сортировку. Если вы говорите о том, что новые строки не распознаются как сортируемые элементы, загляните в [refresh] (http://api.jqueryui.com/sortable/#method-refresh). Если вы говорите о том, что что-то еще не работает в динамически созданных элементах, это, вероятно, проблема [event Delegation] (http://stackoverflow.com/q/203198/2333214). –

+1

Я уверен, что с вашей помощью я успешно выполнил все правильно. Спасибо =) – Brian

2

Я думаю, что эта скрипка дает вам то, что вы хотите: http://jsfiddle.net/t011juda/31/

$(document).ready(function() { 
    var startTable = "table1"; 
    var $tabs = $("#" + startTable); 
    $("tbody.connectedSortable") 
      .sortable({ 
       connectWith: ".connectedSortable", 
       items: "> tr:not(:first)", 
       appendTo: $tabs, 
       helper: "clone", 
       cursor: "move", 
       zIndex: 999990, 
       start: function (event, ui) { 
        //alert("start1"); 
        var start_pos = ui.item.index(); 
        ui.item.data('start_pos', start_pos); 
       } 

      }); 

    var startTable2 = "table2"; 
    var $tabs2 = $("#" + startTable2); 

$("tbody.connectedSortable") 
     .sortable({ 
      connectWith: ".connectedSortable", 
      items: "> tr:not(:first)", 
      appendTo: $tabs, 
      helper: "clone", 
      cursor: "move", 
      zIndex: 999990, 
      start: function (event, ui) { 
       //alert("start2"); 
       var start_pos = ui.item.index(); 
       ui.item.data('start_pos', start_pos); 
       //alert(start_pos); 
      }, 
      update: function (event, ui) { 
       if (this.id == 'table2' && this === ui.item.parent()[0]) 
        alert("update2"); 
       else if (this.id == 'table1' && this === ui.item.parent()[0]) 
        alert("update1"); 
      } 
     }); 
    }); 

На самом деле, объяснение списка обновляется дважды приводится здесь: jquery Sortable connectWith calls the update method twice

Обратите внимание, что вы имели table1 и table2 IdS repeated.I удалили дубликаты и перенесли один из них на <tbody>.

Следует также отметить, что `Обновление ручки D & D оба пути

+0

Спасибо! У меня есть один вопрос, а как насчет того, хотите ли вы исключить два первых элемента из выделения? Я вижу "items:"> tr: not (: first) "" исключает первую строку, но я не могу исключить две первые строки. –

Смежные вопросы