From 032e365c74e0ac611c6fe94e7b12b6798cc41770 Mon Sep 17 00:00:00 2001 From: John J Bomhold Date: Sun, 7 Mar 2021 17:49:43 -0600 Subject: [PATCH] Adds SortGroup new prefered method. --- src/BlazorSortableJS.DemoCSB/DemoCSB.csproj | 13 +- src/BlazorSortableJS.DemoCore/DemoCore.csproj | 11 +- .../Pages/Index.razor | 172 ++++++++++------ src/BlazorSortableJS.DemoSSB/DemoSSB.csproj | 2 +- src/BlazorSortableJS/BlazorSortableJS.csproj | 13 +- .../Components/DynamicComponentBase.cs | 3 - .../Components/SortGroup.razor | 28 +++ .../Components/SortGroup.razor.cs | 192 ++++++++++++++++++ .../Components/SortableGroup.razor | 5 +- .../Components/SortableItem.razor | 31 +-- .../Components/SortableItem.razor.cs | 32 +++ src/BlazorSortableJS/SortableJS.cs | 4 +- 12 files changed, 396 insertions(+), 110 deletions(-) create mode 100644 src/BlazorSortableJS/Components/SortGroup.razor create mode 100644 src/BlazorSortableJS/Components/SortGroup.razor.cs create mode 100644 src/BlazorSortableJS/Components/SortableItem.razor.cs diff --git a/src/BlazorSortableJS.DemoCSB/DemoCSB.csproj b/src/BlazorSortableJS.DemoCSB/DemoCSB.csproj index 5db4ebb..2725772 100644 --- a/src/BlazorSortableJS.DemoCSB/DemoCSB.csproj +++ b/src/BlazorSortableJS.DemoCSB/DemoCSB.csproj @@ -1,21 +1,18 @@ - + - netstandard2.1 + net5.0 8.0 3.0 - - - - + + + - - diff --git a/src/BlazorSortableJS.DemoCore/DemoCore.csproj b/src/BlazorSortableJS.DemoCore/DemoCore.csproj index ef0697e..ef188be 100644 --- a/src/BlazorSortableJS.DemoCore/DemoCore.csproj +++ b/src/BlazorSortableJS.DemoCore/DemoCore.csproj @@ -1,13 +1,16 @@  - netstandard2.1 + netstandard2.1;net5.0 3.0 - - - + + + + + + diff --git a/src/BlazorSortableJS.DemoCore/Pages/Index.razor b/src/BlazorSortableJS.DemoCore/Pages/Index.razor index 59f3d56..ff3c2a4 100644 --- a/src/BlazorSortableJS.DemoCore/Pages/Index.razor +++ b/src/BlazorSortableJS.DemoCore/Pages/Index.razor @@ -1,81 +1,137 @@ @page "/" -Sortable List - - - @foreach (var item in @MyGroup.Sortable.GetRaw()) - { - @item.Data - } - -Same Group - - @foreach (var item in @My2Group.Sortable.GetRaw()) - { - @item.Data - } - -Resulting Data +@using System.Text.Json + + +
+
Sortable List + + + + Same Group + + + +
+
+ + List 1 Raw Contents +
    + @foreach (var item in items.OrderBy(q => q.Order)) + { +
  • @item.Order - @item.Text - @item.Id
  • + } +
+ List 2 Raw Contents +
    + @foreach (var item in items2.OrderBy(q => q.Order)) + { +
  • @item.Order -@item.Text - @item.Id
  • + } +
+
+
+Resulting For Gorup 2
    - @foreach (var item in resultsList) + @foreach (var item in ResultsList) { -
  • @item
  • +
  • @item.Text - @item.Order - @item.Id
  • }
