Skip to content

Commit ddea0e5

Browse files
committed
update
1 parent 6df0848 commit ddea0e5

File tree

9 files changed

+912
-123
lines changed

9 files changed

+912
-123
lines changed

.github/workflows/publish-to-gh-pages.yml

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,17 +24,15 @@ jobs:
2424
cd ${{ env.WEBAPP_PATH }}
2525
tailwindcss --input ./wwwroot/app.css --output ./wwwroot/app.min.css --minify
2626
27-
- name: Change <base href="" /> in App.razor to match gh repo name
27+
- name: Change <base href="" /> in index.html to match gh repo name
2828
run: |
2929
REPO_NAME=$(echo "${{ github.repository }}" | awk -F '/' '{print $NF}')
3030
sed -i 's/<base href="\/" \/>/<base href="\/'$REPO_NAME'\/" \/>/g' ${{ env.WEBAPP_PATH }}wwwroot/index.html
3131
3232
- name: Publish .NET app
3333
run: dotnet publish ${{ env.WEBAPP_PATH }}${{env.WEBAPP_CSPROJ}} --configuration Release -o ${{ env.WEBAPP_PATH }}${{env.PUBLISH_DIR}}
3434

35-
#- name: Add .nojekyll file
36-
# run:
37-
- name: copy index.html to 404.html AND add .nojekyll file
35+
- name: copy index.html to 404.html AND add .nojekyll file (https://github.blog/2009-12-29-bypassing-jekyll-on-github-pages/)
3836
run: |
3937
cp ${{ env.WEBAPP_PATH }}${{env.PUBLISH_DIR}}/wwwroot/index.html ${{ env.WEBAPP_PATH }}${{env.PUBLISH_DIR}}/wwwroot/404.html
4038
touch ${{ env.WEBAPP_PATH }}${{env.PUBLISH_DIR}}/wwwroot/.nojekyll

src/Layout/NavMenu.razor

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,10 @@
5656

5757
List<(string name, string link)> menuItems =new()
5858
{
59-
("Example 1", ""),
60-
("Example 2", "Example2"),
59+
("Ex 1", ""),
60+
("Ex 2", "Example2"),
61+
("Ex 3", "Example3"),
62+
("Ex 4", "Example4"),
6163
("Github \u2b67",WebsiteKeys.GitHubRepo ),
6264
};
6365
}

src/Pages/Example2.razor

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
@page "/Example2"
22
@inject ILogger<Example2> Logger
3-
<article>
4-
<p>
5-
This is more advanced solution that allows multiple child elements to be part of a draggable element.
6-
</p>
3+
<article class="prose prose-invert mb-5">
4+
<p>
5+
This advanced solution enables multiple child elements to be incorporated into a draggable element.
6+
</p>
7+
<p>
8+
A notable challenge here is the inability to move an item to the end of the list. This requires specialized handling, which is addressed in
9+
<a href="Example3">Example 3</a>.
10+
</p>
711
</article>
812
<div>
913
</div>
@@ -21,22 +25,22 @@
2125
@ondragend="()=> draggingModel = null" draggable="true"
2226

2327
>
24-
<div class=" bg-emerald-500 py-3">
25-
<div @ondragenter="@(() => { Logger.LogInformation("Drag Enter on Name element {elemName}", item.Name);})" class="bg-amber-600 py-10 mx-2 px-2 rounded-xl">@item.Name</div>
28+
<div class=" bg-emerald-700 py-3">
29+
<div @ondragenter="@(() => { Logger.LogInformation("Drag Enter on Name element {elemName}", item.Name);})" class="bg-amber-800 py-5 mx-2 px-2 rounded-xl">@item.Name</div>
2630
<div>Child elem. to demonstrate the issue</div>
2731
</div>
2832

2933
@if (draggingModel is not null)
3034
{ //this is overlay for dropping. Otherwise it flickers between dragenter and leave, bsc of child element
3135
//this overlays the child elements of <li>
32-
<div class="bg-rose-100/20 absolute inset-0 w-full h-full @(item.IsDragOver ?"border-t-4 border-red-500":"")"
36+
<div class="bg-neutral-500/20 absolute inset-0 w-full h-full @(item.IsDragOver ?"border-t-4 border-red-500":"")"
3337
@ondrop="()=>HandleDrop(item)"
3438
@ondragenter="@(()=>{item.IsDragOver = true; Console.WriteLine($"Drag Enter {item.Name}"); })"
3539
@ondragleave="@(()=> {item.IsDragOver = false; Console.WriteLine($"Drag Leave {item.Name}"); })"
3640
>
3741
</div>
3842
}
39-
</li>
43+
</li>
4044
}
4145
</ul>
4246
</div>

