Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
3.9k views
in Technique[技术] by (71.8m points)

blazor server side - Using row drag drop in a table to sort a backed List<BusinessEntity>

I'm trying to make a UI component that allows for easy sorting by drag-drop. I used a library to get started: https://github.com/Postlagerkarte/blazor-dragdrop

Here is my setup:

Components/ApproverPriorityList.razor

@using Project.ViewModels.PrimaryDb
@using Project.ViewModels.PrimaryDb.Datasets

<div id="main" class="container-fluid">
    <DxComboBox Data="@AllResources" TextFieldName="@nameof(ResourceViewModel.Text)" @bind-Value="@_newApprover" />
    <DxButton Text="Add" @onclick="AddApprover" />

    <hr />

    <Dropzone Items="LoadedApprovers">
        <ApproverItem OnRemoveClick="(item) => LoadedApprovers.Remove(item)" Item="@context"></ApproverItem>
    </Dropzone>
</div>

@code{

    [Parameter]
    public IList<ApproverTemplateDetailViewModel> LoadedApprovers { get; set; }

    [Parameter]
    public IList<ResourceViewModel> AllResources { get; set; }

    private string _newApprover;

    private void AddApprover()
    {
        if (string.IsNullOrWhiteSpace(_newApprover)) return;

        LoadedApprovers.Add(new ApproverTemplateDetailViewModel
        {
            ApproverResourceId = _newApprover,
            ApprovalLevel      = byte.Parse((LoadedApprovers.Count + 1).ToString()),
        });

        _newApprover = string.Empty;
    }

}

Components/ApproverItem.razor

@using Project.ViewModels.PrimaryDb

<div class="approverItemStyle">
    <DxButton Text="" @onclick="@(() => OnRemoveClick.InvokeAsync(Item))" />
    <i class="fad fa-user fa-fw theme-da"></i>
    @Item.ApproverResourceId
</div>

@code {

    [Parameter]
    public ApproverTemplateDetailViewModel Item { get; set; }

    [Parameter]
    public EventCallback<ApproverTemplateDetailViewModel> OnRemoveClick { get; set; }

}

Models

namespace Project.ViewModels.PrimaryDb
{
    public class ApproverTemplateDetailViewModel
    {
        public ApproverTemplateDetailViewModel() { }

        public ApproverTemplateDetailViewModel(ApproverTemplateDetail model)
        {
            Id                 = model.Id;
            ApproverResourceId = model.ApproverResourceId;
            ApprovalLevel      = model.ApprovalLevel;
        }

        public int    Id                 { get; set; }          
        public string ApproverResourceId { get; set; }
        public byte   ApprovalLevel      { get; set; }
    }
    
    public class ResourceViewModel
    {
        public ResourceViewModel() { }

        public ResourceViewModel(DataResource model)
        {
            Email = model.Email;
            Name  = model.FullName;             
        }

        public string Email { get; set; }           
        public string Text => $"{Name} ({Email})";
    }
}

Pages/Request-New.razor

@page "/request-new"

@using ProjectWeb.Services.Interfaces
@using Project.PrimaryDb
@using Project.PrimaryDb.Datasets
@using Project.PrimaryDb.Lookups    

@inject IResourceService ResourceProviderService
@inject IApproverTemplateService ApproverTemplateProviderService

<EditForm Model="@_model" CaptionPosition="CaptionPosition.Vertical" Context="editFormContext" OnValidSubmit="@HandleValidSubmit">
    <DataAnnotationsValidator />

    <DxFormLayout CssClass="dxFormLayoutHeaderStyle">
        <DxFormLayoutGroup Caption="Approvers" ColSpanMd="12">
            <DxFormLayoutItem Caption="List:" ColSpanMd="6">
                <Template>
                    <ApproverPriorityList LoadedApprovers="@_approverListData"></ApproverPriorityList>
                </Template>
            </DxFormLayoutItem >
        </DxFormLayoutGroup>            
    </DxFormLayout>
</EditForm>

@code {
    private BudgetReleaseRequestViewModel          _model = new BudgetReleaseRequestViewModel();
    private ApproverTemplateViewModel              _selectedTemplate;
    
    private IList<ResourceViewModel>               _localResources;     
    private IList<ApproverTemplateViewModel>       _approverHeadData;
    private IList<ApproverTemplateDetailViewModel> _approverListData = new List<ApproverTemplateDetailViewModel>();

    protected override async Task OnInitializedAsync()
    {
        @    = (await ResourceProviderService.GetAllResources()).ToList();
                    
        _approverListData  = (await ApproverTemplateProviderService.GetAllApproverTemplateDetails()).ToList();
        _approverListData  = _approverListData.Where(w => w.TemplateId == 1).ToList();
    }

    private void HandleValidSubmit(EditContext editContext) 
    {
    
    }

}

CSS

/*add this to avoid flickering*/
.plk-dd-inprogess > * {
    pointer-events: none;
}

/*dropzone style style*/
.plk-dd-dropzone {
    min-height: 50px;
}

/*drag drop styles*/

.plk-dd-spacing {
    height: 10px;
}

.plk-dd-spacing-dragged-over {
    padding: 25px;
}

.plk-dd-dragged-over {
    background-color: lightgray;
    opacity: 0.6;
    animation: blinker 1s linear infinite;
}

.plk-dd-dragged-over > div {
    background-color: lightgray;
    opacity: 0.6;
    animation: blinker 1s linear infinite;
}

.plk-dd-dragged-over-denied {
    background-color: red;
    opacity: 0.6;
    animation: blinker 1s linear infinite;
}

.plk-dd-in-transit {
    opacity: 0;
}

.plk-dd-in-transit > div {
     opacity: 0;
}

@keyframes blinker {
    50% {
        opacity: 0;
    }
}

.blink_me {
    animation: blinker 1s linear infinite;
}

/*for flex demo*/

.plk-flex .plk-dd-spacing {
    width: 20px;
    height: auto;
}

.plk-flex .plk-dd-dragged-over {
    background-color: lightgray;
    opacity: 0.6;
    animation: blinker 1s linear infinite;
}

.plk-flex .plk-dd-dragged-over > div {
    background-color: lightgray;
    opacity: 0.9;
    animation: blinker 1s linear infinite;
}

.plk-flex .plk-dd-in-transit {
    background-color: orangered;
}

.plk-flex .plk-dd-in-transit > div {
    background-color: orangered;
}

.plk-dd-noselect {
    -webkit-touch-callout: none; /* iOS Safari */
    -webkit-user-select: none; /* Safari */
    -khtml-user-select: none; /* Konqueror HTML */
    -moz-user-select: none; /* Old versions of Firefox */
    -ms-user-select: none; /* Internet Explorer/Edge */
    user-select: none; /* Non-prefixed version, currently
                                  supported by Chrome, Edge, Opera and Firefox */
}

Now, I have the UI working visually: I can drag & drop row to sort out. I need to add mechanism to hold sort order somehow in code. I have no idea where to begin on that? In my class ApproverTemplateDetailViewModel, there is a property ApprovalLevel that I want to hold the sort order


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)
等待大神答复

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...