Open Closed

Binding Dynamic Columns on LeptonX Theme #3899


0
novelty created
  • ABP Framework version: Version 6.0.0-rc.4 (Prerelease)
  • UI type: Blazor

Hello,

We are building a workflow application that works with dynamic columns. A part of the application is, users are able to create dynamic inputs for text, dates, integers etc. Another part of the application allows users to create dynamically built lists, wich consists of checkboxes as of now. Example can be found below:

Here "Kurulan Şarj Ünitesi" is a dynamically created list consisting of 3 checkboxes, we are trying to bind selection dynamically to a model using form. Since user is able to create as much as lists or inputs, we are not able to bind these inputs to the models using one static model on a form. Below are the models are we are using for this process:

public class FlowActivityDetail : FullAuditedAggregateRoot<Guid>
    {
        public Guid FlowActivityId { get; private set; }
        public int FlowStep { get; private set; }
        public string DynamicDetail { get; private set; }
        public int DataType { get; private set; }
        public int Requirement { get; private set; }
        public int Row { get; set; }
    }

public class DynamicList : FullAuditedAggregateRoot<Guid>
    {
        public Guid FlowActivityDetailId { get; set; }
        public string ListName { get; private set; }
    }

public class DynamicListItem : FullAuditedAggregateRoot<Guid>
    {
        public Guid DynamicListId { get; set; }
        public string ItemName { get; set; }
    }

public class FlowActivityValue : FullAuditedAggregateRoot<Guid>
    {
        public Guid FlowActivityDetailId { get; set; }
        public string Value { get; set; }
    }

Our form code for rendering dynamic columns and binding inputs to FlowActivityValue as a record. Note that each input needs to bind to a different FlowActivityValue:

<Form>
    <Validations @ref="@CreateValidationsRef" Model="@NewFlowActivityValue"  Mode="ValidationMode.Manual" ValidateOnLoad="false">
        <Validation>
            @foreach (var flowActivityDetail in FlowActivityDetailsByFAList)
            {
                if (flowActivityDetail.DataType == (int)DataTypeEnum.String)
                {
                    <Field>
                        <FieldLabel>@flowActivityDetail.DynamicDetail</FieldLabel>
                        <TextEdit @onchange="@(e => CreateFlowActivityValueAsync(flowActivityDetail.Id, e.Value.ToString()))"/>
                    </Field>
                }

                if (flowActivityDetail.DataType == (int)DataTypeEnum.Date)
                {
                    <Field>
                        <FieldLabel>@flowActivityDetail.DynamicDetail</FieldLabel>
                        <FieldBody>
                            <DatePicker TValue="DateTime?" Placeholder="DD/MM/YYYY" @bind-Text="@NewFlowActivityValue.Value" />
                        </FieldBody>
                        <FieldHelp>Format: DD/MM/YYYY</FieldHelp>
                    </Field>
                }

                //TODO seçim için düzelt
                if (flowActivityDetail.DataType == (int)DataTypeEnum.Selection)
                {
                    var dynamicListItems = DynamicListItems.Where(x => x.DynamicListName == flowActivityDetail.DynamicDetail).ToList();
                    <Field>
                        <FieldLabel>@flowActivityDetail.DynamicDetail</FieldLabel>
                        <FieldBody>
                            @foreach (var dynamicListItem in dynamicListItems)
                            {
                                <Check TValue="string" @bind-Checked="@NewFlowActivityValue.Value">@dynamicListItem.ItemName</Check>
                            }
                        </FieldBody>
                    </Field>
                }
                //TODO resim ve dosya için eklenecek
            }
            <Button Color="Color.Primary"
                    Type="@ButtonType.Submit"
                    PreventDefaultOnSubmit="true"
                    Clicked="SendToApproval">
                @L["Save"]
            </Button>
        </Validation>
    </Validations>
</Form>

We have tried to use onchange method to bind the dynamic fields, but this is not reliable since user can actually leave the form page and decide to not finish the form. If this happens we would be left with unrelated data in our database. We are trying to solve this in a way that however many dynamic inputs and list items should be created on a database at FlowActivityValue table with a click of a save button. Our question is is there an abp commercial module or a library we can use to get this process done? How would you suggest us to go about doing this? Thank you.


2 Answer(s)
  • 0
    novelty created

    Are there any updates on this ?

  • 0
    enisn created
    Support Team

    You don'T have to save database all the changes, you can keep data in Blazor component until saving it.

    I'll present a simple example how to achieve that and how to modify items in memory in blazor ui

    public partial Class MyPage
    {
        public Dictionary<string, string> MyList {get;} = new();
        
        public string Key { get; set; }
        
        public string Value { get; set; }
        
        public void AddOption()
        {
            MyList.Add(Key, Value);
        }
        
        public async Task SaveAsync()
        {
            // TODO: Save 'MyList'.
        }
    }
    
    
    @foreach(var item in MyList)
    {
        <Field>
            <FieldLabel>@item.Key</FieldLabel>
            <FieldBody>
                <TextEdit @bind-Value="@MyList[@item.Key].Value" />
            </FieldBody>
        </Field>
    }
    </hr />
    <Field>
        <FieldLabel>Key</FieldLabel>
        <FieldBody>
            <TextEdit @bind-Value="@Key" />
        </FieldBody>
    </Field>
    
    <Field>
        <FieldLabel>Key</FieldLabel>
        <FieldBody>
            <TextEdit @bind-Value="@Value" />
        </FieldBody>
    </Field>
    <Button OnClick="()=>AddOption("")" />
     Text="</Button>Add Option
    
    <Button OnClick="SaveAsync" >Save</Button>