@code { - SortableGroup MyGroup; - SortableGroup My2Group; - List items { get; set; } = new List { "T1", "T2", "T3" }; - List items2 { get; set; } = new List { "T4", "T5", "T6" }; - List resultsList { get; set; } = new List(); + string Id1 = Guid.NewGuid().ToString(); + string Id2 = Guid.NewGuid().ToString(); + int Order = 0; + SortGroup MyGroup; + SortGroup My2Group; + List items { get; set; } = new List +{ + new Items("T1"), + new Items("T2"), + new Items("T3"), + }; + List items2 { get; set; } = new List +{ + new Items("T4"), + new Items("T5"), + new Items("T6"), + }; + List ResultsList { get; set; } = new List(); - public async Task New() + public async Task Remove() { - var items = new List { "T1", "T2", "T3", "T4", "T5" }; - await MyGroup.Sortable.ClearAsync(); - await MyGroup.Sortable.CreateAsync(MyGroup.Id, new SortableJsOptions + // This is just a shortcut for the demo + try { - Group = "test", - Animation = 100, - // OnSort = async (e) => { resultsList = await MyGroup.Sortable.GetData(); StateHasChanged(); } - }); - - MyGroup.Sortable.SetData(items); - StateHasChanged(); + items.Remove(items.First()); + } + catch{} + // Inform Group of direct changes. + await MyGroup.UpdateAsync(); + ResultsList = await My2Group.GetOrderListAsync("Order"); } - protected override Task OnInitializedAsync() + + public async Task OnSort(SortableEvent e) { - resultsList = items; - return base.OnInitializedAsync(); + ResultsList = await My2Group.GetOrderListAsync("Order"); } - public void Test(SortableJSEvent e) + public async Task OnAdd(SortableEvent e) { - Console.WriteLine(e); + // Changes are already tracked do not use UpdateAsync() + if (e.Sender.Id == Id1) + { + items.Add(e.Data); + } + else + { + items2.Add(e.Data); + } + _= await MyGroup.GetOrderListAsync("Order"); + ResultsList = await My2Group.GetOrderListAsync("Order"); } - protected async override Task OnAfterRenderAsync(bool firstrun) + public async Task OnRemove(SortableEvent e) { - if (firstrun) + // Changes are already tracked do not use UpdateAsync() + if (e.Sender.Id == Id1) { - MyGroup.Sortable.SetData(items); - await MyGroup.Sortable.CreateAsync(MyGroup.Id, new SortableJsOptions - { - Group = "test", - Animation = 100, - OnClone = Test - // OnSort = async (e) => { resultsList = await MyGroup.Sortable.GetData(); StateHasChanged(); } - }); + var item = items.FirstOrDefault(q => q.Id == e.Data.Id); + if (item != null) + items.Remove(item); + } + else + { + var item = items2.FirstOrDefault(q => q.Id == e.Data.Id); + if (item != null) + items2.Remove(item); + } + _ = await MyGroup.GetOrderListAsync("Order"); + ResultsList = await My2Group.GetOrderListAsync("Order"); + } - My2Group.Sortable.SetData(items2); - await My2Group.Sortable.CreateAsync(My2Group.Id, new SortableJsOptions - { - Group = "test", - Animation = 100, - OnClone = Test, - OnSort = async (e) => { resultsList = await My2Group.Sortable.GetDataAsync(); StateHasChanged(); } - }); + protected override Task OnInitializedAsync() + { + return base.OnInitializedAsync(); + } + + + public class Items + { + public int Order { get; set; } = 0; + public string Text { get; set; } + public string Id { get; set; } = Guid.NewGuid().ToString(); - StateHasChanged(); + public Items() + { + + } + public Items(string text) + { + Text = text; } } } \ No newline at end of file diff --git a/src/BlazorSortableJS.DemoSSB/DemoSSB.csproj b/src/BlazorSortableJS.DemoSSB/DemoSSB.csproj index 36ad743..ea626d6 100644 --- a/src/BlazorSortableJS.DemoSSB/DemoSSB.csproj +++ b/src/BlazorSortableJS.DemoSSB/DemoSSB.csproj @@ -1,7 +1,7 @@  - netcoreapp3.0 + netcoreapp3.0;net5.0 8.0 diff --git a/src/BlazorSortableJS/BlazorSortableJS.csproj b/src/BlazorSortableJS/BlazorSortableJS.csproj index 1d50383..542155a 100644 --- a/src/BlazorSortableJS/BlazorSortableJS.csproj +++ b/src/BlazorSortableJS/BlazorSortableJS.csproj @@ -1,10 +1,10 @@  - netstandard2.1 + netstandard2.1;net5.0 3.0 BlazorSortableJs - 1.0.4 + 1.0.5 John J Bomhold Blazor SortableJs Wrapper @@ -18,9 +18,12 @@ John J Bomhold - - - + + + + + + diff --git a/src/BlazorSortableJS/Components/DynamicComponentBase.cs b/src/BlazorSortableJS/Components/DynamicComponentBase.cs index e977907..78bab66 100644 --- a/src/BlazorSortableJS/Components/DynamicComponentBase.cs +++ b/src/BlazorSortableJS/Components/DynamicComponentBase.cs @@ -1,8 +1,5 @@ using Microsoft.AspNetCore.Components; -using System; using System.Collections.Generic; -using System.Reflection; -using System.Threading.Tasks; namespace BlazorSortableJS.Components { diff --git a/src/BlazorSortableJS/Components/SortGroup.razor b/src/BlazorSortableJS/Components/SortGroup.razor new file mode 100644 index 0000000..843e64b --- /dev/null +++ b/src/BlazorSortableJS/Components/SortGroup.razor @@ -0,0 +1,28 @@ +@typeparam TItem + + @if(!ForceReDraw) + { + if (IsDiv) + { +
+ @foreach (var item in Sortable.GetRaw()) + { +
+ @Template(item) +
+ } +
+ } + else + { +
    + @foreach (var item in Sortable.GetRaw()) + { +
  • + @Template(item) +
  • + } +
+ } + } +
\ No newline at end of file diff --git a/src/BlazorSortableJS/Components/SortGroup.razor.cs b/src/BlazorSortableJS/Components/SortGroup.razor.cs new file mode 100644 index 0000000..61b3f7a --- /dev/null +++ b/src/BlazorSortableJS/Components/SortGroup.razor.cs @@ -0,0 +1,192 @@ +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Web; +using Microsoft.JSInterop; +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Text.Json; +using System.Threading.Tasks; + +namespace BlazorSortableJS.Components +{ + public partial class SortGroup : ComponentBase + { + [Inject] private IJSRuntime jSRuntime { get; set; } + [Parameter] public string Id { get; set; } + [Parameter] public string Class { get; set; } + [Parameter] public string TemplateClass { get; set; } + [Parameter] public string GroupName { get; set; } = Guid.NewGuid().ToString(); + [Parameter] public string Style { get; set; } + [Parameter] public bool IsDiv { get; set; } + [Parameter] public RenderFragment> Template { get; set; } + [Parameter] public EventCallback OnClick { get; set; } + [Parameter] public EventCallback TemplateOnClick { get; set; } + + [Parameter] public List Items { get; set; } + + [Parameter] public EventCallback> OnChoose { get; set; } + [Parameter] public EventCallback> OnUnchoose { get; set; } + [Parameter] public EventCallback> OnStart { get; set; } + [Parameter] public EventCallback> OnEnd { get; set; } + [Parameter] public EventCallback> OnAdd { get; set; } + [Parameter] public EventCallback> OnUpdate { get; set; } + [Parameter] public EventCallback> OnSort { get; set; } + [Parameter] public EventCallback> OnRemove { get; set; } + [Parameter] public EventCallback> OnFilter { get; set; } + [Parameter] public EventCallback> OnMove { get; set; } + [Parameter] public EventCallback> OnClone { get; set; } + [Parameter] public EventCallback> OnChange { get; set; } + public SortableJS Sortable { get; set; } + private bool Render; + private bool ForceReDraw; + + public async Task> GetOrderListAsync(string orderColumn) + { + var items = await Sortable.GetDataAsync(); + if (!string.IsNullOrEmpty(orderColumn)) + { + for (var i = 0; i < items.Count; ++i) + { + var type = typeof(TItem); + PropertyInfo pi = type.GetProperty(orderColumn); + pi.SetValue(items[i], i); + } + } + return items; + } + + private string TemplateTag + { + get + { + return (IsDiv) ? "div" : "li"; + } + } + private string Tag + { + get + { + return (IsDiv) ? "div" : "ul"; + } + } + + protected override Task OnInitializedAsync() + { + if (Id == null) + Id = Guid.NewGuid().ToString(); + Sortable = new SortableJS(jSRuntime); + Sortable.SetData(Items); + return base.OnInitializedAsync(); + } + public async void OnChooseEvent(SortableJSEvent e) + { + await OnChoose.InvokeAsync(new SortableEvent(this,e)); + } + public async void OnUnchooseEvent(SortableJSEvent e) + { + await OnUnchoose.InvokeAsync(new SortableEvent(this,e)); + } + public async void OnStartEvent(SortableJSEvent e) + { + await OnStart.InvokeAsync(new SortableEvent(this,e)); + } + public async void OnEndEvent(SortableJSEvent e) + { + await OnEnd.InvokeAsync(new SortableEvent(this,e)); + } + public async void OnAddEvent(SortableJSEvent e) + { + await OnAdd.InvokeAsync(new SortableEvent(this,e)); + } + public async void OnUpdateEvent(SortableJSEvent e) + { + await OnUpdate.InvokeAsync(new SortableEvent(this,e)); + } + public async void OnSortEvent(SortableJSEvent e) + { + await OnSort.InvokeAsync(new SortableEvent(this,e)); + } + public async void OnRemoveEvent(SortableJSEvent e) + { + await OnRemove.InvokeAsync(new SortableEvent(this,e)); + } + public async void OnFilterEvent(SortableJSEvent e) + { + await OnFilter.InvokeAsync(new SortableEvent(this,e)); + } + public async void OnMoveEvent(SortableJSEvent e) + { + await OnMove.InvokeAsync(new SortableEvent(this,e)); + } + public async void OnCloneEvent(SortableJSEvent e) + { + await OnClone.InvokeAsync(new SortableEvent(this,e)); + } + public async void OnChangeEvent(SortableJSEvent e) + { + await OnChange.InvokeAsync(new SortableEvent(this,e)); + } + + public async Task UpdateAsync() + { + await Sortable.ClearAsync(); + Sortable = new SortableJS(jSRuntime); + Sortable.SetData(Items); + ForceReDraw = true; + await InvokeAsync(StateHasChanged); + } + private async Task Start() + { + await Sortable.CreateAsync(Id, new SortableJsOptions + { + Group = GroupName, + Animation = 100, + OnClone = OnCloneEvent, + OnAdd = OnAddEvent, + OnChange = OnChangeEvent, + OnChoose = OnChooseEvent, + OnEnd = OnEndEvent, + OnFilter = OnFilterEvent, + OnMove = OnMoveEvent, + OnRemove = OnRemoveEvent, + OnSort = OnSortEvent, + OnStart = OnStartEvent, + OnUnchoose = OnUnchooseEvent, + OnUpdate = OnUpdateEvent, + }); + } + protected override async Task OnAfterRenderAsync(bool firstrun) + { + if (ForceReDraw) + { + Render = true; + ForceReDraw = false; + await InvokeAsync(StateHasChanged); + } + if (firstrun || Render) + { + Render = false; + await Start(); + } + } + } + + public class SortableEvent + { + public SortGroup Sender { get; set; } + public T Data { get; set; } + public SortableJSEvent Event { get; set; } + public SortableEvent(SortGroup sender, SortableJSEvent e) + { + Sender = sender; + try + { + Data = JsonSerializer.Deserialize(e.Data.ToString(), + new JsonSerializerOptions() {PropertyNameCaseInsensitive = true}); + } + catch{} + + Event = e; + } + } +} diff --git a/src/BlazorSortableJS/Components/SortableGroup.razor b/src/BlazorSortableJS/Components/SortableGroup.razor index 9ec8aa1..ca1a3d6 100644 --- a/src/BlazorSortableJS/Components/SortableGroup.razor +++ b/src/BlazorSortableJS/Components/SortableGroup.razor @@ -1,9 +1,10 @@ @inherits DynamicComponentBase +@attribute [Obsolete("SortGroup is not preferred")] @typeparam TItem @inject IJSRuntime jSRuntime; - @ChildContent + @ChildContent @code { @@ -26,7 +27,7 @@ protected override Task OnInitializedAsync() { - + if (Id == null) Id = Guid.NewGuid().ToString(); Sortable = new SortableJS(jSRuntime); diff --git a/src/BlazorSortableJS/Components/SortableItem.razor b/src/BlazorSortableJS/Components/SortableItem.razor index 5493d30..2eca0b5 100644 --- a/src/BlazorSortableJS/Components/SortableItem.razor +++ b/src/BlazorSortableJS/Components/SortableItem.razor @@ -1,32 +1,9 @@ @inherits DynamicComponentBase +@attribute [Obsolete("SortGroup is not preferred")] @typeparam TItem @if (Item != null) { - - @ChildContent - -} -@code { - [Parameter] public string Id { get; set; } - [Parameter] public string Class { get; set; } - [Parameter] public string Style { get; set; } - [Parameter] public bool IsDiv { get; set; } - [Parameter] public RenderFragment ChildContent { get; set; } - [Parameter] public EventCallback OnClick { get; set; } - [Parameter] public SortableJSSortItem Item { get; set; } - [CascadingParameter] public SortableJS Sortable { get; set; } - - - string Tag - { - get - { - return (IsDiv) ? "div" : "li"; - } - } - - protected override Task OnAfterRenderAsync(bool firstrun) - { - return base.OnAfterRenderAsync(false); - } + + @ChildContent + } \ No newline at end of file diff --git a/src/BlazorSortableJS/Components/SortableItem.razor.cs b/src/BlazorSortableJS/Components/SortableItem.razor.cs new file mode 100644 index 0000000..6e4c053 --- /dev/null +++ b/src/BlazorSortableJS/Components/SortableItem.razor.cs @@ -0,0 +1,32 @@ +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Web; +using System.Threading.Tasks; + +namespace BlazorSortableJS.Components +{ + public partial class SortableItem : DynamicComponentBase + { + [Parameter] public string Id { get; set; } + [Parameter] public string Class { get; set; } + [Parameter] public string Style { get; set; } + [Parameter] public bool IsDiv { get; set; } + [Parameter] public RenderFragment ChildContent { get; set; } + [Parameter] public EventCallback OnClick { get; set; } + [Parameter] public SortableJSSortItem Item { get; set; } + [CascadingParameter] public SortableJS Sortable { get; set; } + + + string Tag + { + get + { + return (IsDiv) ? "div" : "li"; + } + } + + protected override Task OnAfterRenderAsync(bool firstrun) + { + return base.OnAfterRenderAsync(false); + } + } +} diff --git a/src/BlazorSortableJS/SortableJS.cs b/src/BlazorSortableJS/SortableJS.cs index 9e4be76..3b95336 100644 --- a/src/BlazorSortableJS/SortableJS.cs +++ b/src/BlazorSortableJS/SortableJS.cs @@ -162,7 +162,7 @@ public ValueTask DestroyAsync() public void Add(string dataId, string data) { - var newItem = JsonSerializer.Deserialize(data); + var newItem = JsonSerializer.Deserialize(data, new JsonSerializerOptions(){PropertyNameCaseInsensitive = true}); _list.Add(new SortableJSSortItem() { DataId = dataId, Data = newItem, Show = false }); } @@ -203,7 +203,7 @@ public void OnAdd(object sender, SortableJSEvent data) { if (Guid.Parse(sender.ToString()) == RefId) { - var json = JsonSerializer.Serialize(data.Data); + var json = JsonSerializer.Serialize(data.Data, new JsonSerializerOptions(){PropertyNameCaseInsensitive = true}); Add(data.DataId, json); _opt.OnAdd?.Invoke(data);