Skip to content

Commit a64d468

Browse files
Update to 25.1.3+
1 parent ceeac84 commit a64d468

36 files changed

+2418
-23
lines changed
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Threading.Tasks;
5+
using Microsoft.AspNetCore.Mvc;
6+
7+
namespace ASP_NET_Core.Controllers
8+
{
9+
public class HomeController : Controller
10+
{
11+
public IActionResult Index()
12+
{
13+
return View();
14+
}
15+
16+
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
17+
public IActionResult Error() {
18+
return View();
19+
}
20+
}
21+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<div class="demo-header">
2+
<h3>TreeView - Select multiple items and drag'n'drop</h3>
3+
<div id="toggle-container">
4+
<span>Clear selection after drop</span>
5+
@(Html.DevExtreme().Switch().ID("clearAfterDropSwitch"))
6+
</div>
7+
</div>
8+
@(Html.DevExtreme().TabPanel()
9+
.Items(tabs => {
10+
tabs.Add().Title("Plain Data")
11+
.Template(@<text><div>
12+
@(await Html.PartialAsync("../PartialViews/TreeViewPlain"))
13+
</div></text>);
14+
tabs.Add().Title("Hierarchical Data")
15+
.Template(@<text><div>
16+
@(await Html.PartialAsync("../PartialViews/TreeViewHierarchy"))
17+
</div></text>);
18+
})
19+
)
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
@(Html.DevExtreme().Sortable()
2+
.Filter(".dx-treeview-item")
3+
.AllowDropInsideItem(true)
4+
.AllowReordering(true)
5+
.OnDragStart("dragStartH")
6+
.OnDragChange("dragChangeH")
7+
.OnDragEnd("dragEndH")
8+
.DragTemplate(new JS("dragTemplateH"))
9+
.Content(
10+
Html.DevExtreme().TreeView()
11+
.ID("tree-view-hierarchy")
12+
.ElementAttr("class", "tab-item-content")
13+
.DataSource(new JS("itemsDriveHierarchy"))
14+
.ExpandNodesRecursive(false)
15+
.SelectNodesRecursive(false)
16+
.ShowCheckBoxesMode(TreeViewCheckBoxMode.Normal)
17+
.DataStructure(TreeViewDataStructure.Tree)
18+
.DisplayExpr("name")
19+
.Width(300).ToString()
20+
)
21+
)
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
@(Html.DevExtreme().Sortable()
2+
.Filter(".dx-treeview-item")
3+
.AllowDropInsideItem(true)
4+
.AllowReordering(true)
5+
.OnDragStart("dragStartP")
6+
.OnDragChange("dragChangeP")
7+
.OnDragEnd("dragEndP")
8+
.DragTemplate(new JS("dragTemplateP"))
9+
.Content(
10+
Html.DevExtreme().TreeView()
11+
.ID("tree-view-plain")
12+
.ElementAttr("class", "tab-item-content")
13+
.DataSource(new JS("itemsDrivePlain"))
14+
.ExpandNodesRecursive(false)
15+
.SelectNodesRecursive(false)
16+
.ShowCheckBoxesMode(TreeViewCheckBoxMode.Normal)
17+
.DataStructure(TreeViewDataStructure.Plain)
18+
.DisplayExpr("name")
19+
.Width(300).ToString()
20+
)
21+
)
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<!DOCTYPE html>
2+
3+
<html>
4+
<head>
5+
<meta name="viewport" content="width=device-width, initial-scale=1">
6+
<meta charset="utf-8">
7+
<meta http-equiv="X-UA-Compatible" content="IE=edge">
8+
<meta name="description" content="">
9+
<meta name="author" content="">
10+
11+
<title>ASP_NET_Core</title>
12+
<link href="~/favicon.ico" rel="shortcut icon" type="image/x-icon" />
13+
14+
@* Uncomment to use the HtmlEditor control *@
15+
@* <script src="https://unpkg.com/devextreme-quill/dist/dx-quill.min.js"></script> *@
16+
17+
<link rel="stylesheet" href="~/css/vendor.css" asp-append-version="true" />
18+
<link rel="stylesheet" href="~/css/Site.css" />
19+
<script src="~/js/vendor.js" asp-append-version="true"></script>
20+
<script src="~/js/data-PlainTree.js"></script>
21+
<script src="~/js/data-HierarchyTree.js"></script>
22+
<script src="~/js/TreeView-plain.js"></script>
23+
<script src="~/js/TreeView-hierarchy.js"></script>
24+
</head>
25+
26+
<body class="dx-viewport">
27+
<div class="demo-container">
28+
@RenderBody()
29+
</div>
30+
</body>
31+
32+
</html>

ASP.NET Core/orig_Program.cs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Threading.Tasks;
5+
using Microsoft.AspNetCore.Hosting;
6+
using Microsoft.Extensions.Configuration;
7+
using Microsoft.Extensions.Hosting;
8+
using Microsoft.Extensions.Logging;
9+
10+
namespace ASP_NET_Core
11+
{
12+
public class Program
13+
{
14+
public static void Main(string[] args)
15+
{
16+
CreateHostBuilder(args).Build().Run();
17+
}
18+
19+
public static IHostBuilder CreateHostBuilder(string[] args) =>
20+
Host.CreateDefaultBuilder(args)
21+
.ConfigureWebHostDefaults(webBuilder => {
22+
webBuilder.UseStartup<Startup>();
23+
});
24+
}
25+
}

ASP.NET Core/orig_Startup.cs

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Threading.Tasks;
5+
using Microsoft.AspNetCore.Builder;
6+
using Microsoft.AspNetCore.Hosting;
7+
using Microsoft.Extensions.Configuration;
8+
using Microsoft.Extensions.DependencyInjection;
9+
using Microsoft.Extensions.Hosting;
10+
11+
namespace ASP_NET_Core
12+
{
13+
public class Startup
14+
{
15+
public Startup(IConfiguration configuration)
16+
{
17+
Configuration = configuration;
18+
}
19+
20+
public IConfiguration Configuration { get; }
21+
22+
// This method gets called by the runtime. Use this method to add services to the container.
23+
public void ConfigureServices(IServiceCollection services)
24+
{
25+
// Add framework services.
26+
services
27+
.AddControllersWithViews()
28+
.AddJsonOptions(options => options.JsonSerializerOptions.PropertyNamingPolicy = null);
29+
}
30+
31+
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
32+
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
33+
{
34+
if (env.IsDevelopment())
35+
{
36+
app.UseDeveloperExceptionPage();
37+
}
38+
else
39+
{
40+
app.UseExceptionHandler("/Home/Error");
41+
}
42+
app.UseStaticFiles();
43+
44+
app.UseRouting();
45+
46+
app.UseAuthorization();
47+
48+
app.UseEndpoints(endpoints => {
49+
endpoints.MapControllerRoute(
50+
name: "default",
51+
pattern: "{controller=Home}/{action=Index}/{id?}");
52+
});
53+
}
54+
}
55+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<dx-sortable filter=".dx-treeview-item"
2+
[allowDropInsideItem]="true"
3+
[allowReordering]="true"
4+
(onDragStart)="dragStart($event)"
5+
(onDragChange)="dragChange($event)"
6+
(onDragEnd)="dragEnd($event)"
7+
dragTemplate="draggedItemsTemplate"
8+
>
9+
<div *dxTemplate="let dragData of 'draggedItemsTemplate'">
10+
<div *ngFor="let node of dragData.itemData">
11+
<div class="dragged-item">{{node.text}}</div>
12+
</div>
13+
</div>
14+
<dx-tree-view #treeView
15+
class="tab-item-content"
16+
[items]="treeItems"
17+
[expandNodesRecursive]="false"
18+
[selectNodesRecursive]="false"
19+
showCheckBoxesMode="normal"
20+
dataStructure="tree"
21+
displayExpr="name"
22+
[width]="300"
23+
></dx-tree-view>
24+
</dx-sortable>
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
import { Component, ViewChild, Input } from '@angular/core';
2+
import { DataService } from 'src/app/services/data.service';
3+
import { DxTreeViewComponent } from 'devextreme-angular';
4+
5+
@Component({
6+
selector: 'tree-view-hierarchy',
7+
templateUrl: './tree-view-hierarchy.component.html'
8+
})
9+
export class TreeViewHierarchyComponent {
10+
@ViewChild("treeView") treeView: DxTreeViewComponent;
11+
@Input() shouldClearSelection: boolean;
12+
treeItems: any[];
13+
constructor(dataService: DataService) {
14+
this.treeItems = dataService.getHierarchicalData();
15+
}
16+
dragStart(e) {
17+
const treeView = this.treeView.instance;
18+
e.itemData = treeView.getSelectedNodes();
19+
e.cancel = !this.canDrag(treeView, e);
20+
}
21+
dragChange(e) {
22+
const treeView = this.treeView.instance;
23+
e.cancel = !this.canDrop(treeView, e);
24+
}
25+
dragEnd(e) {
26+
const treeView = this.treeView.instance;
27+
const allItems = treeView.option("items");
28+
if (this.canDrop(treeView, e)) {
29+
const toNode = this.getNodeByVisualIndex(treeView, this.calculateToIndex(e));
30+
const treeViewExpr = {
31+
items: treeView.option("itemsExpr"),
32+
key: treeView.option("keyExpr")
33+
}
34+
this.moveNodes(allItems, e, toNode, treeViewExpr);
35+
}
36+
treeView.option("items", allItems);
37+
if (this.shouldClearSelection)
38+
treeView.unselectAll();
39+
}
40+
canDrag(treeView, e) {
41+
const fromNode = this.getNodeByVisualIndex(treeView, e.fromIndex);
42+
return fromNode.selected && e.itemData && e.itemData.length;
43+
}
44+
canDrop(treeView, e) {
45+
const toNode = this.getNodeByVisualIndex(treeView, e.toIndex);
46+
const canAcceptChildren = (e.dropInsideItem && toNode.itemData.isDirectory) || !e.dropInsideItem;
47+
const toNodeIsChild = toNode && e.itemData.some(i => this.isParent(toNode, i));
48+
const fromIndices = e.itemData.map(node => this.getVisualIndexByNode(treeView, node));
49+
const targetThemselves = toNode && (e.itemData.some(i => i.key === toNode.key) || fromIndices.includes(e.toIndex));
50+
return canAcceptChildren && !toNodeIsChild && !targetThemselves;
51+
}
52+
moveNodes(items, e, toNode, treeFieldExpr) {
53+
const nodesToMove = this.getTopNodes(e.itemData);
54+
nodesToMove.forEach(nodeToMove => {
55+
const fromNodeContainingArray = this.getNodeContainingArray(nodeToMove, items, treeFieldExpr.items);
56+
const fromIndex = this.getLocalIndex(fromNodeContainingArray, nodeToMove.key, treeFieldExpr.key);
57+
fromNodeContainingArray.splice(fromIndex, 1);
58+
});
59+
if (e.dropInsideItem) {
60+
const toIndex = toNode.itemData[treeFieldExpr.items].length;
61+
toNode.itemData[treeFieldExpr.items].splice(toIndex, 0, ...nodesToMove.map(i => i.itemData));
62+
} else {
63+
const toNodeContainingArray = this.getNodeContainingArray(toNode, items, treeFieldExpr.items);
64+
const toIndex = toNode === null
65+
? items.length
66+
: this.getLocalIndex(toNodeContainingArray, toNode.key, treeFieldExpr.key);
67+
toNodeContainingArray.splice(toIndex, 0, ...nodesToMove.map(i => i.itemData));
68+
}
69+
}
70+
isParent(node, possibleParentNode) {
71+
if (!node.parent) return false;
72+
return node.parent.key !== possibleParentNode.key ? this.isParent(node.parent, possibleParentNode) : true;
73+
}
74+
getTopNodes(nodes) {
75+
return nodes.filter(nodeToCheck => {
76+
return !nodes.some(n => this.isParent(nodeToCheck, n));
77+
});
78+
}
79+
getNodeContainingArray(node, rootArray, itemsExpr) {
80+
return node === null || node.parent === null
81+
? rootArray
82+
: node.parent.itemData[itemsExpr];
83+
}
84+
getVisualIndexByNode(treeView, node) {
85+
const nodeElements = Array.from(treeView.element().querySelectorAll('.dx-treeview-node'));
86+
const nodeElement = nodeElements.find(n => (<Element>n).getAttribute('data-item-id') === node.key);
87+
return nodeElements.indexOf(nodeElement);
88+
}
89+
getNodeByVisualIndex(treeView, index) {
90+
const nodeElement = treeView.element().querySelectorAll('.dx-treeview-node')[index];
91+
if (nodeElement) {
92+
return this.getNodeByKey(treeView.getNodes(), nodeElement.getAttribute('data-item-id'));
93+
}
94+
return null;
95+
}
96+
getNodeByKey(nodes, key) {
97+
for (let i = 0; i < nodes.length; i++) {
98+
if (nodes[i].key == key) {
99+
return nodes[i];
100+
}
101+
if (nodes[i].children) {
102+
const node = this.getNodeByKey(nodes[i].children, key);
103+
if (node != null) {
104+
return node;
105+
}
106+
}
107+
}
108+
return null;
109+
}
110+
calculateToIndex(e) {
111+
if (e.dropInsideItem) return e.toIndex;
112+
return e.fromIndex >= e.toIndex ? e.toIndex : e.toIndex + 1;
113+
}
114+
getLocalIndex(array, key, keyExpr) {
115+
const idsArray = array.map((elem) => elem[keyExpr]);
116+
return idsArray.indexOf(key);
117+
}
118+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<dx-sortable filter=".dx-treeview-item"
2+
[allowDropInsideItem]="true"
3+
[allowReordering]="true"
4+
(onDragStart)="dragStart($event)"
5+
(onDragChange)="dragChange($event)"
6+
(onDragEnd)="dragEnd($event)"
7+
dragTemplate="draggedItemsTemplate"
8+
>
9+
<div *dxTemplate="let dragData of 'draggedItemsTemplate'">
10+
<div *ngFor="let node of dragData.itemData">
11+
<div class="dragged-item">{{node.text}}</div>
12+
</div>
13+
</div>
14+
<dx-tree-view #treeView
15+
class="tab-item-content"
16+
[items]="treeItems"
17+
[expandNodesRecursive]="false"
18+
[selectNodesRecursive]="false"
19+
showCheckBoxesMode="normal"
20+
dataStructure="plain"
21+
displayExpr="name"
22+
[width]="300"
23+
></dx-tree-view>
24+
</dx-sortable>

0 commit comments

Comments
 (0)