Skip to content

Commit

Permalink
refactored components code behind, added observable models concept
Browse files Browse the repository at this point in the history
  • Loading branch information
suxrobGM committed Aug 2, 2024
1 parent 7f7316f commit 41f3939
Show file tree
Hide file tree
Showing 21 changed files with 462 additions and 309 deletions.
132 changes: 65 additions & 67 deletions src/FormBuilder/Components/FieldPropertyEditor.razor
Original file line number Diff line number Diff line change
@@ -1,82 +1,80 @@
@using FormBuilder.Models

@if (Field is not null)
{
<RadzenStack class="@ContainerClass" Orientation="Orientation.Vertical">
<RadzenFormField Text="ID">
<RadzenTextBox @bind-Value="Field.Name" Disabled="true"/>
<RadzenStack class="@ContainerClass" Orientation="Orientation.Vertical">
<RadzenFormField Text="ID">
<RadzenTextBox Value="@Field.Name" Disabled="true"/>
</RadzenFormField>
<RadzenFormField Text="Input Type">
<RadzenDropDown
TValue="FieldType"
@bind-Value="InputType"
Data="_inputTypes"
TextProperty="Text"
ValueProperty="Value">
</RadzenDropDown>
</RadzenFormField>
<RadzenFormField Text="Label">
<RadzenTextBox @bind-Value="@Field.Label"/>
</RadzenFormField>
<RadzenFormField Text="Placeholder" AllowFloatingLabel="false">
<RadzenTextBox @bind-Value="@Field.Placeholder"/>
</RadzenFormField>
<RadzenFormField Text="Hint" AllowFloatingLabel="false">
<RadzenTextBox @bind-Value="@Field.Hint"/>
</RadzenFormField>
<RadzenStack Orientation="Orientation.Horizontal" Gap="1rem" AlignItems="AlignItems.Center">
<RadzenLabel Text="Read only" Component="ReadOnlyInput"/>
<RadzenSwitch Name="ReadOnlyInput" @bind-Value="Field.ReadOnly"/>
</RadzenStack>
<RadzenStack Orientation="Orientation.Horizontal" Gap="1rem" AlignItems="AlignItems.Center">
<RadzenLabel Text="Disabled" Component="DisabledInput"/>
<RadzenSwitch Name="DisabledInput" @bind-Value="@Field.Disabled"/>
</RadzenStack>

@if (Field is NumericField<int> numericIntField)
{
<NumericFieldEditor Field="numericIntField"/>
}
@if (Field is NumericField<decimal> numericDecimalField)
{
<NumericFieldEditor Field="numericDecimalField"/>
}

@if (Field is DateField dateField)
{
<RadzenFormField Text="Date Format">
<RadzenTextBox @bind-Value="@dateField.DateFormat"/>
</RadzenFormField>
<RadzenFormField Text="Input Type">
}

@if (Field is SelectField selectField)
{
<RadzenFormField Text="List ID">
<RadzenDropDown
TValue="FieldType"
@bind-Value="InputType"
Data="_inputTypes"
TextProperty="Text"
ValueProperty="Value">
TValue="int?"
@bind-Value="SelectedListId"
Data="_listIds"
Count="@_listIdCount"
LoadData="LoadListIdValuesAsync"
AllowVirtualization="true"
AllowFiltering="true"
AllowClear="true">
</RadzenDropDown>
</RadzenFormField>
<RadzenFormField Text="Label">
<RadzenTextBox @bind-Value="Label"/>
</RadzenFormField>
<RadzenFormField Text="Placeholder" AllowFloatingLabel="false">
<RadzenTextBox @bind-Value="Placeholder"/>
</RadzenFormField>
<RadzenFormField Text="Hint" AllowFloatingLabel="false">
<RadzenTextBox @bind-Value="Field.Hint"/>
</RadzenFormField>
<RadzenStack Orientation="Orientation.Horizontal" Gap="1rem" AlignItems="AlignItems.Center">
<RadzenLabel Text="Read only" Component="ReadOnlyInput"/>
<RadzenSwitch Name="ReadOnlyInput" @bind-Value="@ReadOnly"/>
</RadzenStack>
<RadzenStack Orientation="Orientation.Horizontal" Gap="1rem" AlignItems="AlignItems.Center">
<RadzenLabel Text="Disabled" Component="DisabledInput"/>
<RadzenSwitch Name="DisabledInput" @bind-Value="@Disabled"/>
</RadzenStack>

@if (Field is NumericField<int> numericIntField)
{
<NumericFieldEditor Field="numericIntField"/>
}
@if (Field is NumericField<decimal> numericDecimalField)
{
<NumericFieldEditor Field="numericDecimalField"/>
}

@if (Field is DateField dateField)
{
<RadzenFormField Text="Date Format">
<RadzenTextBox @bind-Value="dateField.DateFormat"></RadzenTextBox>
</RadzenFormField>
}

@if (Field is SelectField)
@if (selectField.ListId is not null)
{
<RadzenFormField Text="List ID">
<RadzenFormField Text="List Values">
<RadzenDropDown
@bind-Value="SelectedListId"
Data="_listIds"
Count="@_listIdCount"
LoadData="LoadListIdValuesAsync"
AllowVirtualization="true"
TValue="string"
Data="_listValues"
Disabled="ListValuesLoading"
AllowFiltering="true"
AllowClear="true">
</RadzenDropDown>
</RadzenFormField>

@if (SelectedListId is not null)
{
<RadzenFormField Text="List Values">
<RadzenDropDown
TValue="string"
Data="_listValues"
Disabled="ListValuesLoading"
AllowFiltering="true"
AllowClear="true">
</RadzenDropDown>
</RadzenFormField>
}
}
}

<FieldValidatorsEditor @bind-Field="Field"/>
</RadzenStack>
}
<FieldValidatorsEditor Field="Field"/>
</RadzenStack>
88 changes: 8 additions & 80 deletions src/FormBuilder/Components/FieldPropertyEditor.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,20 +31,17 @@ public partial class FieldPropertyEditor : ComponentBase
/// <summary>
/// The currently selected field to edit.
/// </summary>
[Parameter]
public Field? Field { get; set; }
[Parameter, EditorRequired]
public Field Field { get; set; } = default!;