src/Pages/Example3.razor

Lines changed: 88 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -1,91 +1,98 @@
11
@page "/Example3"
2-
<article>
3-
<p>
4-
This is more advanced solution that allows multiple child elements to be part of a draggable element.
5-
</p>
2+
<article class="prose prose-invert">
3+
<p>
4+
Example 3 addresses the challenge of moving an item to the end of the list. This is achieved by use of a variable named `lastModel`,
5+
And placing an element at the end of the list that is not draggable. This element is then used as the drop target for the last item in the list.
6+
</p>
67
</article>
8+
9+
710
<div>
811
</div>
912
<div class="flex justify-center bg-gray-800">
10-
11-
<ul class="mx-auto my-5 "
12-
ondragover="event.preventDefault();"
13-
>
14-
@foreach (var item in Models.OrderBy(x => x.Order))
15-
{
16-
if (item.Order == int.MaxValue)
17-
{
18-
<li @ondrop="()=>HandleDrop(item)" @key="item" class="h-5 bg-green-200 w-full
19-
@(item.IsDragOver ?"border-t-4 border-red-500":"")" >
20-
</li>
21-
continue;
22-
}
23-
<li @key="item" class="pb-2 relative"
24-
@ondragstart="() => draggingModel = item"
25-
@ondragend="()=> draggingModel = null" draggable="true"
26-
@ondrop="()=>HandleDrop(item)"
27-
>
28-
<div class=" bg-emerald-500 py-3">
29-
<div class="bg-amber-600 py-10 mx-2 px-2 rounded-xl">@item.Name</div>
30-
<div>Child elem. to demonstrate the issue</div>
31-
</div>
32-
33-
@if (draggingModel is not null)
34-
{ //this is overlay for dropping. Otherwise it flickers between dragenter and leave, bsc of child element
35-
//this overlays the child elements of <li>
36-
<div class="bg-rose-100/20 absolute inset-0 w-full h-full @(item.IsDragOver ?"border-t-4 border-red-500":"")"
37-
@ondrop="()=>HandleDrop(item)"
38-
@ondragenter="@(()=>{item.IsDragOver = true; Console.WriteLine($"Drag Enter {item.Name}"); })"
39-
@ondragleave="@(()=> {item.IsDragOver = false; Console.WriteLine($"Drag Leave {item.Name}"); })"
40-
>
41-
</div>
42-
}
43-
44-
</li>
45-
}
46-
</ul>
13+
14+
<ul class="mx-auto my-5 "
15+
ondragover="event.preventDefault();">
16+
@foreach (var item in Models.OrderBy(x => x.Order))
17+
{
18+
19+
<li @key="item" class="pb-2 relative w-64"
20+
@ondragstart="() => draggingModel = item"
21+
@ondragend="() => draggingModel = null" draggable="@(item == lastModel ? "false" : "true")"
22+
>
23+
24+
25+
@if (item == lastModel)
26+
{
27+
if (draggingModel is not null)
28+
{
29+
<div @ondrop="() => HandleDrop(item)" @key="item" class="h-10 bg-transparent w-full
30+
@(item.IsDragOver ? "border-t-4 border-red-500" : "")">
31+
</div>
32+
}
33+
}
34+
else
35+
{
36+
<div class=" bg-sky-800 py-3 rounded-xl px-2">
37+
<div class="bg-indigo-800 py-5 mx-2 px-2 rounded-xl">@item.Name</div>
38+
<div>Part of content...</div>
39+
</div>
40+
}
41+
42+
@if (draggingModel is not null)
43+
{//for explanation why we need this overlay, see Example2
44+
<div class="bg-neutral-500/20 absolute inset-0 w-full h-full @(item.IsDragOver ? "border-t-4 border-red-500" : "")"
45+
@ondrop="() => HandleDrop(item)"
46+
@ondragenter="@(() => { item.IsDragOver = true; Console.WriteLine($"Drag Enter {item.Name}"); })"
47+
@ondragleave="@(() => { item.IsDragOver = false; Console.WriteLine($"Drag Leave {item.Name}"); })">
48+
</div>
49+
}
50+
51+
</li>
52+
}
53+
</ul>
4754
</div>
4855

