Sharpening up everything!
This commit is contained in:
@@ -4,5 +4,4 @@ public static class ContentTypes
|
|||||||
public const string OapApplication = nameof(OapApplication);
|
public const string OapApplication = nameof(OapApplication);
|
||||||
public const string OapApplicationForm = nameof(OapApplicationForm);
|
public const string OapApplicationForm = nameof(OapApplicationForm);
|
||||||
public const string OapApplicationFormStep = nameof(OapApplicationFormStep);
|
public const string OapApplicationFormStep = nameof(OapApplicationFormStep);
|
||||||
public const string OapExplanation = nameof(OapExplanation);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using Oap.OapApplication;
|
using Oap.OapApplication;
|
||||||
using Oap.OapExplanation;
|
|
||||||
using OrchardCore.Autoroute.Models;
|
using OrchardCore.Autoroute.Models;
|
||||||
using OrchardCore.ContentFields.Fields;
|
using OrchardCore.ContentFields.Fields;
|
||||||
using OrchardCore.ContentFields.Settings;
|
using OrchardCore.ContentFields.Settings;
|
||||||
@@ -7,6 +6,7 @@ using OrchardCore.ContentManagement.Metadata;
|
|||||||
using OrchardCore.ContentManagement.Metadata.Settings;
|
using OrchardCore.ContentManagement.Metadata.Settings;
|
||||||
using OrchardCore.Data.Migration;
|
using OrchardCore.Data.Migration;
|
||||||
using OrchardCore.Flows.Models;
|
using OrchardCore.Flows.Models;
|
||||||
|
using OrchardCore.Forms.Models;
|
||||||
using OrchardCore.Html.Models;
|
using OrchardCore.Html.Models;
|
||||||
using OrchardCore.Html.Settings;
|
using OrchardCore.Html.Settings;
|
||||||
using OrchardCore.Lists.Models;
|
using OrchardCore.Lists.Models;
|
||||||
@@ -115,40 +115,128 @@ public class Migrations : DataMigration
|
|||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<int> UpdateFrom2Async()
|
public Task<int> UpdateFrom2Async()
|
||||||
{
|
{
|
||||||
await m_contentDefinitionManager
|
return Task.FromResult(3);
|
||||||
.AlterPartDefinitionAsync(nameof(OapExplanationPart), part => part
|
|
||||||
.Attachable());
|
|
||||||
|
|
||||||
await m_contentDefinitionManager
|
|
||||||
.AlterTypeDefinitionAsync(ContentTypes.OapExplanation, type => type
|
|
||||||
.WithPart<OapExplanationPart>()
|
|
||||||
.Stereotype("Widget"));
|
|
||||||
|
|
||||||
return 3;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<int> UpdateFrom3Async()
|
public Task<int> UpdateFrom3Async()
|
||||||
{
|
{
|
||||||
await m_contentDefinitionManager
|
return Task.FromResult(4);
|
||||||
.AlterPartDefinitionAsync(nameof(OapExplanationPart), part => part
|
|
||||||
.WithField(nameof(OapExplanationPart.Text), field => field
|
|
||||||
.OfType(nameof(HtmlField))
|
|
||||||
.WithDisplayName(nameof(OapExplanationPart.Text))
|
|
||||||
.WithDescription("A detailed explanation of a field.")));
|
|
||||||
|
|
||||||
return 4;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<int> UpdateFrom4Async()
|
public Task<int> UpdateFrom4Async()
|
||||||
|
{
|
||||||
|
return Task.FromResult(5);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<int> UpdateFrom5Async()
|
||||||
|
{
|
||||||
|
return Task.FromResult(6);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<int> UpdateFrom6Async()
|
||||||
{
|
{
|
||||||
await m_contentDefinitionManager
|
await m_contentDefinitionManager
|
||||||
.AlterPartDefinitionAsync(nameof(OapExplanationPart), part => part
|
.AlterTypeDefinitionAsync(ContentTypes.OapApplicationForm, type => type
|
||||||
.WithField(nameof(OapExplanationPart.Text), field => field
|
.WithPart(nameof(TitlePart)));
|
||||||
.WithSettings(new ContentPartFieldSettings { Editor = "Wysiwyg" })));
|
|
||||||
|
|
||||||
return 5;
|
return 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<int> UpdateFrom7Async()
|
||||||
|
{
|
||||||
|
await m_contentDefinitionManager
|
||||||
|
.AlterTypeDefinitionAsync("Input", type => type
|
||||||
|
.WithPart("Explanation", "HtmlBodyPart", part => part
|
||||||
|
.WithPosition("1")
|
||||||
|
.WithDisplayName("Details to help the user correctly fill out this form field.")
|
||||||
|
.WithEditor("Wysiwyg")
|
||||||
|
));
|
||||||
|
|
||||||
|
await m_contentDefinitionManager
|
||||||
|
.AlterTypeDefinitionAsync("TextArea", type => type
|
||||||
|
.WithPart("Explanation", "HtmlBodyPart", part => part
|
||||||
|
.WithPosition("1")
|
||||||
|
.WithDisplayName("Details to help the user correctly fill out this form field.")
|
||||||
|
.WithEditor("Wysiwyg")
|
||||||
|
));
|
||||||
|
|
||||||
|
await m_contentDefinitionManager
|
||||||
|
.AlterTypeDefinitionAsync("Select", type => type
|
||||||
|
.WithPart("Explanation", "HtmlBodyPart", part => part
|
||||||
|
.WithPosition("1")
|
||||||
|
.WithDisplayName("Details to help the user correctly fill out this form field.")
|
||||||
|
.WithEditor("Wysiwyg")
|
||||||
|
));
|
||||||
|
|
||||||
|
return 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<int> UpdateFrom8Async()
|
||||||
|
{
|
||||||
|
await m_contentDefinitionManager
|
||||||
|
.AlterTypeDefinitionAsync("Input", type => type
|
||||||
|
.WithPart("Explanation", "HtmlBodyPart", part => part
|
||||||
|
.WithPosition("4")
|
||||||
|
)
|
||||||
|
.WithPart("InputPart", part => part
|
||||||
|
.WithPosition("5")
|
||||||
|
)
|
||||||
|
.WithPart("FormElementValidationPart", part => part
|
||||||
|
.WithPosition("6")
|
||||||
|
));
|
||||||
|
|
||||||
|
await m_contentDefinitionManager
|
||||||
|
.AlterTypeDefinitionAsync("TextArea", type => type
|
||||||
|
.WithPart("Explanation", "HtmlBodyPart", part => part
|
||||||
|
.WithPosition("4")
|
||||||
|
)
|
||||||
|
.WithPart("TextAreaPart", part => part
|
||||||
|
.WithPosition("5")
|
||||||
|
)
|
||||||
|
.WithPart("FormElementValidationPart", part => part
|
||||||
|
.WithPosition("6")
|
||||||
|
));
|
||||||
|
|
||||||
|
await m_contentDefinitionManager
|
||||||
|
.AlterTypeDefinitionAsync("Select", type => type
|
||||||
|
.WithPart("Explanation", "HtmlBodyPart", part => part
|
||||||
|
.WithPosition("4")
|
||||||
|
)
|
||||||
|
.WithPart("SelectPart", part => part
|
||||||
|
.WithPosition("5")
|
||||||
|
)
|
||||||
|
.WithPart("FormElementValidationPart", part => part
|
||||||
|
.WithPosition("6")
|
||||||
|
));
|
||||||
|
|
||||||
|
return 9;
|
||||||
|
}
|
||||||
|
public async Task<int> UpdateFrom9Async()
|
||||||
|
{
|
||||||
|
await m_contentDefinitionManager
|
||||||
|
.AlterTypeDefinitionAsync("Input", type => type
|
||||||
|
.WithPart("Explanation", "HtmlBodyPart", part => part
|
||||||
|
.WithDisplayName("Explanation")
|
||||||
|
.WithDescription("Details to help the user correctly fill out this form field.")
|
||||||
|
));
|
||||||
|
|
||||||
|
await m_contentDefinitionManager
|
||||||
|
.AlterTypeDefinitionAsync("TextArea", type => type
|
||||||
|
.WithPart("Explanation", "HtmlBodyPart", part => part
|
||||||
|
.WithDisplayName("Explanation")
|
||||||
|
.WithDescription("Details to help the user correctly fill out this form field.")
|
||||||
|
));
|
||||||
|
|
||||||
|
await m_contentDefinitionManager
|
||||||
|
.AlterTypeDefinitionAsync("Select", type => type
|
||||||
|
.WithPart("Explanation", "HtmlBodyPart", part => part
|
||||||
|
.WithDisplayName("Explanation")
|
||||||
|
.WithDescription("Details to help the user correctly fill out this form field.")
|
||||||
|
));
|
||||||
|
|
||||||
|
return 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly IContentDefinitionManager m_contentDefinitionManager;
|
private readonly IContentDefinitionManager m_contentDefinitionManager;
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ using Microsoft.AspNetCore.Builder;
|
|||||||
using Microsoft.AspNetCore.Routing;
|
using Microsoft.AspNetCore.Routing;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Oap.OapApplication;
|
using Oap.OapApplication;
|
||||||
using Oap.OapExplanation;
|
|
||||||
using OrchardCore.ContentManagement;
|
using OrchardCore.ContentManagement;
|
||||||
using OrchardCore.Data.Migration;
|
using OrchardCore.Data.Migration;
|
||||||
|
|
||||||
@@ -13,7 +12,6 @@ public class Startup : OrchardCore.Modules.StartupBase
|
|||||||
public override void ConfigureServices(IServiceCollection services)
|
public override void ConfigureServices(IServiceCollection services)
|
||||||
{
|
{
|
||||||
services.AddContentPart<OapApplicationPart>();
|
services.AddContentPart<OapApplicationPart>();
|
||||||
services.AddContentPart<OapExplanationPart>();
|
|
||||||
|
|
||||||
services.AddDataMigration<Migrations>();
|
services.AddDataMigration<Migrations>();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
<h1 class="mb-6 border-b-2 border-solid border-black pb-1 text-center text-2xl font-bold">
|
||||||
|
@Model.Header.TitlePart.Title
|
||||||
|
</h1>
|
||||||
|
|
||||||
|
@await DisplayAsync(Model.Content)
|
||||||
@@ -1,20 +1,9 @@
|
|||||||
<h1 class="mb-6 border-b-2 border-solid border-black pb-1 text-center text-2xl font-bold">
|
<div>
|
||||||
Form Title
|
<h2 class="text-lg font-bold">
|
||||||
</h1>
|
@Model.Header.TitlePart.Title
|
||||||
|
</h2>
|
||||||
<div class="flex flex-row gap-x-4">
|
|
||||||
<aside class="h-full min-h-full">
|
@await DisplayAsync(Model.Content.HtmlBodyPart)
|
||||||
<menu alias="alias:application-steps-menu" cache-id="application-steps-menu" cache-fixed-duration="00:05:00" cache-tag="alias:application-steps-menu" />
|
|
||||||
</aside>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<h2 class="text-lg font-bold">
|
|
||||||
@Model.Header.TitlePart.Title
|
|
||||||
</h2>
|
|
||||||
|
|
||||||
@await DisplayAsync(Model.Content.HtmlBodyPart)
|
|
||||||
|
|
||||||
@await DisplayAsync(Model.Content.FlowPart)
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
@await DisplayAsync(Model.Content.FlowPart)
|
||||||
</div>
|
</div>
|
||||||
19
src/OAP/Oap.Theme/Views/FormElementLabelPart.cshtml
Normal file
19
src/OAP/Oap.Theme/Views/FormElementLabelPart.cshtml
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
@using OrchardCore.Forms.ViewModels
|
||||||
|
@using OrchardCore.Forms.Models
|
||||||
|
@model ShapeViewModel<FormElementLabelPart>
|
||||||
|
@{
|
||||||
|
var formElementPart = Model.Value.ContentItem.As<FormElementPart>();
|
||||||
|
var formInputElementPart = Model.Value.ContentItem.As<FormInputElementPart>();
|
||||||
|
var elementId = formElementPart.Id;
|
||||||
|
var fieldName = formInputElementPart.Name;
|
||||||
|
var fieldId = !string.IsNullOrEmpty(elementId) ? elementId : !string.IsNullOrEmpty(fieldName) ? Html.GenerateIdFromName(fieldName) : default(string);
|
||||||
|
}
|
||||||
|
|
||||||
|
@if (Model.Value.Option == LabelOptions.Standard)
|
||||||
|
{
|
||||||
|
<label for="@fieldId" class="block font-bold text-gray-900">@Model.Value.Label</label>
|
||||||
|
}
|
||||||
|
else if (Model.Value.Option == LabelOptions.ScreenReaders)
|
||||||
|
{
|
||||||
|
<label for="@fieldId" class="sr-only">@Model.Value.Label</label>
|
||||||
|
}
|
||||||
7
src/OAP/Oap.Theme/Views/Input-HtmlBodyPart.cshtml
Normal file
7
src/OAP/Oap.Theme/Views/Input-HtmlBodyPart.cshtml
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
@model OrchardCore.Html.ViewModels.HtmlBodyPartViewModel
|
||||||
|
|
||||||
|
<div class="mt-1 text-sm leading-6 text-gray-600">
|
||||||
|
<div class="richtext">
|
||||||
|
@Html.Raw(Model.Html)
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
40
src/OAP/Oap.Theme/Views/InputPart.cshtml
Normal file
40
src/OAP/Oap.Theme/Views/InputPart.cshtml
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
@using OrchardCore.Forms.Models
|
||||||
|
@model ShapeViewModel<InputPart>
|
||||||
|
@{
|
||||||
|
var formElementPart = Model.Value.ContentItem.As<FormElementPart>();
|
||||||
|
var formInputElementPart = Model.Value.ContentItem.As<FormInputElementPart>();
|
||||||
|
var elementId = formElementPart.Id;
|
||||||
|
var fieldName = formInputElementPart.Name;
|
||||||
|
var fieldId = !string.IsNullOrEmpty(elementId) ? elementId : !string.IsNullOrEmpty(fieldName) ? Html.GenerateIdFromName(fieldName) : default(string);
|
||||||
|
var fieldValue = Model.Value.DefaultValue;
|
||||||
|
var fieldClass = "";
|
||||||
|
var isChecked = false;
|
||||||
|
|
||||||
|
if (Model.Value.Type == "text")
|
||||||
|
{
|
||||||
|
fieldClass = "block w-full rounded-md border-0 py-1.5 px-2 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600";
|
||||||
|
}
|
||||||
|
else if (Model.Value.Type == "number" || Model.Value.Type == "date")
|
||||||
|
{
|
||||||
|
fieldClass = "block w-1/3 rounded-md border-0 py-1.5 px-2 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ViewData.ModelState.TryGetValue(fieldName, out var fieldEntry))
|
||||||
|
{
|
||||||
|
if (Model.Value.Type == "checkbox")
|
||||||
|
{
|
||||||
|
isChecked = fieldEntry.AttemptedValue == fieldValue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fieldValue = fieldEntry.AttemptedValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fieldEntry.Errors.Count > 0)
|
||||||
|
{
|
||||||
|
fieldClass += " input-validation-error is-invalid";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
<input id="@fieldId" name="@fieldName" type="@Model.Value.Type" class="@fieldClass" value="@fieldValue" placeholder="@Model.Value.Placeholder" @(isChecked ? "checked" : "") />
|
||||||
15
src/OAP/Oap.Theme/Views/OapApplicationForm-ListPart.cshtml
Normal file
15
src/OAP/Oap.Theme/Views/OapApplicationForm-ListPart.cshtml
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
@model OrchardCore.Lists.ViewModels.ListPartViewModel
|
||||||
|
@inject OrchardCore.ContentManagement.Display.IContentItemDisplayManager ContentItemDisplayManager
|
||||||
|
|
||||||
|
<div class="flex flex-col gap-x-4">
|
||||||
|
@foreach (var step in Model.ContentItems)
|
||||||
|
{
|
||||||
|
var stepContent = await ContentItemDisplayManager.BuildDisplayAsync(
|
||||||
|
step,
|
||||||
|
Model.Context.Updater,
|
||||||
|
Model.Context.DisplayType,
|
||||||
|
Model.Context.GroupId);
|
||||||
|
|
||||||
|
@await DisplayAsync(stepContent)
|
||||||
|
}
|
||||||
|
</div>
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
<p class="pl-4 my-2 text-sm text-gray-500">
|
|
||||||
@Html.Raw(Model.Html)
|
|
||||||
</p>
|
|
||||||
23
src/OAP/Oap.Theme/Views/Select-FormElementLabelPart.cshtml
Normal file
23
src/OAP/Oap.Theme/Views/Select-FormElementLabelPart.cshtml
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
@using OrchardCore.Forms.ViewModels
|
||||||
|
@using OrchardCore.Forms.Models
|
||||||
|
@model ShapeViewModel<FormElementLabelPart>
|
||||||
|
@{
|
||||||
|
var formElementPart = Model.Value.ContentItem.As<FormElementPart>();
|
||||||
|
var formInputElementPart = Model.Value.ContentItem.As<FormInputElementPart>();
|
||||||
|
var elementId = formElementPart.Id;
|
||||||
|
var fieldName = formInputElementPart.Name;
|
||||||
|
var fieldId = !string.IsNullOrEmpty(elementId) ? elementId : !string.IsNullOrEmpty(fieldName) ? Html.GenerateIdFromName(fieldName) : default(string);
|
||||||
|
}
|
||||||
|
|
||||||
|
@if (Model.Value.Option == LabelOptions.Standard)
|
||||||
|
{
|
||||||
|
<legend class="font-bold text-gray-900">
|
||||||
|
@Model.Value.Label
|
||||||
|
</legend>
|
||||||
|
}
|
||||||
|
else if (Model.Value.Option == LabelOptions.ScreenReaders)
|
||||||
|
{
|
||||||
|
<legend class="sr-only">
|
||||||
|
@Model.Value.Label
|
||||||
|
</legend>
|
||||||
|
}
|
||||||
7
src/OAP/Oap.Theme/Views/Select-HtmlBodyPart.cshtml
Normal file
7
src/OAP/Oap.Theme/Views/Select-HtmlBodyPart.cshtml
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
@model OrchardCore.Html.ViewModels.HtmlBodyPartViewModel
|
||||||
|
|
||||||
|
<div class="mt-1 text-sm leading-6 text-gray-600">
|
||||||
|
<div class="richtext">
|
||||||
|
@Html.Raw(Model.Html)
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
53
src/OAP/Oap.Theme/Views/SelectPart.cshtml
Normal file
53
src/OAP/Oap.Theme/Views/SelectPart.cshtml
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
@using OrchardCore.Forms.Models
|
||||||
|
@model ShapeViewModel<SelectPart>
|
||||||
|
@{
|
||||||
|
var formElementPart = Model.Value.ContentItem.As<FormElementPart>();
|
||||||
|
var formInputElementPart = Model.Value.ContentItem.As<FormInputElementPart>();
|
||||||
|
var elementId = formElementPart.Id;
|
||||||
|
var fieldName = formInputElementPart.Name;
|
||||||
|
var fieldId = !string.IsNullOrEmpty(elementId) ? elementId : !string.IsNullOrEmpty(fieldName) ?
|
||||||
|
Html.GenerateIdFromName(fieldName) : default(string);
|
||||||
|
var fieldValue = Model.Value.DefaultValue;
|
||||||
|
var validationClass = "";
|
||||||
|
|
||||||
|
if (ViewData.ModelState.TryGetValue(fieldName, out var fieldEntry))
|
||||||
|
{
|
||||||
|
fieldValue = fieldEntry.AttemptedValue;
|
||||||
|
if (fieldEntry.Errors.Count > 0)
|
||||||
|
{
|
||||||
|
validationClass += " input-validation-error is-invalid"; // TODO: use validation classes from tailwind!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@if (Model.Value.Editor == SelectEditorOption.Checkbox || Model.Value.Editor == SelectEditorOption.Radio)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
var htmlType = Model.Value.Editor == SelectEditorOption.Checkbox ? "checkbox" : "radio";
|
||||||
|
<div class="mt-2 space-y-2">
|
||||||
|
@foreach (var option in Model.Value.Options)
|
||||||
|
{
|
||||||
|
<div class="flex items-center gap-x-3">
|
||||||
|
<input type="@htmlType" id="@(fieldId + "_" + i)" name="@fieldName"
|
||||||
|
class="@validationClass h-4 w-4 border-gray-300 text-indigo-600 focus:ring-indigo-600"
|
||||||
|
value="@option.Value" @(option.Value == fieldValue ? "checked='checked'" : "") />
|
||||||
|
<label class="block text-sm font-medium text-gray-900" for="@(fieldId + "_" + i)">@option.Text</label>
|
||||||
|
</div>
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<div class="mt-2">
|
||||||
|
<select id="@fieldId" name="@fieldName"
|
||||||
|
class="@validationClass block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:max-w-xs sm:text-sm sm:leading-6">
|
||||||
|
@foreach (var option in Model.Value.Options)
|
||||||
|
{
|
||||||
|
var optionValue = !string.IsNullOrWhiteSpace(option.Value) ? option.Value : option.Text;
|
||||||
|
var isOptionSelected = optionValue == fieldValue;
|
||||||
|
<option value="@optionValue" selected="@isOptionSelected">@option.Text</option>
|
||||||
|
}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
7
src/OAP/Oap.Theme/Views/TextArea-HtmlBodyPart.cshtml
Normal file
7
src/OAP/Oap.Theme/Views/TextArea-HtmlBodyPart.cshtml
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
@model OrchardCore.Html.ViewModels.HtmlBodyPartViewModel
|
||||||
|
|
||||||
|
<div class="mt-1 text-sm leading-6 text-gray-600">
|
||||||
|
<div class="richtext">
|
||||||
|
@Html.Raw(Model.Html)
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
21
src/OAP/Oap.Theme/Views/TextAreaPart.cshtml
Normal file
21
src/OAP/Oap.Theme/Views/TextAreaPart.cshtml
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
@using OrchardCore.Forms.Models
|
||||||
|
@model ShapeViewModel<TextAreaPart>
|
||||||
|
@{
|
||||||
|
var formElementPart = Model.Value.ContentItem.As<FormElementPart>();
|
||||||
|
var formInputElementPart = Model.Value.ContentItem.As<FormInputElementPart>();
|
||||||
|
var elementId = formElementPart.Id;
|
||||||
|
var fieldName = formInputElementPart.Name;
|
||||||
|
var fieldId = !string.IsNullOrEmpty(elementId) ? elementId : !string.IsNullOrEmpty(fieldName) ? Html.GenerateIdFromName(fieldName) : default(string);
|
||||||
|
var fieldValue = Model.Value.DefaultValue?.Trim();
|
||||||
|
var fieldClass = "block w-full rounded-md border-0 py-1.5 px-2 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600";
|
||||||
|
|
||||||
|
if (ViewData.ModelState.TryGetValue(fieldName, out var fieldEntry))
|
||||||
|
{
|
||||||
|
fieldValue = fieldEntry.AttemptedValue;
|
||||||
|
if (fieldEntry.Errors.Count > 0)
|
||||||
|
{
|
||||||
|
fieldClass = "form-control input-validation-error is-invalid";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
<textarea id="@fieldId" name="@fieldName" class="@fieldClass" placeholder="@Model.Value.Placeholder">@fieldValue</textarea>
|
||||||
@@ -1,3 +1,3 @@
|
|||||||
<div class="flex flex-col gap-4">
|
<div class="flex flex-col gap-6">
|
||||||
@await DisplayAsync(Model.Content)
|
@await DisplayAsync(Model.Content)
|
||||||
</div>
|
</div>
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
<div class="grid grid-cols-2">
|
<div>
|
||||||
@await DisplayAsync(Model.Content)
|
@await DisplayAsync(Model.Content.FormElementLabelPart)
|
||||||
|
@await DisplayAsync(Model.Content.Explanation)
|
||||||
|
@await DisplayAsync(Model.Content.InputPart)
|
||||||
</div>
|
</div>
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
<div>
|
|
||||||
@await DisplayAsync(Model.Content)
|
|
||||||
</div>
|
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
<div class="flex flex-col">
|
<fieldset>
|
||||||
@await DisplayAsync(Model.Content)
|
@await DisplayAsync(Model.Content.FormElementLabelPart)
|
||||||
</div>
|
@await DisplayAsync(Model.Content.Explanation)
|
||||||
|
@await DisplayAsync(Model.Content.SelectPart)
|
||||||
|
</fieldset>
|
||||||
5
src/OAP/Oap.Theme/Views/Widget-TextArea.cshtml
Normal file
5
src/OAP/Oap.Theme/Views/Widget-TextArea.cshtml
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
<div>
|
||||||
|
@await DisplayAsync(Model.Content.FormElementLabelPart)
|
||||||
|
@await DisplayAsync(Model.Content.Explanation)
|
||||||
|
@await DisplayAsync(Model.Content.TextAreaPart)
|
||||||
|
</div>
|
||||||
@@ -12,3 +12,4 @@
|
|||||||
@using OrchardCore.ContentManagement
|
@using OrchardCore.ContentManagement
|
||||||
@using OrchardCore.ContentManagement.Routing
|
@using OrchardCore.ContentManagement.Routing
|
||||||
@using OrchardCore.Menu.Models
|
@using OrchardCore.Menu.Models
|
||||||
|
@using OrchardCore.DisplayManagement.Views
|
||||||
|
|||||||
@@ -547,14 +547,16 @@ span.field-validation-error {
|
|||||||
--tw-text-opacity: 1;
|
--tw-text-opacity: 1;
|
||||||
color: rgb(220 38 38 / var(--tw-text-opacity));
|
color: rgb(220 38 38 / var(--tw-text-opacity));
|
||||||
}
|
}
|
||||||
.relative {
|
.sr-only {
|
||||||
position: relative;
|
position: absolute;
|
||||||
}
|
width: 1px;
|
||||||
.right-\[-px\] {
|
height: 1px;
|
||||||
right: -px;
|
padding: 0;
|
||||||
}
|
margin: -1px;
|
||||||
.z-50 {
|
overflow: hidden;
|
||||||
z-index: 50;
|
clip: rect(0, 0, 0, 0);
|
||||||
|
white-space: nowrap;
|
||||||
|
border-width: 0;
|
||||||
}
|
}
|
||||||
.mx-auto {
|
.mx-auto {
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
@@ -571,6 +573,15 @@ span.field-validation-error {
|
|||||||
.mb-6 {
|
.mb-6 {
|
||||||
margin-bottom: 1.5rem;
|
margin-bottom: 1.5rem;
|
||||||
}
|
}
|
||||||
|
.mt-1 {
|
||||||
|
margin-top: 0.25rem;
|
||||||
|
}
|
||||||
|
.mt-2 {
|
||||||
|
margin-top: 0.5rem;
|
||||||
|
}
|
||||||
|
.mt-6 {
|
||||||
|
margin-top: 1.5rem;
|
||||||
|
}
|
||||||
.block {
|
.block {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
@@ -589,9 +600,21 @@ span.field-validation-error {
|
|||||||
.h-full {
|
.h-full {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
.h-4 {
|
||||||
|
height: 1rem;
|
||||||
|
}
|
||||||
.min-h-full {
|
.min-h-full {
|
||||||
min-height: 100%;
|
min-height: 100%;
|
||||||
}
|
}
|
||||||
|
.w-4 {
|
||||||
|
width: 1rem;
|
||||||
|
}
|
||||||
|
.w-full {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.w-1\/3 {
|
||||||
|
width: 33.333333%;
|
||||||
|
}
|
||||||
.max-w-screen-md {
|
.max-w-screen-md {
|
||||||
max-width: 768px;
|
max-width: 768px;
|
||||||
}
|
}
|
||||||
@@ -601,35 +624,48 @@ span.field-validation-error {
|
|||||||
.grid-cols-2 {
|
.grid-cols-2 {
|
||||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||||
}
|
}
|
||||||
.grid-rows-2 {
|
|
||||||
grid-template-rows: repeat(2, minmax(0, 1fr));
|
|
||||||
}
|
|
||||||
.flex-row {
|
.flex-row {
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
}
|
}
|
||||||
.flex-col {
|
.flex-col {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
|
.items-center {
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
.justify-end {
|
.justify-end {
|
||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
}
|
}
|
||||||
.gap-2 {
|
|
||||||
gap: 0.5rem;
|
|
||||||
}
|
|
||||||
.gap-4 {
|
.gap-4 {
|
||||||
gap: 1rem;
|
gap: 1rem;
|
||||||
}
|
}
|
||||||
|
.gap-6 {
|
||||||
|
gap: 1.5rem;
|
||||||
|
}
|
||||||
.gap-x-4 {
|
.gap-x-4 {
|
||||||
column-gap: 1rem;
|
column-gap: 1rem;
|
||||||
}
|
}
|
||||||
|
.gap-x-3 {
|
||||||
|
column-gap: 0.75rem;
|
||||||
|
}
|
||||||
|
.space-y-6 > :not([hidden]) ~ :not([hidden]) {
|
||||||
|
--tw-space-y-reverse: 0;
|
||||||
|
margin-top: calc(1.5rem * calc(1 - var(--tw-space-y-reverse)));
|
||||||
|
margin-bottom: calc(1.5rem * var(--tw-space-y-reverse));
|
||||||
|
}
|
||||||
|
.space-y-2 > :not([hidden]) ~ :not([hidden]) {
|
||||||
|
--tw-space-y-reverse: 0;
|
||||||
|
margin-top: calc(0.5rem * calc(1 - var(--tw-space-y-reverse)));
|
||||||
|
margin-bottom: calc(0.5rem * var(--tw-space-y-reverse));
|
||||||
|
}
|
||||||
.whitespace-nowrap {
|
.whitespace-nowrap {
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
.rounded-md {
|
.rounded-md {
|
||||||
border-radius: 0.375rem;
|
border-radius: 0.375rem;
|
||||||
}
|
}
|
||||||
.border-\[1px\] {
|
.border-0 {
|
||||||
border-width: 1px;
|
border-width: 0px;
|
||||||
}
|
}
|
||||||
.border-b-2 {
|
.border-b-2 {
|
||||||
border-bottom-width: 2px;
|
border-bottom-width: 2px;
|
||||||
@@ -641,13 +677,9 @@ span.field-validation-error {
|
|||||||
--tw-border-opacity: 1;
|
--tw-border-opacity: 1;
|
||||||
border-color: rgb(0 0 0 / var(--tw-border-opacity));
|
border-color: rgb(0 0 0 / var(--tw-border-opacity));
|
||||||
}
|
}
|
||||||
.border-gray-500 {
|
.border-gray-300 {
|
||||||
--tw-border-opacity: 1;
|
--tw-border-opacity: 1;
|
||||||
border-color: rgb(107 114 128 / var(--tw-border-opacity));
|
border-color: rgb(209 213 219 / var(--tw-border-opacity));
|
||||||
}
|
|
||||||
.border-r-white {
|
|
||||||
--tw-border-opacity: 1;
|
|
||||||
border-right-color: rgb(255 255 255 / var(--tw-border-opacity));
|
|
||||||
}
|
}
|
||||||
.bg-amber-300 {
|
.bg-amber-300 {
|
||||||
--tw-bg-opacity: 1;
|
--tw-bg-opacity: 1;
|
||||||
@@ -656,10 +688,6 @@ span.field-validation-error {
|
|||||||
.p-6 {
|
.p-6 {
|
||||||
padding: 1.5rem;
|
padding: 1.5rem;
|
||||||
}
|
}
|
||||||
.py-1 {
|
|
||||||
padding-top: 0.25rem;
|
|
||||||
padding-bottom: 0.25rem;
|
|
||||||
}
|
|
||||||
.px-2 {
|
.px-2 {
|
||||||
padding-left: 0.5rem;
|
padding-left: 0.5rem;
|
||||||
padding-right: 0.5rem;
|
padding-right: 0.5rem;
|
||||||
@@ -668,19 +696,21 @@ span.field-validation-error {
|
|||||||
padding-left: 1rem;
|
padding-left: 1rem;
|
||||||
padding-right: 1rem;
|
padding-right: 1rem;
|
||||||
}
|
}
|
||||||
|
.py-1 {
|
||||||
|
padding-top: 0.25rem;
|
||||||
|
padding-bottom: 0.25rem;
|
||||||
|
}
|
||||||
.py-2 {
|
.py-2 {
|
||||||
padding-top: 0.5rem;
|
padding-top: 0.5rem;
|
||||||
padding-bottom: 0.5rem;
|
padding-bottom: 0.5rem;
|
||||||
}
|
}
|
||||||
|
.py-1\.5 {
|
||||||
|
padding-top: 0.375rem;
|
||||||
|
padding-bottom: 0.375rem;
|
||||||
|
}
|
||||||
.pb-1 {
|
.pb-1 {
|
||||||
padding-bottom: 0.25rem;
|
padding-bottom: 0.25rem;
|
||||||
}
|
}
|
||||||
.pr-2 {
|
|
||||||
padding-right: 0.5rem;
|
|
||||||
}
|
|
||||||
.pt-1 {
|
|
||||||
padding-top: 0.25rem;
|
|
||||||
}
|
|
||||||
.pl-4 {
|
.pl-4 {
|
||||||
padding-left: 1rem;
|
padding-left: 1rem;
|
||||||
}
|
}
|
||||||
@@ -694,20 +724,25 @@ span.field-validation-error {
|
|||||||
font-size: 1.5rem;
|
font-size: 1.5rem;
|
||||||
line-height: 2rem;
|
line-height: 2rem;
|
||||||
}
|
}
|
||||||
.text-sm {
|
|
||||||
font-size: 0.875rem;
|
|
||||||
line-height: 1.25rem;
|
|
||||||
}
|
|
||||||
.text-lg {
|
.text-lg {
|
||||||
font-size: 1.125rem;
|
font-size: 1.125rem;
|
||||||
line-height: 1.75rem;
|
line-height: 1.75rem;
|
||||||
}
|
}
|
||||||
|
.text-sm {
|
||||||
|
font-size: 0.875rem;
|
||||||
|
line-height: 1.25rem;
|
||||||
|
}
|
||||||
.font-bold {
|
.font-bold {
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
}
|
}
|
||||||
.text-black {
|
.font-semibold {
|
||||||
--tw-text-opacity: 1;
|
font-weight: 600;
|
||||||
color: rgb(0 0 0 / var(--tw-text-opacity));
|
}
|
||||||
|
.font-medium {
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
.leading-6 {
|
||||||
|
line-height: 1.5rem;
|
||||||
}
|
}
|
||||||
.text-gray-500 {
|
.text-gray-500 {
|
||||||
--tw-text-opacity: 1;
|
--tw-text-opacity: 1;
|
||||||
@@ -717,6 +752,39 @@ span.field-validation-error {
|
|||||||
--tw-text-opacity: 1;
|
--tw-text-opacity: 1;
|
||||||
color: rgb(31 41 55 / var(--tw-text-opacity));
|
color: rgb(31 41 55 / var(--tw-text-opacity));
|
||||||
}
|
}
|
||||||
|
.text-gray-600 {
|
||||||
|
--tw-text-opacity: 1;
|
||||||
|
color: rgb(75 85 99 / var(--tw-text-opacity));
|
||||||
|
}
|
||||||
|
.text-gray-900 {
|
||||||
|
--tw-text-opacity: 1;
|
||||||
|
color: rgb(17 24 39 / var(--tw-text-opacity));
|
||||||
|
}
|
||||||
|
.text-indigo-600 {
|
||||||
|
--tw-text-opacity: 1;
|
||||||
|
color: rgb(79 70 229 / var(--tw-text-opacity));
|
||||||
|
}
|
||||||
|
.shadow-sm {
|
||||||
|
--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);
|
||||||
|
--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);
|
||||||
|
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
|
||||||
|
}
|
||||||
|
.ring-1 {
|
||||||
|
--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
|
||||||
|
--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);
|
||||||
|
box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
|
||||||
|
}
|
||||||
|
.ring-inset {
|
||||||
|
--tw-ring-inset: inset;
|
||||||
|
}
|
||||||
|
.ring-gray-300 {
|
||||||
|
--tw-ring-opacity: 1;
|
||||||
|
--tw-ring-color: rgb(209 213 219 / var(--tw-ring-opacity));
|
||||||
|
}
|
||||||
|
.placeholder\:text-gray-400::placeholder {
|
||||||
|
--tw-text-opacity: 1;
|
||||||
|
color: rgb(156 163 175 / var(--tw-text-opacity));
|
||||||
|
}
|
||||||
.hover\:bg-amber-500:hover {
|
.hover\:bg-amber-500:hover {
|
||||||
--tw-bg-opacity: 1;
|
--tw-bg-opacity: 1;
|
||||||
background-color: rgb(245 158 11 / var(--tw-bg-opacity));
|
background-color: rgb(245 158 11 / var(--tw-bg-opacity));
|
||||||
@@ -725,6 +793,18 @@ span.field-validation-error {
|
|||||||
--tw-text-opacity: 1;
|
--tw-text-opacity: 1;
|
||||||
color: rgb(0 0 0 / var(--tw-text-opacity));
|
color: rgb(0 0 0 / var(--tw-text-opacity));
|
||||||
}
|
}
|
||||||
|
.focus\:ring-2:focus {
|
||||||
|
--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
|
||||||
|
--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);
|
||||||
|
box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
|
||||||
|
}
|
||||||
|
.focus\:ring-inset:focus {
|
||||||
|
--tw-ring-inset: inset;
|
||||||
|
}
|
||||||
|
.focus\:ring-indigo-600:focus {
|
||||||
|
--tw-ring-opacity: 1;
|
||||||
|
--tw-ring-color: rgb(79 70 229 / var(--tw-ring-opacity));
|
||||||
|
}
|
||||||
.disabled\:cursor-not-allowed:disabled {
|
.disabled\:cursor-not-allowed:disabled {
|
||||||
cursor: not-allowed;
|
cursor: not-allowed;
|
||||||
}
|
}
|
||||||
@@ -736,5 +816,20 @@ span.field-validation-error {
|
|||||||
--tw-text-opacity: 1;
|
--tw-text-opacity: 1;
|
||||||
color: rgb(75 85 99 / var(--tw-text-opacity));
|
color: rgb(75 85 99 / var(--tw-text-opacity));
|
||||||
}
|
}
|
||||||
|
@media (min-width: 640px) {
|
||||||
|
|
||||||
|
.sm\:max-w-xs {
|
||||||
|
max-width: 20rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sm\:text-sm {
|
||||||
|
font-size: 0.875rem;
|
||||||
|
line-height: 1.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sm\:leading-6 {
|
||||||
|
line-height: 1.5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +0,0 @@
|
|||||||
using OrchardCore.ContentFields.Fields;
|
|
||||||
using OrchardCore.ContentManagement;
|
|
||||||
|
|
||||||
namespace Oap.OapExplanation;
|
|
||||||
public class OapExplanationPart : ContentPart
|
|
||||||
{
|
|
||||||
public HtmlField Text { get; set; } = new();
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user