/// <summary>
/// Event that is triggered when the selected field's property changes.
/// </summary>
[Parameter]
public EventCallback<Field?> FieldChanged { get; set; }
public EventCallback<Field> FieldChanged { get; set; }

/// <summary>
/// Event that is triggered when a field property changes such as label, placeholder, etc.
/// Event that is triggered when a field type changes.
/// </summary>
[Parameter]
public EventCallback<FieldPropertyChangedArgs> PropertyChanged { get; set; }
public EventCallback<FieldTypeChangedEventArgs> FieldTypeChanged { get; set; }

/// <summary>
/// The CSS class for the container element.
Expand All @@ -56,82 +53,17 @@ public partial class FieldPropertyEditor : ComponentBase

#region Binding Properties

private string? Label
{
get => Field?.Label;
set
{
if (Field is null || Field.Label == value)
{
return;
}

Field.Label = value;
FieldChanged.InvokeAsync(Field);
PropertyChanged.InvokeAsync(new FieldPropertyChangedArgs(Field, nameof(Models.Field.Label), value));
}
}

private string? Placeholder
{
get => Field?.Placeholder;
set
{
if (Field is null || Field.Placeholder == value)
{
return;
}

Field.Placeholder = value;
FieldChanged.InvokeAsync(Field);
PropertyChanged.InvokeAsync(new FieldPropertyChangedArgs(Field, nameof(Models.Field.Placeholder), value));
}
}

private FieldType InputType
{
get => Field?.Type ?? FieldType.Text;
set
{
if (Field is null || Field.Type == value)
{
return;
}

FieldChanged.InvokeAsync(Field);
PropertyChanged.InvokeAsync(new FieldPropertyChangedArgs(Field, nameof(Models.Field.Type), value));
}
}

private bool ReadOnly
{
get => Field?.ReadOnly ?? false;
get => Field.Type;
set
{
if (Field is null || Field.ReadOnly == value)
if (Field.Type == value)
{
return;
}

Field.ReadOnly = value;
FieldChanged.InvokeAsync(Field);
PropertyChanged.InvokeAsync(new FieldPropertyChangedArgs(Field, nameof(Models.Field.ReadOnly), value));
}
}

private bool Disabled
{
get => Field?.Disabled ?? false;
set
{
if (Field is null || Field.Disabled == value)
{
return;
}

Field.Disabled = value;
FieldChanged.InvokeAsync(Field);
PropertyChanged.InvokeAsync(new FieldPropertyChangedArgs(Field, nameof(Models.Field.Disabled), value));
FieldTypeChanged.InvokeAsync(new FieldTypeChangedEventArgs(Field, value));
}
}

Expand All @@ -143,8 +75,6 @@ private int? SelectedListId
if (Field is SelectField selectField && selectField.ListId != value)
{
selectField.ListId = value;
FieldChanged.InvokeAsync(Field);
PropertyChanged.InvokeAsync(new FieldPropertyChangedArgs(Field, nameof(SelectField.ListId), value));
_ = FetchListValuesAsync(value);
}
}
Expand Down Expand Up @@ -207,5 +137,3 @@ private async Task FetchListValuesAsync(int? listId)
ListValuesLoading = false;
}
}

