Forms: Add multiline input (#4942)

This commit is contained in:
d11n
2023-05-10 11:14:19 +02:00
committed by GitHub
parent 99bcec5597
commit 2c26b77afc
8 changed files with 90 additions and 27 deletions

View File

@@ -0,0 +1,26 @@
using System.Collections.Generic;
using BTCPayServer.Abstractions.Form;
namespace BTCPayServer.Forms;
public class FieldValueMirror : IFormComponentProvider
{
public string View { get; } = null;
public void Validate(Form form, Field field)
{
if (form.GetFieldByFullName(field.Value) is null)
{
field.ValidationErrors = new List<string> { $"{field.Name} requires {field.Value} to be present" };
}
}
public void Register(Dictionary<string, IFormComponentProvider> typeToComponentProvider)
{
typeToComponentProvider.Add("mirror", this);
}
public string GetValue(Form form, Field field)
{
return form.GetFieldByFullName(field.Value)?.Value;
}
}

View File

@@ -12,6 +12,7 @@ public static class FormDataExtensions
serviceCollection.AddSingleton<FormDataService>();
serviceCollection.AddSingleton<FormComponentProviders>();
serviceCollection.AddSingleton<IFormComponentProvider, HtmlInputFormProvider>();
serviceCollection.AddSingleton<IFormComponentProvider, HtmlTextareaFormProvider>();
serviceCollection.AddSingleton<IFormComponentProvider, HtmlFieldsetFormProvider>();
serviceCollection.AddSingleton<IFormComponentProvider, HtmlSelectFormProvider>();
serviceCollection.AddSingleton<IFormComponentProvider, FieldValueMirror>();

View File

@@ -5,27 +5,6 @@ using BTCPayServer.Validation;
namespace BTCPayServer.Forms;
public class FieldValueMirror : IFormComponentProvider
{
public string View { get; } = null;
public void Validate(Form form, Field field)
{
if (form.GetFieldByFullName(field.Value) is null)
{
field.ValidationErrors = new List<string>() { $"{field.Name} requires {field.Value} to be present" };
}
}
public void Register(Dictionary<string, IFormComponentProvider> typeToComponentProvider)
{
typeToComponentProvider.Add("mirror", this);
}
public string GetValue(Form form, Field field)
{
return form.GetFieldByFullName(field.Value)?.Value;
}
}
public class HtmlInputFormProvider : FormComponentProviderBase
{
public override void Register(Dictionary<string, IFormComponentProvider> typeToComponentProvider)

View File

@@ -9,10 +9,9 @@ public class HtmlSelectFormProvider : FormComponentProviderBase
{
public override void Register(Dictionary<string, IFormComponentProvider> typeToComponentProvider)
{
foreach (var t in new[] {
"select"})
typeToComponentProvider.Add(t, this);
typeToComponentProvider.Add("select", this);
}
public override string View => "Forms/SelectElement";
public override void Validate(Form form, Field field)

View File

@@ -0,0 +1,23 @@
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using BTCPayServer.Abstractions.Form;
namespace BTCPayServer.Forms;
public class HtmlTextareaFormProvider : FormComponentProviderBase
{
public override void Register(Dictionary<string, IFormComponentProvider> typeToComponentProvider)
{
typeToComponentProvider.Add("textarea", this);
}
public override string View => "Forms/TextareaElement";
public override void Validate(Form form, Field field)
{
if (field.Required)
{
ValidateField<RequiredAttribute>(field);
}
}
}

View File

@@ -0,0 +1,28 @@
@model BTCPayServer.Abstractions.Form.Field
@{
var isInvalid = ViewContext.ModelState[Model.Name]?.ValidationState is Microsoft.AspNetCore.Mvc.ModelBinding.ModelValidationState.Invalid;
var errors = isInvalid ? ViewContext.ModelState[Model.Name].Errors : null;
}
<div class="form-group">
<label class="form-label" for="@Model.Name"@(Model.Required ? " data-required" : "")>
@Model.Label
</label>
<textarea id="@Model.Name" class="form-control @(errors is null ? "" : "is-invalid")"
name="@Model.Name" data-val="true"
@if (!string.IsNullOrEmpty(Model.HelpText))
{
@Safe.Raw($" aria-describedby=\"HelpText-{Model.Name}\"")
}
@if (Model.Required)
{
@Safe.Raw($" data-val-required=\"{Model.Label} is required.\" required")
}
>@Model.Value</textarea>
<span class="text-danger" data-valmsg-for="@Model.Name" data-valmsg-replace="true">@(isInvalid && errors.Any() ? errors.First().ErrorMessage : string.Empty)</span>
@if (!string.IsNullOrEmpty(Model.HelpText))
{
<div id="@($"HelpText-{Model.Name}")" class="form-text">
@Safe.Raw(Model.HelpText)
</div>
}
</div>

View File

@@ -1,3 +1,5 @@
@using System.Text.RegularExpressions
@using Microsoft.AspNetCore.Mvc.TagHelpers
@model (Dictionary<string, object> Items, int Level)
@functions {
@@ -22,14 +24,14 @@
{
<th class="w-150px">@key</th>
}
<td>
<td style="white-space:pre-wrap">
@if (IsValidURL(str))
{
<a href="@str" target="_blank" rel="noreferrer noopener">@str</a>
}
else
{
@value?.ToString()
@str.Trim()
}
</td>
}

View File

@@ -39,7 +39,12 @@
<div class="row">
<div class="col-xl-10 col-xxl-constrain">
<div class="d-flex align-items-center justify-content-between mb-3">
<h3 class="mb-0">@ViewData["Title"]</h3>
<h3 class="mb-0">
<span>@ViewData["Title"]</span>
<a href="https://docs.btcpayserver.org/Forms" target="_blank" rel="noreferrer noopener" title="More information...">
<vc:icon symbol="info" />
</a>
</h3>
<div class="d-flex gap-3 mt-3 mt-sm-0">
<button type="submit" class="btn btn-primary order-sm-1" id="SaveButton">Save</button>
@if (!isNew)