Skip to content

Commit

Permalink
implemented Validators editor menu
Browse files Browse the repository at this point in the history
  • Loading branch information
suxrobGM committed Aug 1, 2024
1 parent 23af91c commit 7f7316f
Show file tree
Hide file tree
Showing 26 changed files with 301 additions and 67 deletions.
15 changes: 4 additions & 11 deletions src/FormBuilder/Components/FieldPropertyEditor.razor
Original file line number Diff line number Diff line change
Expand Up @@ -33,20 +33,13 @@
<RadzenSwitch Name="DisabledInput" @bind-Value="@Disabled"/>
</RadzenStack>

@if (Field is TextField textField)
{
<RadzenFormField Text="Max Length">
<RadzenNumeric @bind-Value="textField.MaxLength"></RadzenNumeric>
</RadzenFormField>
}

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

@if (Field is DateField dateField)
Expand Down Expand Up @@ -83,7 +76,7 @@
</RadzenFormField>
}
}
<RadzenText Text="Validators" TextStyle="TextStyle.H6" TextAlign="TextAlign.Center" />

<FieldValidatorsEditor @bind-Field="Field"/>
</RadzenStack>
}
60 changes: 60 additions & 0 deletions src/FormBuilder/Components/FieldValidatorsEditor.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
@using FormBuilder.Models

<RadzenPanelMenu>
<RadzenPanelMenuItem Text="Add Validator" Icon="rule">
<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)"/>
break;
case FieldType.NumericInt or FieldType.NumericDecimal:
<RadzenPanelMenuItem Text="Numeric Range Validator" Icon="filter_1" Click="() => AddValidator(ValidatorType.NumericRange)"/>
break;
}
</RadzenPanelMenuItem>
</RadzenPanelMenu>

<RadzenAccordion Multiple="true">
<Items>
@foreach (var validator in Field.Validators)
{
@switch (validator)
{
case RequiredValidator requiredValidator:
<RadzenAccordionItem Text="Required Validator" Icon="check">
<ValidatorPropertyEditor
TValue="RequiredValidator"
Validator="@requiredValidator"
ValidatorChanged="RaiseFieldChanged"/>
</RadzenAccordionItem>
break;
case EmailValidator emailValidator:
<RadzenAccordionItem Text="Email Validator" Icon="mail">
<ValidatorPropertyEditor
TValue="EmailValidator"
Validator="@emailValidator"
ValidatorChanged="RaiseFieldChanged"/>
</RadzenAccordionItem>
break;
case LengthValidator lengthValidator:
<RadzenAccordionItem Text="Length Validator" Icon="abc">
<ValidatorPropertyEditor
TValue="LengthValidator"
Validator="@lengthValidator"
ValidatorChanged="RaiseFieldChanged"/>
</RadzenAccordionItem>
break;
case NumericRangeValidator numericRangeValidator:
<RadzenAccordionItem Text="Numeric Range Validator" Icon="filter_1">
<ValidatorPropertyEditor
TValue="NumericRangeValidator"
Validator="@numericRangeValidator"
ValidatorChanged="RaiseFieldChanged"/>
</RadzenAccordionItem>
break;
}
}
</Items>
</RadzenAccordion>
29 changes: 29 additions & 0 deletions src/FormBuilder/Components/FieldValidatorsEditor.razor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using FormBuilder.Factories;
using FormBuilder.Models;
using Microsoft.AspNetCore.Components;

namespace FormBuilder.Components;

public partial class FieldValidatorsEditor : ComponentBase
{
#region Parameters

[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);
}
}
19 changes: 10 additions & 9 deletions src/FormBuilder/Components/FormEditor.razor
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
@using FormBuilder.Models

<RadzenRow class="vh-100">
<RadzenColumn Size="12" SizeMD="9" SizeLG="10">
<RadzenColumn Size="12" SizeMD="8" SizeLG="9">
<RadzenStack Orientation="Orientation.Vertical" Gap="1rem">
@if (_formDefinition.Id is not null)
{
Expand Down Expand Up @@ -47,10 +47,10 @@
</RadzenStack>
</RadzenColumn>

<RadzenColumn class="border rz-background-color-base-100" Size="12" SizeMD="3" SizeLG="2">
<RadzenColumn class="border rz-background-color-base-100" Size="12" SizeMD="4" SizeLG="3">
<RadzenStack Orientation="Orientation.Vertical" Gap="0.5rem">
<RadzenPanelMenu>
<RadzenPanelMenuItem Text="Fields" Icon="payment">
<RadzenPanelMenuItem Text="Add Field" Icon="payment">
<Dragable Data="() => AddField(FieldType.Text)" Zone="FieldsZone">
<RadzenPanelMenuItem Text="Text Field" Icon="input" Click="() => AddField(FieldType.Text)"/>
</Dragable>
Expand Down Expand Up @@ -79,12 +79,13 @@
</FieldPropertyEditor>
}