public record FieldPropertyChangedArgs(Field Field, string PropertyName, object? NewValue);
41 changes: 21 additions & 20 deletions src/FormBuilder/Components/FieldValidatorsEditor.razor
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,28 @@

<RadzenPanelMenu>
<RadzenPanelMenuItem Text="Add Validator" Icon="rule">
<RadzenPanelMenuItem Text="Required Validator" Icon="check" Click="() => AddValidator(ValidatorType.Required)"/>
<RadzenPanelMenuItem
Text="Required Validator"
Icon="check"
Click="() => AddValidator(ValidatorType.Required)"/>

@switch (Field.Type)
{
case FieldType.Text:
<RadzenPanelMenuItem Text="Email Validator" Icon="mail" Click="() => AddValidator(ValidatorType.Email)"/>
<RadzenPanelMenuItem Text="Length Validator" Icon="abc" Click="() => AddValidator(ValidatorType.Length)"/>
<RadzenPanelMenuItem
Text="Email Validator"
Icon="mail"
Click="() => AddValidator(ValidatorType.Email)"/>
<RadzenPanelMenuItem
Text="Length Validator"
Icon="abc"
Click="() => AddValidator(ValidatorType.Length)"/>
break;
case FieldType.NumericInt or FieldType.NumericDecimal:
<RadzenPanelMenuItem Text="Numeric Range Validator" Icon="filter_1" Click="() => AddValidator(ValidatorType.NumericRange)"/>
<RadzenPanelMenuItem
Text="Numeric Range Validator"
Icon="filter_1"
Click="() => AddValidator(ValidatorType.NumericRange)"/>
break;
}
</RadzenPanelMenuItem>
Expand All @@ -24,34 +37,22 @@
{
case RequiredValidator requiredValidator:
<RadzenAccordionItem Text="Required Validator" Icon="check">
<ValidatorPropertyEditor
TValue="RequiredValidator"
Validator="@requiredValidator"
ValidatorChanged="RaiseFieldChanged"/>
<ValidatorPropertyEditor Validator="@requiredValidator"/>
</RadzenAccordionItem>
break;
case EmailValidator emailValidator:
<RadzenAccordionItem Text="Email Validator" Icon="mail">
<ValidatorPropertyEditor
TValue="EmailValidator"
Validator="@emailValidator"
ValidatorChanged="RaiseFieldChanged"/>
<ValidatorPropertyEditor Validator="@emailValidator"/>
</RadzenAccordionItem>
break;
case LengthValidator lengthValidator:
<RadzenAccordionItem Text="Length Validator" Icon="abc">
<ValidatorPropertyEditor
TValue="LengthValidator"
Validator="@lengthValidator"
ValidatorChanged="RaiseFieldChanged"/>
<ValidatorPropertyEditor Validator="@lengthValidator"/>
</RadzenAccordionItem>
break;
case NumericRangeValidator numericRangeValidator:
<RadzenAccordionItem Text="Numeric Range Validator" Icon="filter_1">
<ValidatorPropertyEditor
TValue="NumericRangeValidator"
Validator="@numericRangeValidator"
ValidatorChanged="RaiseFieldChanged"/>
<ValidatorPropertyEditor Validator="@numericRangeValidator"/>
</RadzenAccordionItem>
break;
}
Expand Down
12 changes: 2 additions & 10 deletions src/FormBuilder/Components/FieldValidatorsEditor.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,12 @@ public partial class FieldValidatorsEditor : ComponentBase

[Parameter, EditorRequired]
public Field Field { get; set; } = default!;

[Parameter]
public EventCallback<Field> FieldChanged { get; set; }

#endregion

private void RaiseFieldChanged()
{
FieldChanged.InvokeAsync(Field);
}

private void AddValidator(ValidatorType validatorType)
{
Field.Validators.Add(ValidatorFactory.Create(validatorType));
FieldChanged.InvokeAsync(Field);
var validator = ValidatorFactory.Create(validatorType);
Field.Validators.Add(validator);
}
}
4 changes: 2 additions & 2 deletions src/FormBuilder/Components/FormEditor.razor
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,8 @@
<RadzenText TextStyle="TextStyle.H5" TextAlign="TextAlign.Center">Properties</RadzenText>
<FieldPropertyEditor
ContainerClass="px-1"
@bind-Field="SelectedField"
PropertyChanged="(e) => HandleFieldPropertyChanged(e)">
Field="SelectedField"
FieldTypeChanged="HandleFieldTypeChanged">
</FieldPropertyEditor>
}

Expand Down
Loading

0 comments on commit 41f3939

Please sign in to comment.