0

これが私のビューです。ここには、グリッドと統合されたソータブルがあります。これは正常に機能しますが、問題はグリッドがグループ化されていることです。また、各グループに独自の並べ替え機能を持たせたいと考えています。つまり、ユーザーがあるグループから別のグループに行をドラッグ アンド ドロップできないようにする必要があります。それ、どうやったら出来るの?グループごとに個別の 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>
4

2 に答える 2

1

剣道は、グループ化されたグリッドで 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"
      }]);
    }
  });
};

これにより、アイテムをそのグループにドラッグできます。数はグループ内よりもはるかに大きくなったり小さくなったりしますが、結果の並べ替えは正しく表示されます!

プログラマーが何かが不可能だと言うのは嫌いです...

于 2016-05-11T13:16:38.157 に答える