Kendo Sortable интегрируется с сгруппированной сеткой
Вот мой вид, в котором у меня есть Sortable, который интегрирован с сеткой. Это работает нормально, но проблема в том, что Сетка сгруппирована. И я хочу, чтобы каждая группа имела свою собственную сортируемую функциональность, а это означает, что пользователь не должен иметь возможность перетаскивать строки из одной группы в другую. Как я могу это сделать? Должен ли я иметь отдельные Sortables для каждой группы?
@(Html.Kendo().Grid<QRMT.ViewModels.SubsystemViewModel>()
.Name("subsystems")
.ToolBar(toolbar => toolbar.Create().Text("Add new Subsystem"))
.Columns(columns =>
{
columns.ForeignKey(c => c.SystemId, new SelectList(ViewBag.Systems, "Value", "Text")).Hidden();
columns.Bound(c => c.SubsystemCode);
columns.Bound(c => c.SubsystemDesc);
columns.Command(c => { c.Edit(); c.Destroy(); }).Width(200);
})
.Editable(e => e.Mode(GridEditMode.PopUp).Window(window => window.Width(500)))
.DataSource(dataSource => dataSource
.Ajax()
.Events(events => events.Sync("onSync").Error("onError"))
.Model(model =>
{
model.Id(m => m.SubsystemId);
})
.Group(group => group.Add(m => m.SystemId))
.Create(create => create.Action("Add", "Subsystems"))
.Read(read => read.Action("Read", "Subsystems"))
.Update(update => update.Action("Update", "Subsystems"))
.Destroy(destroy => destroy.Action("Delete", "Subsystems"))
)
.Events(events => events.Edit("onEdit"))
)
@(Html.Kendo().Sortable()
.For("#subsystems")
.Filter("table > tbody > tr:not(.k-grouping-row)")
.Cursor("move")
.HintHandler("noHint")
.PlaceholderHandler("placeholder")
.ContainerSelector("#subsystems tbody")
.Events(events => events.Change("onChange"))
)
<script type="text/javascript">
var noHint = $.noop;
function placeholder(element) {
return element.clone().addClass("k-state-hover").css("opacity", 0.65);
}
function onEdit(e) {
if (e.model.isNew()) {
$('.k-window-title').text("Add");
}
}
function onSync(e) {
this.read();
}
function onError(e) {
alert(e.errors);
}
function onChange(e) {
var grid = $("#subsystems").data("kendoGrid"),
skip = grid.dataSource.skip(),
oldIndex = e.oldIndex + skip,
newIndex = e.newIndex + skip,
data = grid.dataSource.data(),
dataItem = grid.dataSource.getByUid(e.item.data("uid"));
grid.dataSource.remove(dataItem);
grid.dataSource.insert(newIndex, dataItem);
}
</script>
<style>
.k-grid tbody tr:not(.k-grouping-row) {
cursor: move;
}
</style>
2 ответа
Kendo Sortable виджет не работает с сгруппированной сеткой. Это написано в разделе известных ограничений раздела справки по интеграции Sortable-Grid.
Кендо говорит, что использование KendoSortable невозможно на сгруппированных сетках, однако я нашел возможное решение! в своем вопросе вы ограничиваете себя только возможностью перетаскивать внутри одной группы. Если у вас есть поле для хранения заказа и сортировки, это не имеет значения.
Мое решение, опубликованное ниже, было сделано для угловой реализации, но событие onchange является javascript, поэтому я думаю, что это можно переделать. (tr filter [data-uid] будет гарантировать, что ни одна строка группировки не выбрана)
- сначала правильно перечислите все строки, возможно, потребуется для инициализации значения SortOrder
- затем установите новый индекс в перемещенной строке
- затем измените, где это необходимо
- тогда прибегай к помощи сетки. Возможно, здесь необходимо указать жестко заданное имя поля вместо "primarySortField".
$scope.initMySortOrderGrouped = function(grid, myDatasource, primarySortField) {
grid.table.kendoSortable({
filter: ">tbody>tr[data-uid]",
hint: $.noop,
cursor: "move",
placeholder: function(element) {
return element.clone().addClass("k-state-hover").css("opacity", 0.65);
},
container: "#" + grid.element[0].id + " tbody",
change: function(e) {
/*Needed on grid for sorting to work conditionally*/
if (grid.canWrite) {
var skip = 0,
oldIndex = e.oldIndex + skip,
newIndex = e.newIndex + skip,
view = myDatasource.view(),
dataItem = myDatasource.getByUid(e.item.data("uid"));
/*retrieve the moved dataItem*/
/*set initial values where needed*/
var countRows = 0;
for (var i = 0; i < view.length; i++) {
for (var j = 0; j < view[i].items.length; j++) {
if (view[i].items[j].SortOrder != countRows + j) {
view[i].items[j].SortOrder = countRows + j;
view[i].items[j].dirty = true;
}
}
countRows += view[i].items.length
}
dataItem.SortOrder = newIndex; /*update the order*/
dataItem.dirty = true;
countRows = 0;
/*shift the order of the records*/
for (var i = 0; i < view.length; i++) {
for (var j = 0; j < view[i].items.length; j++) {
if (oldIndex < newIndex) {
if (countRows + j > oldIndex && countRows + j <= newIndex) {
view[i].items[j].SortOrder--;
view[i].items[j].dirty = true;
}
} else {
if (countRows + j >= newIndex && countRows + j < oldIndex) {
view[i].items[j].SortOrder++;
view[i].items[j].dirty = true;
}
}
}
countRows += view[i].items.length
}
myDatasource.sync();
/*submit the changes through the update transport and refresh the Grid*/
}
myDatasource.sort([{
field: primarySortField,
dir: "asc"
}, {
field: "SortOrder",
dir: "asc"
}]);
}
});
};
Это позволит вам перетаскивать элементы над его группой, число будет намного выше или ниже, чем в группе, но итоговая сортировка будет отображаться правильно!
Я ненавижу, когда программисты говорят что-то невозможное...