597 lines
33 KiB
C#
597 lines
33 KiB
C#
using DevExpress.Blazor;
|
|
using Microsoft.AspNetCore.Components;
|
|
using Microsoft.AspNetCore.Components.Forms;
|
|
using Microsoft.AspNetCore.Components.Web;
|
|
using System.ComponentModel.DataAnnotations;
|
|
using System.Linq.Expressions;
|
|
using TIAMWebApp.Shared.Application.Utility;
|
|
using Microsoft.Extensions.Localization;
|
|
using TIAM.Resources;
|
|
using TIAMWebApp.Shared.Application.Interfaces;
|
|
using System.Reflection;
|
|
using TIAMWebApp.Shared.Application.Models;
|
|
using TIAMSharedUI.Shared;
|
|
using System.Text.RegularExpressions;
|
|
using AyCode.Core.Consts;
|
|
using TIAM.Core.Loggers;
|
|
using AyCode.Services.Loggers;
|
|
|
|
|
|
namespace TIAMSharedUI.Pages.Components
|
|
{
|
|
public partial class InputWizard : ComponentBase
|
|
{
|
|
[Inject]
|
|
public required IEnumerable<IAcLogWriterClientBase> LogWriters { get; set; }
|
|
|
|
[Inject]
|
|
IStringLocalizer<TIAMResources> localizer { get; set; }
|
|
|
|
[Inject]
|
|
public ISessionService sessionService { get; set; }
|
|
|
|
public Dictionary<int, Guid> FormSteps { get; set; } = new Dictionary<int, Guid>();
|
|
public int CurrentStep { get; set; } = 0;
|
|
|
|
//TestUserData Data { get; set; } = new TestUserData();
|
|
|
|
[Parameter]
|
|
public string TitleResourceString { get; set; } = "Wizard";
|
|
|
|
[Parameter]
|
|
public string SubtitleResourceString { get; set; } = "Let's fill in this form";
|
|
|
|
[Parameter]
|
|
public object Data { get; set; } = new object();
|
|
|
|
[Parameter]
|
|
public EventCallback<object> OnSubmit { get; set; }
|
|
|
|
[Parameter]
|
|
public string SubmitButtonText { get; set; } = "Submit";
|
|
|
|
[Required]
|
|
[Parameter]
|
|
public List<string> IgnoreReflection { get; set; }
|
|
|
|
[Parameter]
|
|
public string CssClass { get; set; } = "";
|
|
|
|
private ILogger _logger;
|
|
|
|
string _formSubmitResult = "";
|
|
private string _spinnerClass = "";
|
|
|
|
protected override async Task OnInitializedAsync()
|
|
{
|
|
_logger = new LoggerClient<InputWizard>(LogWriters.ToArray());
|
|
}
|
|
|
|
async Task HandleValidSubmit()
|
|
{
|
|
_spinnerClass = "spinner-border spinner-border-sm";
|
|
await Task.Delay(500);
|
|
|
|
var debugString = "Success: ";
|
|
|
|
var myType = Data.GetType();
|
|
IList<PropertyInfo> props = new List<PropertyInfo>(myType.GetProperties());
|
|
|
|
foreach (var prop in props)
|
|
{
|
|
var propValue = prop.GetValue(Data, null);
|
|
|
|
// Do something with propValue
|
|
debugString += $"{prop.Name} = {propValue}\n";
|
|
}
|
|
|
|
_formSubmitResult = debugString;
|
|
_spinnerClass = "";
|
|
|
|
await OnSubmit.InvokeAsync(Data);
|
|
|
|
}
|
|
void HandleInvalidSubmit()
|
|
{
|
|
_formSubmitResult = "Please correct all errors";
|
|
}
|
|
|
|
public void OnNext(MouseEventArgs args)
|
|
{
|
|
_logger.Info("OnNext called");
|
|
CurrentStep++;
|
|
}
|
|
|
|
public void OnPrevious(MouseEventArgs args)
|
|
{
|
|
_logger.Info("OnPrev called");
|
|
CurrentStep--;
|
|
}
|
|
|
|
public RenderFragment CreateEditFormFields() => formLayoutBuilder =>
|
|
{
|
|
var type = Data.GetType();
|
|
|
|
//for (var i = 0; i < 1000; i++)
|
|
_logger.Info("Hellooooo " + type.AssemblyQualifiedName);
|
|
|
|
var propertyList = type.GetProperties();
|
|
var length = propertyList.Length - IgnoreReflection.Count;
|
|
//var propertyList = typeof(TestUserData).GetProperties();
|
|
formLayoutBuilder.OpenComponent<DxFormLayout>(0);
|
|
|
|
formLayoutBuilder.AddAttribute(1, "ChildContent", (RenderFragment)((layoutItemBuilder) =>
|
|
{
|
|
var i = 0;
|
|
var k = 0;
|
|
foreach (var property in propertyList)
|
|
{
|
|
var isActive = k == CurrentStep;
|
|
//if (property.Name == "Id" || property.Name == "Latitude" || property.Name == "Longitude" || property.Name == "Created" || property.Name == "Modified")
|
|
//if (property.Name == "Id" || property.Name == "Created" || property.Name == "Modified")
|
|
if (IgnoreReflection.Contains(property.Name))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
Guid stepId;
|
|
|
|
if (!FormSteps.ContainsKey(k))
|
|
{
|
|
stepId = Guid.NewGuid();
|
|
_logger.Detail($"Adding step {k}, {stepId}, for {property.Name}");
|
|
FormSteps.Add(k, stepId);
|
|
}
|
|
else
|
|
{
|
|
stepId = FormSteps[k];
|
|
}
|
|
|
|
//the following line creates an expression that accesses the property value by name
|
|
var access = Expression.Property(Expression.Constant(Data), property.Name);
|
|
//the following line creates a lambda expression that returns the value of the property
|
|
var lambda = Expression.Lambda(typeof(Func<>).MakeGenericType(property.PropertyType), access);
|
|
|
|
_logger.Detail($"{property.Name}, {property.GetType().FullName}");
|
|
_logger.Detail(lambda.ToString());
|
|
|
|
_logger.Detail($"lambda: {lambda.ToString()}");
|
|
|
|
layoutItemBuilder.OpenElement(i++, "div");//open div
|
|
layoutItemBuilder.AddAttribute(i++, "id", stepId.ToString());
|
|
layoutItemBuilder.AddAttribute(i++, "class", "disply-flex align-items-center "+CssClass);
|
|
layoutItemBuilder.AddAttribute(i++, "style", "width: 100%;");
|
|
if (k != CurrentStep)
|
|
{
|
|
layoutItemBuilder.AddAttribute(i++, "hidden", "true");
|
|
}
|
|
else
|
|
{
|
|
//this input should be focused, so we set a flag
|
|
_logger.Detail($"Setting focus to {property.Name}");
|
|
|
|
}
|
|
|
|
var attrList = (DataTypeAttribute)property.GetCustomAttributes(typeof(DataTypeAttribute), false).First();
|
|
var displayLabel = (DisplayAttribute)property.GetCustomAttributes(typeof(DisplayAttribute), false).First();
|
|
layoutItemBuilder.OpenComponent<DxFormLayoutItem>(i++); //open dxformlayoutitem
|
|
layoutItemBuilder.AddAttribute(i++, "Caption", localizer.GetString(displayLabel.Name));
|
|
layoutItemBuilder.AddAttribute(i++, "ColSpanMd", 12);
|
|
layoutItemBuilder.AddAttribute(i++, "CaptionPosition", CaptionPosition.Vertical);
|
|
layoutItemBuilder.AddAttribute(i++, "CssClass", "justify-content-center");
|
|
|
|
layoutItemBuilder.AddAttribute(i++, "Template", (RenderFragment<object>)((context) => ((editor) =>
|
|
{
|
|
var j = 0;
|
|
switch (attrList.DataType)
|
|
{
|
|
|
|
case DataType.Text:
|
|
{
|
|
editor.OpenComponent<DxTextBox>(j++);
|
|
_logger.Detail($"{property.Name}, {property.PropertyType}");
|
|
editor.AddAttribute(j++, "Text", property.GetValue(Data));
|
|
editor.AddAttribute(j++, "TextExpression", lambda);
|
|
editor.AddAttribute(j++, "CssClass", "form-field");
|
|
|
|
if (isActive)
|
|
{
|
|
editor.AddAttribute(j++, "Id", "ActiveInput");
|
|
}
|
|
editor.AddAttribute(j++, "TextChanged", EventCallback.Factory.Create<string>(this, str => { property.SetValue(Data, str); }));
|
|
editor.CloseComponent();
|
|
|
|
break;
|
|
}
|
|
case DataType.Password:
|
|
{
|
|
|
|
editor.OpenComponent<DxTextBox>(j++);
|
|
editor.AddAttribute(j++, "Password", true);
|
|
editor.AddAttribute(j++, "NullText", "Password");
|
|
editor.AddAttribute(j++, "Text", property.GetValue(Data));
|
|
editor.AddAttribute(j++, "TextExpression", lambda);
|
|
editor.AddAttribute(j++, "TextChanged", EventCallback.Factory.Create<string>(this, str => { property.SetValue(Data, str); }));
|
|
editor.CloseComponent();
|
|
break;
|
|
}
|
|
case DataType.PhoneNumber:
|
|
{
|
|
editor.OpenComponent<DxMaskedInput<string>>(j++);
|
|
editor.AddAttribute(j++, "Value", property.GetValue(Data));
|
|
|
|
editor.AddAttribute(j++, "Mask", AcRegExpression.PhoneNumberMask);
|
|
editor.AddAttribute(j++, "MaskMode", MaskMode.RegEx);
|
|
editor.AddAttribute(j++, "BindValueMode", BindValueMode.OnInput);
|
|
editor.AddAttribute(j++, "NullText", "+11234567890");
|
|
editor.AddAttribute(j++, "MaskAutoCompleteMode", MaskAutoCompleteMode.None);
|
|
editor.AddAttribute(j++, "ValueExpression", lambda);
|
|
//editor.AddAttribute(j++, "Placeholder", "#");
|
|
//editor.AddAttribute(j++, "PlaceholdersVisible", false);
|
|
editor.AddAttribute(j++, "ValueChanged", EventCallback.Factory.Create<string>(this, str => SetPhoneNumber(property, Data, str)));
|
|
//editor.AddAttribute(j++, "TextChanged", EventCallback.Factory.Create<string>(this, str => { property.SetValue(Data, str); }));
|
|
/*editor.AddAttribute(i++, "Template", (RenderFragment<object>)((context) => ((regexProperties) =>
|
|
{
|
|
var l = 0;
|
|
regexProperties.OpenComponent<DxRegExMaskProperties>(l++);
|
|
regexProperties.AddAttribute(l++, "Placeholder", "#");
|
|
regexProperties.AddAttribute(l++, "PlaceholdersVisible", false);
|
|
regexProperties.CloseComponent();
|
|
})));*/
|
|
editor.CloseComponent();
|
|
break;
|
|
}
|
|
case DataType.EmailAddress:
|
|
{
|
|
editor.OpenComponent<DxMaskedInput<string>>(j++);
|
|
editor.AddAttribute(j++, "Value", property.GetValue(Data));
|
|
editor.AddAttribute(j++, "Mask", AcRegExpression.EmailMask);
|
|
editor.AddAttribute(j++, "MaskMode", MaskMode.RegEx);
|
|
|
|
editor.AddAttribute(j++, "BindValueMode", BindValueMode.OnInput);
|
|
//MaskAutoCompleteMode="@((MaskAutoCompleteMode)AutoCompleteMode)"
|
|
editor.AddAttribute(j++, "MaskAutoCompleteMode", MaskAutoCompleteMode.None);
|
|
editor.AddAttribute(j++, "NullText", "example@example.com");
|
|
editor.AddAttribute(j++, "ValueExpression", lambda);
|
|
|
|
editor.AddAttribute(j++, "Placeholder", "#");
|
|
editor.AddAttribute(j++, "PlaceholdersVisible", false);
|
|
|
|
editor.AddAttribute(j++, "ValueChanged", EventCallback.Factory.Create<string>(this, str => { property.SetValue(Data, str); }));
|
|
//editor.AddAttribute(j++, "Template", (RenderFragment<object>)((context) => ((editor2) =>
|
|
//{
|
|
// var l = 0;
|
|
// editor2.OpenComponent<DxRegExMaskProperties>(l++);
|
|
// editor2.AddAttribute(l++, "Placeholder", "#");
|
|
// editor2.AddAttribute(l++, "PlaceholdersVisible", "false");
|
|
// editor2.CloseComponent();
|
|
//})));
|
|
editor.CloseComponent();
|
|
break;
|
|
}
|
|
case DataType.Date:
|
|
{
|
|
editor.OpenComponent<DxDateEdit<DateTime>>(j);
|
|
editor.AddAttribute(j++, "Date", property.GetValue(Data));
|
|
editor.AddAttribute(j++, "DateExpression", lambda);
|
|
editor.AddAttribute(j++, "TimeSectionVisible", true);
|
|
editor.AddAttribute(j++, "TimeSectionScrollPickerFormat", "tt h m");
|
|
editor.AddAttribute(j++, "CssClass", "form-field");
|
|
editor.AddAttribute(j++, "DateChanged", EventCallback.Factory.Create<DateTime>(this, str => { property.SetValue(Data, str); }));
|
|
editor.CloseComponent();
|
|
break;
|
|
|
|
}
|
|
case DataType.Custom:
|
|
{
|
|
if (property.PropertyType == typeof(double))
|
|
{
|
|
|
|
editor.OpenComponent<DxMaskedInput<double>>(j);
|
|
|
|
editor.AddAttribute(j++, "Value", property.GetValue(Data));
|
|
|
|
editor.AddAttribute(j++, "Mask", "n6");
|
|
editor.AddAttribute(j++, "BindValueMode", BindValueMode.OnInput);
|
|
editor.AddAttribute(j++, "ValueExpression", lambda);
|
|
editor.AddAttribute(j++, "CssClass", "form-field");
|
|
editor.AddAttribute(j++, "ValueChanged", EventCallback.Factory.Create<double>(this, str => { property.SetValue(Data, str); }));
|
|
editor.CloseComponent();
|
|
break;
|
|
}
|
|
else if (property.PropertyType == typeof(int))
|
|
{
|
|
|
|
editor.OpenComponent<DxMaskedInput<int>>(j);
|
|
|
|
editor.AddAttribute(j++, "Value", property.GetValue(Data));
|
|
editor.AddAttribute(j++, "BindValueMode", BindValueMode.OnInput);
|
|
editor.AddAttribute(j++, "Mask", NumericMask.WholeNumber);
|
|
editor.AddAttribute(j++, "ValueExpression", lambda);
|
|
editor.AddAttribute(j++, "CssClass", "form-field");
|
|
editor.AddAttribute(j++, "ValueChanged", EventCallback.Factory.Create<int>(this, str => { property.SetValue(Data, str); }));
|
|
editor.CloseComponent();
|
|
break;
|
|
}
|
|
else if (property.PropertyType == typeof(IEnumerable<string>) && property.Name == "Occupation")
|
|
{
|
|
|
|
editor.OpenComponent<DxComboBox<string, string>>(j);
|
|
editor.AddAttribute(j++, "Data", AdditionalData.Occupations);
|
|
editor.AddAttribute(j++, "Value", property.GetValue(Data));
|
|
editor.AddAttribute(j++, "ValueExpression", lambda);
|
|
editor.AddAttribute(j++, "ValueChanged", EventCallback.Factory.Create<string>(this, str => { property.SetValue(Data, str); }));
|
|
editor.CloseComponent();
|
|
break;
|
|
}
|
|
else if (property.PropertyType == typeof(DriverModel) && property.Name == "Driver")
|
|
{
|
|
//load possible drivers for this serviceprovider
|
|
|
|
//DriverModel driver = (DriverModel)property.GetValue(Data);
|
|
IEnumerable<DriverModel> drivers = new DriverModel[] {
|
|
new DriverModel(Guid.NewGuid(), Guid.NewGuid(), "John Doe"),
|
|
new DriverModel(Guid.NewGuid(), Guid.NewGuid(), "Jane Doe"),
|
|
new DriverModel(Guid.NewGuid(), Guid.NewGuid(), "James Doe")
|
|
};
|
|
|
|
var defaultDriver = drivers.FirstOrDefault();
|
|
|
|
//editor.OpenElement(j++, "p");
|
|
//editor.AddContent(j++, localizer.GetString("Driver"));
|
|
//editor.CloseElement();
|
|
editor.OpenComponent<DxComboBox<DriverModel, DriverModel>>(j);
|
|
editor.AddAttribute(j++, "Data", drivers);
|
|
editor.AddAttribute(j++, "TextFieldName", nameof(defaultDriver.Name));
|
|
editor.AddAttribute(j++, "Value", drivers.FirstOrDefault());
|
|
//editor.AddAttribute(j++, "Text", defaultDriver);
|
|
editor.AddAttribute(j++, "CssClass", "form-field");
|
|
//editor.AddAttribute(j++, "TextExpression", lambda);
|
|
editor.AddAttribute(j++, "ValueExpression", lambda);
|
|
editor.AddAttribute(j++, "ValueChanged", EventCallback.Factory.Create<DriverModel>(this, str => { property.SetValue(Data, str); }));
|
|
editor.CloseComponent();
|
|
break;
|
|
}
|
|
//string.Compare(metadata.CustomDataType, "BoldRed", true) == 0
|
|
//else if (property.PropertyType == typeof(string) && property.Name == "Destination")
|
|
|
|
else if (property.PropertyType == typeof(string) && string.Compare(attrList.CustomDataType, "TransferDestination", true) == 0)
|
|
{
|
|
|
|
editor.OpenComponent<SliderItemSelector>(j);
|
|
editor.AddAttribute(j++, "OwlId", "owlSelector" + stepId);
|
|
editor.AddAttribute(j++, "TextValue", property.GetValue(Data));
|
|
//editor.AddAttribute(j++, "TExpression", lambda);
|
|
editor.AddAttribute(j++, "OnSliderChanged", EventCallback.Factory.Create<string>(this, result =>
|
|
{
|
|
_logger.Detail($"Slider changed to {result}");
|
|
property.SetValue(Data, result);
|
|
_logger.Detail($"bleh: {property.Name} = {property.GetValue(Data)}");
|
|
StateHasChanged(); // Add this line to refresh the UI
|
|
}));
|
|
|
|
editor.CloseComponent();
|
|
editor.OpenComponent<DxTextBox>(j++);
|
|
/*editor.AddAttribute(j++, "CssClass", "form-field");*/
|
|
editor.AddAttribute(j++, "NullText", "Slide or type");
|
|
editor.AddAttribute(j++, "Enabled", false);
|
|
editor.AddAttribute(j++, "Text", property.GetValue(Data));
|
|
editor.AddAttribute(j++, "TextExpression", lambda);
|
|
editor.AddAttribute(j++, "TextChanged", EventCallback.Factory.Create<string>(this, str =>
|
|
{
|
|
property.SetValue(Data, str);
|
|
_logger.Detail($"bleh: {property.Name} = {property.GetValue(Data)}");
|
|
}));
|
|
editor.CloseComponent();
|
|
|
|
}
|
|
|
|
else if (property.PropertyType == typeof(string) && string.Compare(attrList.CustomDataType, "FullName", true) == 0)
|
|
{
|
|
|
|
editor.OpenComponent<FullNameEditor>(j);
|
|
editor.AddAttribute(j++, "NullText", "Please tell us your name.");
|
|
editor.AddAttribute(j++, "FirstNameChanged", EventCallback.Factory.Create<string>(this, result =>
|
|
{
|
|
_logger.Detail($"FirstName changed to {result}");
|
|
|
|
//find property with name FirstName
|
|
var firstNameProperty = propertyList.FirstOrDefault(p => p.Name == "FirstName");
|
|
firstNameProperty.SetValue(Data, result);
|
|
//find property with name LastName
|
|
var lastNameProperty = propertyList.FirstOrDefault(p => p.Name == "LastName");
|
|
//combine the two values, if they are not null
|
|
if (firstNameProperty != null && lastNameProperty != null)
|
|
{
|
|
var firstName = result;
|
|
var lastName = (string)lastNameProperty.GetValue(Data);
|
|
var fullName = $"{firstName} {lastName}";
|
|
property.SetValue(Data, fullName);
|
|
}
|
|
}));
|
|
|
|
editor.AddAttribute(j++, "LastNameChanged", EventCallback.Factory.Create<string>(this, result =>
|
|
{
|
|
_logger.Detail($"LastName changed to {result}");
|
|
|
|
//find property with name FirstName
|
|
var firstNameProperty = propertyList.FirstOrDefault(p => p.Name == "FirstName");
|
|
//find property with name LastName
|
|
var lastNameProperty = propertyList.FirstOrDefault(p => p.Name == "LastName");
|
|
lastNameProperty.SetValue(Data, result);
|
|
//combine the two values, if they are not null
|
|
if (firstNameProperty != null && lastNameProperty != null)
|
|
{
|
|
var firstName = (string)firstNameProperty.GetValue(Data);
|
|
var lastName = result;
|
|
var fullName = $"{firstName} {lastName}";
|
|
property.SetValue(Data, fullName);
|
|
}
|
|
_logger.Detail($"bleh: {property.Name} = {property.GetValue(Data)}");
|
|
StateHasChanged(); // Add this line to refresh the UI
|
|
}));
|
|
|
|
editor.CloseComponent();
|
|
editor.OpenComponent<DxTextBox>(j++);
|
|
/*editor.AddAttribute(j++, "CssClass", "form-field");*/
|
|
editor.AddAttribute(j++, "NullText", "Please type in the above fields");
|
|
editor.AddAttribute(j++, "Enabled", false);
|
|
editor.AddAttribute(j++, "Text", property.GetValue(Data));
|
|
editor.AddAttribute(j++, "TextExpression", lambda);
|
|
editor.AddAttribute(j++, "TextChanged", EventCallback.Factory.Create<string>(this, str =>
|
|
{
|
|
property.SetValue(Data, str);
|
|
_logger.Detail($"bleh: {property.Name} = {property.GetValue(Data)}");
|
|
}));
|
|
editor.CloseComponent();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
case DataType.MultilineText:
|
|
{
|
|
editor.OpenComponent<DxMemo>(j);
|
|
editor.AddAttribute(j++, "Text", property.GetValue(Data));
|
|
editor.AddAttribute(j++, "TextExpression", lambda);
|
|
editor.AddAttribute(j++, "CssClass", "form-field");
|
|
editor.AddAttribute(j++, "TextChanged", EventCallback.Factory.Create<string>(this, str => { property.SetValue(Data, str); }));
|
|
editor.CloseComponent();
|
|
break;
|
|
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
})));
|
|
|
|
layoutItemBuilder.CloseComponent(); //close dxformlayoutitem
|
|
|
|
layoutItemBuilder.OpenComponent<DxButton>(i++);
|
|
layoutItemBuilder.AddAttribute(i++, "Click", EventCallback.Factory.Create<MouseEventArgs>(this, OnPrevious));
|
|
layoutItemBuilder.AddAttribute(i++, "SubmitFormOnClick", false);
|
|
layoutItemBuilder.AddAttribute(i++, "CssClass", "btn btn-secondary mt-3");
|
|
if (!(k > 0))
|
|
{
|
|
layoutItemBuilder.AddAttribute(i++, "disabled", "true");
|
|
|
|
}
|
|
layoutItemBuilder.AddAttribute(i++, "style", "margin-left: auto; width:49%");
|
|
layoutItemBuilder.AddAttribute(i++, "Text", localizer.GetString(ResourceKeys.ButtonPrevious));
|
|
layoutItemBuilder.CloseComponent();
|
|
|
|
|
|
layoutItemBuilder.OpenComponent<DxButton>(i++);
|
|
layoutItemBuilder.AddAttribute(i++, "Click", EventCallback.Factory.Create<MouseEventArgs>(this, OnNext));
|
|
layoutItemBuilder.AddAttribute(i++, "SubmitFormOnClick", false);
|
|
layoutItemBuilder.AddAttribute(i++, "CssClass", "btn btn-primary mt-3");
|
|
if (!(k < length - 1))
|
|
{
|
|
layoutItemBuilder.AddAttribute(i++, "disabled", "true");
|
|
|
|
}
|
|
|
|
layoutItemBuilder.AddAttribute(i++, "style", "margin-left: auto; width:49%");
|
|
layoutItemBuilder.AddAttribute(i++, "Text", localizer.GetString(ResourceKeys.ButtonNext));
|
|
layoutItemBuilder.CloseComponent();
|
|
|
|
layoutItemBuilder.CloseElement(); //close div
|
|
|
|
|
|
layoutItemBuilder.OpenElement(i++, "div");
|
|
layoutItemBuilder.AddAttribute(i++, "class", "text-danger");
|
|
layoutItemBuilder.OpenComponent(i++, typeof(ValidationMessage<>).MakeGenericType(property.PropertyType));
|
|
layoutItemBuilder.AddAttribute(i++, "For", lambda);
|
|
layoutItemBuilder.CloseComponent();
|
|
layoutItemBuilder.CloseElement();
|
|
|
|
|
|
_logger.Detail($"loop {k}, length: {length}, formSteps: {FormSteps.Count} ");
|
|
k++;
|
|
|
|
}
|
|
layoutItemBuilder.OpenComponent<DxFormLayoutItem>(i++);
|
|
layoutItemBuilder.AddAttribute(i++, "ColSpanMd", 12);
|
|
layoutItemBuilder.AddAttribute(i++, "CssClass", "full-width justify-content-center");
|
|
layoutItemBuilder.AddAttribute(i++, "Template", (RenderFragment<object>)((context) => ((editor) =>
|
|
{
|
|
_logger.Detail($"Submit button {CurrentStep}, {FormSteps.Count}");
|
|
|
|
editor.OpenElement(i++, "button");
|
|
editor.AddAttribute(i++, "type", "submit");
|
|
editor.AddAttribute(i++, "class", "btn btn-primary mt-3 w-100");
|
|
editor.AddAttribute(i++, "style", "margin: 0 auto");
|
|
if (CurrentStep < length - 1)
|
|
{
|
|
editor.AddAttribute(i++, "disabled", "true");
|
|
|
|
}
|
|
//editor.AddAttribute(i++, "disabled", "true");
|
|
|
|
editor.OpenElement(i++, "span");
|
|
editor.AddAttribute(i++, "class", _spinnerClass);
|
|
|
|
editor.CloseElement();
|
|
editor.AddContent(i++, localizer.GetString(SubmitButtonText));
|
|
editor.CloseElement();
|
|
|
|
/*editor.OpenComponent<DxButton>(i++);
|
|
editor.AddAttribute(i++, "SubmitFormOnClick", true);
|
|
editor.AddAttribute(i++, "Text", SubmitButtonText);
|
|
editor.AddAttribute(i++, "IconClass", _spinnerClass);
|
|
editor.AddAttribute(i++, "CssClass", "btn btn-primary mt-3");
|
|
if (CurrentStep == propertyList.Length-1)
|
|
{
|
|
editor.AddAttribute(i++, "Visible", true);
|
|
}
|
|
else
|
|
{
|
|
editor.AddAttribute(i++, "Visible", false);
|
|
}
|
|
editor.CloseComponent();*/
|
|
})));
|
|
|
|
layoutItemBuilder.CloseComponent();
|
|
}));
|
|
formLayoutBuilder.CloseComponent();
|
|
};
|
|
|
|
private void SetPhoneNumber(PropertyInfo property, object Data, string str)
|
|
{
|
|
_logger.Info($"SetPhoneNumber called with {str}");
|
|
property.SetValue(Data, str);
|
|
}
|
|
}
|
|
|
|
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false)]
|
|
public class MinPasswordLengthAttribute : ValidationAttribute
|
|
{
|
|
private int MinLength { get; }
|
|
|
|
public MinPasswordLengthAttribute(int minLength, string errorMsg) : base(errorMsg)
|
|
{
|
|
MinLength = minLength;
|
|
}
|
|
|
|
public override bool IsValid(object value)
|
|
{
|
|
return ((string)value).Length >= MinLength;
|
|
}
|
|
}
|
|
|
|
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false)]
|
|
public class EmailAttribute : ValidationAttribute
|
|
{
|
|
public override bool IsValid(object value)
|
|
{
|
|
return Regex.IsMatch((string)value, @"^[\w!#$%&'*+\-/=?\^_`{|}~]+(\.[\w!#$%&'*+\-/=?\^_`{|}~]+)*"
|
|
+ "@"
|
|
+ @"((([\-\w]+\.)+[a-zA-Z]{2,4})|(([0-9]{1,3}\.){3}[0-9]{1,3}))$");
|
|
}
|
|
}
|
|
|
|
|
|
|
|
}
|