@if (_formDefinition.Fields.Count > 0)
{
<RadzenButton Text="Save Form" Click="SaveFormAsync" Disabled="IsLoading"/>
}

<RadzenButton Text="Load Form" Click="OpenLoadFormDialogAsync" Disabled="IsLoading"/>
<RadzenStack class="ms-1 mt-2" Orientation="Orientation.Horizontal" Gap="1rem">
@if (_formDefinition.Fields.Count > 0)
{
<RadzenButton Text="Save Form" Click="SaveFormAsync" Disabled="IsLoading"/>
}
<RadzenButton Text="Load Form" Click="OpenLoadFormDialogAsync" Disabled="IsLoading"/>
</RadzenStack>
</RadzenStack>
</RadzenColumn>
</RadzenRow>
4 changes: 2 additions & 2 deletions src/FormBuilder/Components/FormEditor.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ private async Task UpdateFormDesignJsonAsync()

private Task AddField(FieldType fieldType)
{
var field = FieldFactory.CreateField(fieldType);
var field = FieldFactory.Create(fieldType);
field.Label = fieldType.ToString();
_formDefinition.Fields.Add(field);
SelectedField = field;
Expand Down Expand Up @@ -106,7 +106,7 @@ private Task HandleFieldPropertyChanged(FieldPropertyChangedArgs args)
/// <param name="newType"></param>
private void ChangeFieldType(FieldType newType, Field oldField)
{
var newField = FieldFactory.CreateFieldFrom(newType, oldField);
var newField = FieldFactory.CreateFrom(newType, oldField);
var index = _formDefinition.Fields.IndexOf(oldField);
_formDefinition.Fields[index] = newField; // Replace the old field with the new one, old one will be deleted by GC
SelectedField = newField;
Expand Down
12 changes: 6 additions & 6 deletions src/FormBuilder/Components/FormField.razor
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
Name="@textField.Name"
@bind-Value="textField.Value"
Placeholder="@textField.Placeholder"
MaxLength="@textField.MaxLength"
MaxLength="@textField.GetMaxLength()"
ReadOnly="Disabled">
</RadzenTextBox>
break;
Expand All @@ -28,8 +28,8 @@
Name="@numericIntField.Name"
@bind-Value="numericIntField.Value"
Placeholder="@numericIntField.Placeholder"
Min="numericIntField.Min"
Max="numericIntField.Max"
Min="numericIntField.GetMin()"
Max="numericIntField.GetMax()"
ShowUpDown="numericIntField.ShowUpDown"
Step="@numericIntField.Step"
Format="@numericIntField.Format"
Expand All @@ -41,8 +41,8 @@
Name="@numericField.Name"
@bind-Value="numericField.Value"
Placeholder="@numericField.Placeholder"
Min="numericField.Min"
Max="numericField.Max"
Min="numericField.GetMin()"
Max="numericField.GetMax()"
ShowUpDown="numericField.ShowUpDown"
Step="@numericField.Step"
Format="@numericField.Format"
Expand Down Expand Up @@ -100,7 +100,7 @@
Text="@lengthValidator.Text">
</RadzenLengthValidator>
break;
case RangeValidator rangeValidator:
case NumericRangeValidator rangeValidator:
<RadzenNumericRangeValidator
Component="@Field.Name"
Min="rangeValidator.Min"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,5 @@
@typeparam TValue where TValue : struct

<RadzenFormField Text="Min">
<RadzenNumeric TValue="decimal?" Value="Field.Min" ValueChanged="OnMinChanged"/>
</RadzenFormField>
<RadzenFormField Text="Max">
<RadzenNumeric TValue="decimal?" Value="Field.Max" ValueChanged="OnMaxChanged"/>
</RadzenFormField>
<RadzenFormField Text="Step">
<RadzenNumeric TValue="decimal" />
</RadzenFormField>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,14 @@

namespace FormBuilder.Components;

public partial class NumericFieldPropertyEditor<TValue> : ComponentBase where TValue : struct
public partial class NumericFieldEditor<TValue> : ComponentBase where TValue : struct
{
[Parameter, EditorRequired]
public NumericField<TValue> Field { get; set; } = default!;

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

private void OnMinChanged(decimal? value)
{
Field.Min = value;
FieldChanged.InvokeAsync(Field);
}

private void OnMaxChanged(decimal? value)
{
Field.Max = value;
FieldChanged.InvokeAsync(Field);
}

private void OnStepChanged(string value)
{
Field.Step = value;
Expand Down
42 changes: 42 additions & 0 deletions src/FormBuilder/Components/ValidatorPropertyEditor.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
@using FormBuilder.Models
@typeparam TValue where TValue : FormBuilder.Models.Validator

<RadzenStack Orientation="Orientation.Vertical">
<RadzenFormField Text="Error Text">
<RadzenTextBox Value="@Validator.Text" ValueChanged="OnTextChanged"/>
</RadzenFormField>
<RadzenStack Orientation="Orientation.Horizontal" Gap="1rem" AlignItems="AlignItems.Center">
<RadzenLabel Text="Show as popup" Component="Validator.ShowAsPopup"/>
<RadzenSwitch Name="Validator.ShowAsPopup" Value="@Validator.ShowAsPopup" ValueChanged="OnShowAsPopupChanged"/>
</RadzenStack>

@switch (Validator)
{
case RequiredValidator requiredValidator:
<RadzenStack Orientation="Orientation.Horizontal" Gap="1rem" AlignItems="AlignItems.Center">
<RadzenLabel Text="Required" Component="Validator.IsRequired"/>
<RadzenSwitch Name="Validator.IsRequired" Value="@requiredValidator.IsRequired" Disabled="true"/>
</RadzenStack>
<RadzenStack Orientation="Orientation.Horizontal" Gap="1rem" AlignItems="AlignItems.Center">
<RadzenLabel Text="Show required hint" Component="ShowRequiredHint"/>
<RadzenSwitch Name="Validator.ShowRequiredHint" Value="@requiredValidator.ShowRequiredHint" ValueChanged="OnShowRequiredHintChanged"/>
</RadzenStack>
break;
case LengthValidator lengthValidator:
<RadzenFormField Text="Min Chars Length">
<RadzenNumeric TValue="int?" Value="lengthValidator.MinLength" ValueChanged="OnMinLengthChanged"/>
</RadzenFormField>
<RadzenFormField Text="Max Chars Length">
<RadzenNumeric TValue="int?" Value="lengthValidator.MaxLength" ValueChanged="OnMaxLengthChanged"/>
</RadzenFormField>
break;
case NumericRangeValidator numericRangeValidator:
<RadzenFormField Text="Min">
<RadzenNumeric TValue="int" Value="numericRangeValidator.Min" ValueChanged="OnMinChanged"/>
</RadzenFormField>
<RadzenFormField Text="Max">
<RadzenNumeric TValue="int" Value="numericRangeValidator.Max" ValueChanged="OnMaxChanged"/>
</RadzenFormField>
break;
}
</RadzenStack>
74 changes: 74 additions & 0 deletions src/FormBuilder/Components/ValidatorPropertyEditor.razor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
using FormBuilder.Models;
using Microsoft.AspNetCore.Components;

namespace FormBuilder.Components;

public partial class ValidatorPropertyEditor<TValue> : ComponentBase where TValue : Validator
{
#region Parameters

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

[Parameter]
public EventCallback<TValue> ValidatorChanged { get; set; }

#endregion

private void OnTextChanged(string value)
{
Validator.Text = value;
ValidatorChanged.InvokeAsync(Validator);
}

private void OnShowAsPopupChanged(bool value)
{
Validator.ShowAsPopup = value;
ValidatorChanged.InvokeAsync(Validator);
}

private void OnShowRequiredHintChanged(bool value)
{
if (Validator is RequiredValidator requiredValidator)
{
requiredValidator.ShowRequiredHint = value;
ValidatorChanged.InvokeAsync(Validator);
}
}

private void OnMinLengthChanged(int? value)
{
if (Validator is LengthValidator lengthValidator)
{
lengthValidator.MinLength = value;
ValidatorChanged.InvokeAsync(Validator);
}
}

private void OnMaxLengthChanged(int? value)
{
if (Validator is LengthValidator lengthValidator)
{
lengthValidator.MaxLength = value;
ValidatorChanged.InvokeAsync(Validator);
}
}

private void OnMinChanged(int value)
{
if (Validator is NumericRangeValidator numericRangeValidator)
{
numericRangeValidator.Min = value;
ValidatorChanged.InvokeAsync(Validator);
}
}

private void OnMaxChanged(int value)
{
if (Validator is NumericRangeValidator numericRangeValidator)
{
numericRangeValidator.Max = value;
ValidatorChanged.InvokeAsync(Validator);
}
}
}
2 changes: 1 addition & 1 deletion src/FormBuilder/Converters/ValidatorJsonConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public override Validator Read(ref Utf8JsonReader reader, Type typeToConvert, Js
ValidatorType.Required => JsonSerializer.Deserialize<RequiredValidator>(rootElement.GetRawText(), options),
ValidatorType.Length => JsonSerializer.Deserialize<LengthValidator>(rootElement.GetRawText(), options),
ValidatorType.Email => JsonSerializer.Deserialize<EmailValidator>(rootElement.GetRawText(), options),
ValidatorType.Range => JsonSerializer.Deserialize<RangeValidator>(rootElement.GetRawText(), options),
ValidatorType.NumericRange => JsonSerializer.Deserialize<NumericRangeValidator>(rootElement.GetRawText(), options),
_ => throw new NotSupportedException($"The value of the validator type '{enumValidatorType}' is not supported"),
};

Expand Down
Loading

0 comments on commit 7f7316f

Please sign in to comment.