4956
@code
5057
{
51-
private List<Model> Models { get; } = [];
52-
53-
private class Model
54-
{
55-
public int Order { get; set; }
56-
public string Name { get; set; } = "";
57-
public bool IsDragOver { get; set; }
58-
}
59-
60-
protected override void OnInitialized()
61-
{//fill names wit "random" string
62-
for (var i = 0; i < 10; i++)
63-
{
64-
Model m = new() { Order = i, Name = $"Item {i}" };
65-
Models.Add(m);
66-
}
67-
Models.Add(new(){Order=int.MaxValue});
68-
base.OnInitialized();
69-
}
70-
71-
private void HandleDrop(Model landingModel)
72-
{//landing model -> where the drag happened
73-
if (draggingModel is null) return;
74-
if (landingModel.Order == int.MaxValue)
75-
{
76-
77-
}
78-
int originalOrderLanding = landingModel.Order;//keep the original order for later
79-
//increase model uned by 1
80-
Models.Where(x => x.Order >= landingModel.Order).ToList().ForEach(x => x.Order++);
81-
draggingModel.Order = originalOrderLanding;//replace landing model
82-
int ii = 0;
83-
foreach (var model in Models.OrderBy(x => x.Order).ToList())
84-
{
85-
model.Order = ii++;//keep the numbers from 0 to size-1
86-
model.IsDragOver = false;//remove drag over.
87-
}
88-
}
89-
90-
private Model? draggingModel;//the model that is being dragged
58+
private List<Model> Models { get; } = [];
59+
60+
private class Model
61+
{
62+
public int Order { get; set; }
63+
public string Name { get; set; } = "";
64+
public bool IsDragOver { get; set; }
65+
}
66+
67+
protected override void OnInitialized()
68+
{//fill names wit "random" string
69+
for (var i = 0; i < 10; i++)
70+
{
71+
Model m = new() { Order = i, Name = $"Item {i}" };
72+
Models.Add(m);
73+
}
74+
Models.Add(lastModel);
75+
base.OnInitialized();
76+
}
77+
78+
private void HandleDrop(Model landingModel)
79+
{//landing model -> where the drag happened
80+
if (draggingModel is null) return;
81+
82+
int originalOrderLanding = landingModel.Order;//keep the original order for later
83+
84+
Models.Where(x => x.Order >= landingModel.Order).ToList().ForEach(x => x.Order++);
85+
draggingModel.Order = originalOrderLanding;//replace landing model
86+
int ii = 0;
87+
foreach (var model in Models.OrderBy(x => x.Order).ToList())
88+
{
89+
model.Order = ii++;//keep the numbers from 0 to size-1
90+
model.IsDragOver = false;//remove drag over.
91+
}
92+
lastModel.Order = int.MaxValue - 1;//keep it on the end, but with option to +1
93+
}
94+
95+
private Model? draggingModel;//the model that is being dragged
96+
97+
readonly Model lastModel = new() { Order = int.MaxValue - 1 };//minus 1, because HandeDrop increases the order by 1.
9198
}

src/Pages/Example4.razor

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
@page "/Example4"
2+
<article class="prose prose-invert">
3+
<p>
4+
TODO: Attempt to implement drag and drop with touch events.
5+
</p>
6+
<p>
7+
Currently it just logs the touch events.
8+
</p>
9+
</article>
10+
11+
12+
<div>
13+
</div>
14+
<div class="flex justify-center bg-gray-800">
15+
16+
<ul class="mx-auto my-5 touch-none"
17+
ondragover="event.preventDefault();">
18+
@foreach (var item in Models.OrderBy(x => x.Order))
19+
{
20+
21+
@* @onpointerdown="@(() => Console.WriteLine($"OnPDown {item.Name}"))" *@
22+
@* @onpointerlockchange="@(() => Console.WriteLine($"OnPLockChange"))" *@
23+
@* @onpointermove="@(() => Console.WriteLine($"OnPMove {item.Name}"))" *@
24+
@* @onpointerup="@(() => Console.WriteLine($"OnPUp {item.Name}"))" *@
25+
@* *@
26+
<li @key="item" class="pb-2 relative w-64 "
27+
28+
@ontouchstart="@(() => Console.WriteLine($"OnPTouchStart {item.Name}"))"
29+
@ontouchmove="@(() => Console.WriteLine($"OnPTouchMove {item.Name}"))"
30+
@ontouchend="@(() => Console.WriteLine($"OnPTouchEnd {item.Name}"))"
31+
@ontouchenter="@(() => Console.WriteLine($"OnPTouchEnter {item.Name}"))"
32+
@ontouchcancel="@(() => Console.WriteLine($"OnPTouchCancel {item.Name}"))"
33+
@ontouchleave="@(() => Console.WriteLine($"OnPTouchLeave {item.Name}"))"
34+
>
35+
36+
37+
@if (item == lastModel)
38+
{
39+
if (draggingModel is not null)
40+
{
41+
<div @ondrop="() => HandleDrop(item)" @key="item" class="h-10 bg-transparent w-full
42+
@(item.IsDragOver ? "border-t-4 border-red-500" : "")">
43+
</div>
44+
}
45+
}
46+
else
47+
{
48+
<div class=" bg-sky-800 py-3 rounded-xl px-2">
49+
<div class="bg-indigo-800 py-5 mx-2 px-2 rounded-xl">@item.Name</div>
50+
<div>Part of content...</div>
51+
</div>
52+
}
53+
54+
@if (draggingModel is not null)
55+
{//for explanation why we need this overlay, see Example2
56+
<div class="bg-neutral-500/20 absolute inset-0 w-full h-full @(item.IsDragOver ? "border-t-4 border-red-500" : "")"
57+
58+
59+
60+
@ondrop="() => HandleDrop(item)"
61+
@ondragenter="@(() => { item.IsDragOver = true; Console.WriteLine($"Drag Enter {item.Name}"); })"
62+
@ondragleave="@(() => { item.IsDragOver = false; Console.WriteLine($"Drag Leave {item.Name}"); })">
63+
</div>
64+
}
65+
66+
</li>
67+
}
68+
</ul>
69+
</div>
70+
71+
@code
72+
{
73+
private List<Model> Models { get; } = [];
74+
75+
private class Model
76+
{
77+
public int Order { get; set; }
78+
public string Name { get; set; } = "";
79+
public bool IsDragOver { get; set; }
80+
}
81+
82+
protected override void OnInitialized()
83+
{//fill names wit "random" string
84+
for (var i = 0; i < 10; i++)
85+
{
86+
Model m = new() { Order = i, Name = $"Item {i}" };
87+
Models.Add(m);
88+
}
89+
Models.Add(lastModel);
90+
base.OnInitialized();
91+
}
92+
93+
private void HandleDrop(Model landingModel)
94+
{//landing model -> where the drag happened
95+
if (draggingModel is null) return;
96+
97+
int originalOrderLanding = landingModel.Order;//keep the original order for later
98+
99+
Models.Where(x => x.Order >= landingModel.Order).ToList().ForEach(x => x.Order++);
100+
draggingModel.Order = originalOrderLanding;//replace landing model
101+
int ii = 0;
102+
foreach (var model in Models.OrderBy(x => x.Order).ToList())
103+
{
104+
model.Order = ii++;//keep the numbers from 0 to size-1
105+
model.IsDragOver = false;//remove drag over.
106+
}
107+
lastModel.Order = int.MaxValue - 1;//keep it on the end, but with option to +1
108+
}
109+
110+
private Model? draggingModel;//the model that is being dragged
111+
112+
readonly Model lastModel = new() { Order = int.MaxValue - 1 };//minus 1, because HandeDrop increases the order by 1.
113+
}

src/Pages/Home.razor

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
@page "/"
2-
<article class="my-5">
2+
<article class="prose prose-invert mb-5 ">
33
<p>
44
This example showcases the use of drag and drop functionality for list ordering in Blazor.
55
</p>

src/Program.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
public static class WebsiteKeys
1414
{
1515
public const string GitHubRepo = "https://github.com/tesar-tech/DragAndDropList";
16-
public const string Twitter = "https://twitter.com/";
17-
public const string Title = "Blazor Drag and Drop List";
16+
public const string Twitter = "https://twitter.com/tesar_tech";
17+
public const string Title = "Blazor Drag&Drop List";
1818

1919
}

0 commit comments

Comments
 (0)