moduleDefintions - profiles validation changes

This commit is contained in:
Grayson Walker 2021-07-29 16:46:58 -04:00
parent 2dbf9671d9
commit cf40462531
8 changed files with 914 additions and 812 deletions

View File

@ -10,29 +10,30 @@
@if (_templates != null) @if (_templates != null)
{ {
<form @ref="form" class="@(validated ? "was-validated" : "needs-validation")" novalidate>
<div class="container"> <div class="container">
<div class="row mb-1 align-items-center"> <div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="owner" HelpText="Enter the name of the organization who is developing this module. It should not contain spaces or punctuation." ResourceKey="OwnerName">Owner Name: </Label> <Label Class="col-sm-3" For="owner" HelpText="Enter the name of the organization who is developing this module. It should not contain spaces or punctuation." ResourceKey="OwnerName">Owner Name: </Label>
<div class="col-sm-9"> <div class="col-sm-9">
<input id="owner" class="form-control" @bind="@_owner" /> <input id="owner" class="form-control" @bind="@_owner" maxlength="256" required />
</div> </div>
</div> </div>
<div class="row mb-1 align-items-center"> <div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="module" HelpText="Enter a name for this module. It should not contain spaces or punctuation." ResourceKey="ModuleName">Module Name: </Label> <Label Class="col-sm-3" For="module" HelpText="Enter a name for this module. It should not contain spaces or punctuation." ResourceKey="ModuleName">Module Name: </Label>
<div class="col-sm-9"> <div class="col-sm-9">
<input id="module" class="form-control" @bind="@_module" /> <input id="module" class="form-control" @bind="@_module" maxlength="256" required />
</div> </div>
</div> </div>
<div class="row mb-1 align-items-center"> <div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="description" HelpText="Enter a short description for the module" ResourceKey="Description">Description: </Label> <Label Class="col-sm-3" For="description" HelpText="Enter a short description for the module" ResourceKey="Description">Description: </Label>
<div class="col-sm-9"> <div class="col-sm-9">
<textarea id="description" class="form-control" @bind="@_description" rows="3"></textarea> <textarea id="description" class="form-control" @bind="@_description" rows="3" required></textarea>
</div> </div>
</div> </div>
<div class="row mb-1 align-items-center"> <div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="template" HelpText="Select a module template. Templates are located in the wwwroot/Modules/Templates folder on the server." ResourceKey="Template">Template: </Label> <Label Class="col-sm-3" For="template" HelpText="Select a module template. Templates are located in the wwwroot/Modules/Templates folder on the server." ResourceKey="Template">Template: </Label>
<div class="col-sm-9"> <div class="col-sm-9">
<select id="template" class="form-select" @onchange="(e => TemplateChanged(e))"> <select id="template" class="form-select" @onchange="(e => TemplateChanged(e))" required>
<option value="-">&lt;@Localizer["Template.Select"]&gt;</option> <option value="-">&lt;@Localizer["Template.Select"]&gt;</option>
@foreach (Template template in _templates) @foreach (Template template in _templates)
{ {
@ -44,7 +45,7 @@
<div class="row mb-1 align-items-center"> <div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="reference" HelpText="Select a framework reference version" ResourceKey="FrameworkReference">Framework Reference: </Label> <Label Class="col-sm-3" For="reference" HelpText="Select a framework reference version" ResourceKey="FrameworkReference">Framework Reference: </Label>
<div class="col-sm-9"> <div class="col-sm-9">
<select id="reference" class="form-select" @bind="@_reference"> <select id="reference" class="form-select" @bind="@_reference" required>
@foreach (string version in _versions) @foreach (string version in _versions)
{ {
if (Version.Parse(version).CompareTo(Version.Parse(_minversion)) >= 0) if (Version.Parse(version).CompareTo(Version.Parse(_minversion)) >= 0)
@ -68,9 +69,12 @@
</div> </div>
<button type="button" class="btn btn-success" @onclick="CreateModule">@Localizer["CreateModule"]</button> <button type="button" class="btn btn-success" @onclick="CreateModule">@Localizer["CreateModule"]</button>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink> <NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
</form>
} }
@code { @code {
private ElementReference form;
private bool validated = false;
private string _owner = string.Empty; private string _owner = string.Empty;
private string _module = string.Empty; private string _module = string.Empty;
private string _description = string.Empty; private string _description = string.Empty;
@ -98,6 +102,10 @@
} }
private async Task CreateModule() private async Task CreateModule()
{
validated = true;
var interop = new Interop(JSRuntime);
if (await interop.FormValid(form))
{ {
try try
{ {
@ -118,6 +126,11 @@
await logger.LogError(ex, "Error Creating Module"); await logger.LogError(ex, "Error Creating Module");
} }
} }
else
{
AddModuleMessage(SharedLocalizer["Message.InfoRequired"], MessageType.Warning);
}
}
private bool IsValid(string name) private bool IsValid(string name)
{ {

View File

@ -5,25 +5,26 @@
@inject IStringLocalizer<Edit> Localizer @inject IStringLocalizer<Edit> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer @inject IStringLocalizer<SharedResources> SharedLocalizer
<TabStrip> <form @ref="form" class="@(validated ? "was-validated" : "needs-validation")" novalidate>
<TabStrip>
<TabPanel Name="Definition" ResourceKey="Definition"> <TabPanel Name="Definition" ResourceKey="Definition">
<div class="container"> <div class="container">
<div class="row mb-1 align-items-center"> <div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="name" HelpText="The name of the module" ResourceKey="Name">Name: </Label> <Label Class="col-sm-3" For="name" HelpText="The name of the module" ResourceKey="Name">Name: </Label>
<div class="col-sm-9"> <div class="col-sm-9">
<input id="name" class="form-control" @bind="@_name" /> <input id="name" class="form-control" @bind="@_name" maxlength="256" required />
</div> </div>
</div> </div>
<div class="row mb-1 align-items-center"> <div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="description" HelpText="The description of the module" ResourceKey="Description">Description: </Label> <Label Class="col-sm-3" For="description" HelpText="The description of the module" ResourceKey="Description">Description: </Label>
<div class="col-sm-9"> <div class="col-sm-9">
<textarea id="description" class="form-control" @bind="@_description" rows="2"></textarea> <textarea id="description" class="form-control" @bind="@_description" rows="2" required></textarea>
</div> </div>
</div> </div>
<div class="row mb-1 align-items-center"> <div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="categories" HelpText="Comma delimited list of module categories" ResourceKey="Categories">Categories: </Label> <Label Class="col-sm-3" For="categories" HelpText="Comma delimited list of module categories" ResourceKey="Categories">Categories: </Label>
<div class="col-sm-9"> <div class="col-sm-9">
<input id="categories" class="form-control" @bind="@_categories" /> <input id="categories" class="form-control" @bind="@_categories" required />
</div> </div>
</div> </div>
</div> </div>
@ -81,14 +82,17 @@
</div> </div>
</div> </div>
</TabPanel> </TabPanel>
</TabStrip> </TabStrip>
<button type="button" class="btn btn-success" @onclick="SaveModuleDefinition">@SharedLocalizer["Save"]</button> <button type="button" class="btn btn-success" @onclick="SaveModuleDefinition">@SharedLocalizer["Save"]</button>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink> <NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
<br /> <br />
<br /> <br />
<AuditInfo CreatedBy="@_createdby" CreatedOn="@_createdon" ModifiedBy="@_modifiedby" ModifiedOn="@_modifiedon"></AuditInfo> <AuditInfo CreatedBy="@_createdby" CreatedOn="@_createdon" ModifiedBy="@_modifiedby" ModifiedOn="@_modifiedon"></AuditInfo>
</form>
@code { @code {
private ElementReference form;
private bool validated = false;
private int _moduleDefinitionId; private int _moduleDefinitionId;
private string _name; private string _name;
private string _version; private string _version;
@ -145,6 +149,10 @@
} }
private async Task SaveModuleDefinition() private async Task SaveModuleDefinition()
{
validated = true;
var interop = new Interop(JSRuntime);
if (await interop.FormValid(form))
{ {
try try
{ {
@ -172,4 +180,9 @@
AddModuleMessage(Localizer["Error.Module.Save"], MessageType.Error); AddModuleMessage(Localizer["Error.Module.Save"], MessageType.Error);
} }
} }
else
{
AddModuleMessage(SharedLocalizer["Message.InfoRequired"], MessageType.Warning);
}
}
} }

View File

@ -5,28 +5,39 @@
@inject IStringLocalizer<Export> Localizer @inject IStringLocalizer<Export> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer @inject IStringLocalizer<SharedResources> SharedLocalizer
<form @ref="form" class="@(validated ? "was-validated" : "needs-validation")" novalidate>
<div class="container"> <div class="container">
<div class="row mb-1 align-items-center"> <div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="content" HelpText="Enter the module content" ResourceKey="Content">Content: </Label> <Label Class="col-sm-3" For="content" HelpText="Enter the module content" ResourceKey="Content">Content: </Label>
<div class="col-sm-9"> <div class="col-sm-9">
<textarea id="content" class="form-control" @bind="@_content" rows="5"></textarea> <textarea id="content" class="form-control" @bind="@_content" rows="5" required></textarea>
</div> </div>
</div> </div>
</div> </div>
<button type="button" class="btn btn-success" @onclick="ExportModule">@Localizer["Export"]</button> <button type="button" class="btn btn-success" @onclick="ExportModule">@Localizer["Export"]</button>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink> <NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
</form>
@code {
@code { private ElementReference form;
private bool validated = false;
private string _content = string.Empty; private string _content = string.Empty;
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin; public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin;
public override string Title => "Export Content"; public override string Title => "Export Content";
private async Task ExportModule() private async Task ExportModule()
{
validated = true;
var interop = new Interop(JSRuntime);
if (await interop.FormValid(form))
{ {
_content = await ModuleService.ExportModuleAsync(ModuleState.ModuleId); _content = await ModuleService.ExportModuleAsync(ModuleState.ModuleId);
} }
else
{
AddModuleMessage(SharedLocalizer["Message.InfoRequired"], MessageType.Warning);
} }
}
}

View File

@ -5,6 +5,7 @@
@inject IStringLocalizer<Import> Localizer @inject IStringLocalizer<Import> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer @inject IStringLocalizer<SharedResources> SharedLocalizer
<form @ref="form" class="@(validated ? "was-validated" : "needs-validation")" novalidate>
<div class="container"> <div class="container">
<div class="row mb-1 align-items-center"> <div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="content" HelpText="Enter the module content" ResourceKey="Content">Content: </Label> <Label Class="col-sm-3" For="content" HelpText="Enter the module content" ResourceKey="Content">Content: </Label>
@ -17,15 +18,21 @@
<button type="button" class="btn btn-success" @onclick="ImportModule">@Localizer["Import"]</button> <button type="button" class="btn btn-success" @onclick="ImportModule">@Localizer["Import"]</button>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink> <NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
</form>
@code {
@code {
private string _content = string.Empty; private string _content = string.Empty;
private ElementReference form;
private bool validated = false;
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin; public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin;
public override string Title => "Import Content"; public override string Title => "Import Content";
private async Task ImportModule() private async Task ImportModule()
{
validated = true;
var interop = new Interop(JSRuntime);
if (await interop.FormValid(form))
{ {
if (_content != string.Empty) if (_content != string.Empty)
{ {
@ -52,4 +59,9 @@
AddModuleMessage(Localizer["Message.Required.ImportContent"], MessageType.Warning); AddModuleMessage(Localizer["Message.Required.ImportContent"], MessageType.Warning);
} }
} }
else
{
AddModuleMessage(SharedLocalizer["Message.InfoRequired"], MessageType.Warning);
} }
}
}

View File

@ -8,7 +8,8 @@
@inject IStringLocalizer<Settings> Localizer @inject IStringLocalizer<Settings> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer @inject IStringLocalizer<SharedResources> SharedLocalizer
<TabStrip> <form @ref="form" class="@(validated ? "was-validated" : "needs-validation")" novalidate>
<TabStrip>
<TabPanel Name="Settings" Heading="Settings" ResourceKey="Settings"> <TabPanel Name="Settings" Heading="Settings" ResourceKey="Settings">
@if (_containers != null) @if (_containers != null)
{ {
@ -16,13 +17,13 @@
<div class="row mb-1 align-items-center"> <div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="title" HelpText="Enter the title of the module" ResourceKey="Title">Title: </Label> <Label Class="col-sm-3" For="title" HelpText="Enter the title of the module" ResourceKey="Title">Title: </Label>
<div class="col-sm-9"> <div class="col-sm-9">
<input id="title" type="text" name="Title" class="form-control" @bind="@_title" /> <input id="title" type="text" name="Title" class="form-control" @bind="@_title" required />
</div> </div>
</div> </div>
<div class="row mb-1 align-items-center"> <div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="container" HelpText="Select the module's container" ResourceKey="Container">Container: </Label> <Label Class="col-sm-3" For="container" HelpText="Select the module's container" ResourceKey="Container">Container: </Label>
<div class="col-sm-9"> <div class="col-sm-9">
<select id="container" class="form-select" @bind="@_containerType"> <select id="container" class="form-select" @bind="@_containerType" required>
@foreach (var container in _containers) @foreach (var container in _containers)
{ {
<option value="@container.TypeName">@container.Name</option> <option value="@container.TypeName">@container.Name</option>
@ -33,7 +34,7 @@
<div class="row mb-1 align-items-center"> <div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="allpages" HelpText="Indicate if this module should be displayed on all pages" ResourceKey="DisplayOnAllPages">Display On All Pages? </Label> <Label Class="col-sm-3" For="allpages" HelpText="Indicate if this module should be displayed on all pages" ResourceKey="DisplayOnAllPages">Display On All Pages? </Label>
<div class="col-sm-9"> <div class="col-sm-9">
<select id="allpages" class="form-select" @bind="@_allPages"> <select id="allpages" class="form-select" @bind="@_allPages" required>
<option value="True">@SharedLocalizer["Yes"]</option> <option value="True">@SharedLocalizer["Yes"]</option>
<option value="False">@SharedLocalizer["No"]</option> <option value="False">@SharedLocalizer["No"]</option>
</select> </select>
@ -42,7 +43,7 @@
<div class="row mb-1 align-items-center"> <div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="page" HelpText="The page that the module is located on" ResourceKey="Page">Page: </Label> <Label Class="col-sm-3" For="page" HelpText="The page that the module is located on" ResourceKey="Page">Page: </Label>
<div class="col-sm-9"> <div class="col-sm-9">
<select id="page" class="form-select" @bind="@_pageId"> <select id="page" class="form-select" @bind="@_pageId" required>
@foreach (Page p in PageState.Pages) @foreach (Page p in PageState.Pages)
{ {
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, p.Permissions)) if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, p.Permissions))
@ -79,17 +80,20 @@
@ContainerSettingsComponent @ContainerSettingsComponent
</TabPanel> </TabPanel>
} }
</TabStrip> </TabStrip>
<button type="button" class="btn btn-success" @onclick="SaveModule">@SharedLocalizer["Save"]</button> <button type="button" class="btn btn-success" @onclick="SaveModule">@SharedLocalizer["Save"]</button>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink> <NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
<br /> <br />
<br /> <br />
<AuditInfo CreatedBy="@createdby" CreatedOn="@createdon" ModifiedBy="@modifiedby" ModifiedOn="@modifiedon"></AuditInfo> <AuditInfo CreatedBy="@createdby" CreatedOn="@createdon" ModifiedBy="@modifiedby" ModifiedOn="@modifiedon"></AuditInfo>
</form>
@code { @code {
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Edit; public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Edit;
public override string Title => "Module Settings"; public override string Title => "Module Settings";
private ElementReference form;
private bool validated = false;
private List<Theme> _themes; private List<Theme> _themes;
private List<ThemeControl> _containers = new List<ThemeControl>(); private List<ThemeControl> _containers = new List<ThemeControl>();
private string _title; private string _title;
@ -169,6 +173,10 @@
} }
private async Task SaveModule() private async Task SaveModule()
{
validated = true;
var interop = new Interop(JSRuntime);
if (await interop.FormValid(form))
{ {
if (!string.IsNullOrEmpty(_title)) if (!string.IsNullOrEmpty(_title))
{ {
@ -218,5 +226,10 @@
AddModuleMessage(Localizer["Message.Required.Title"], MessageType.Warning); AddModuleMessage(Localizer["Message.Required.Title"], MessageType.Warning);
} }
} }
else
{
AddModuleMessage(SharedLocalizer["Message.InfoRequired"], MessageType.Warning);
}
}
} }

View File

@ -6,7 +6,9 @@
@inject IStringLocalizer<Add> Localizer @inject IStringLocalizer<Add> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer @inject IStringLocalizer<SharedResources> SharedLocalizer
<TabStrip Refresh="@_refresh">
<form @ref="form" class="@(validated ? "was-validated" : "needs-validation")" novalidate>
<TabStrip Refresh="@_refresh">
<TabPanel Name="Settings" ResourceKey="Settings"> <TabPanel Name="Settings" ResourceKey="Settings">
@if (_themeList != null) @if (_themeList != null)
{ {
@ -14,13 +16,13 @@
<div class="row mb-1 align-items-center"> <div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="Name" HelpText="Enter the page name" ResourceKey="Name">Name: </Label> <Label Class="col-sm-3" For="Name" HelpText="Enter the page name" ResourceKey="Name">Name: </Label>
<div class="col-sm-9"> <div class="col-sm-9">
<input id="Name" class="form-control" @bind="@_name" /> <input id="Name" class="form-control" @bind="@_name" required />
</div> </div>
</div> </div>
<div class="row mb-1 align-items-center"> <div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="Parent" HelpText="Select the parent for the page in the site hierarchy" ResourceKey="Parent">Parent: </Label> <Label Class="col-sm-3" For="Parent" HelpText="Select the parent for the page in the site hierarchy" ResourceKey="Parent">Parent: </Label>
<div class="col-sm-9"> <div class="col-sm-9">
<select id="Parent" class="form-select" @onchange="(e => ParentChanged(e))"> <select id="Parent" class="form-select" @onchange="(e => ParentChanged(e))" required>
<option value="-1">&lt;@Localizer["SiteRoot"]&gt;</option> <option value="-1">&lt;@Localizer["SiteRoot"]&gt;</option>
@foreach (Page page in _pageList) @foreach (Page page in _pageList)
{ {
@ -32,7 +34,7 @@
<div class="row mb-1 align-items-center"> <div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="Insert" HelpText="Select the location where you would like the page to be inserted in relation to other pages" ResourceKey="Insert">Insert: </Label> <Label Class="col-sm-3" For="Insert" HelpText="Select the location where you would like the page to be inserted in relation to other pages" ResourceKey="Insert">Insert: </Label>
<div class="col-sm-9"> <div class="col-sm-9">
<select id="Insert" class="form-select" @bind="@_insert"> <select id="Insert" class="form-select" @bind="@_insert" required>
<option value="<<">@Localizer["AtBeginning"]</option> <option value="<<">@Localizer["AtBeginning"]</option>
@if (_children != null && _children.Count > 0) @if (_children != null && _children.Count > 0)
{ {
@ -56,7 +58,7 @@
<div class="row mb-1 align-items-center"> <div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="navigation" HelpText="Select whether the page is part of the site navigation or hidden" ResourceKey="Navigation">Navigation? </Label> <Label Class="col-sm-3" For="navigation" HelpText="Select whether the page is part of the site navigation or hidden" ResourceKey="Navigation">Navigation? </Label>
<div class="col-sm-9"> <div class="col-sm-9">
<select id="navigation" class="form-select" @bind="@_isnavigation"> <select id="navigation" class="form-select" @bind="@_isnavigation" required>
<option value="True">@SharedLocalizer["Yes"]</option> <option value="True">@SharedLocalizer["Yes"]</option>
<option value="False">@SharedLocalizer["No"]</option> <option value="False">@SharedLocalizer["No"]</option>
</select> </select>
@ -65,7 +67,7 @@
<div class="row mb-1 align-items-center"> <div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="clickable" HelpText="Select whether the link in the site navigation is enabled or disabled" ResourceKey="Clickable">Clickable? </Label> <Label Class="col-sm-3" For="clickable" HelpText="Select whether the link in the site navigation is enabled or disabled" ResourceKey="Clickable">Clickable? </Label>
<div class="col-sm-9"> <div class="col-sm-9">
<select id="clickable" class="form-select" @bind="@_isclickable"> <select id="clickable" class="form-select" @bind="@_isclickable" required>
<option value="True">@SharedLocalizer["Yes"]</option> <option value="True">@SharedLocalizer["Yes"]</option>
<option value="False">@SharedLocalizer["No"]</option> <option value="False">@SharedLocalizer["No"]</option>
</select> </select>
@ -96,7 +98,7 @@
<div class="row mb-1 align-items-center"> <div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="Theme" HelpText="Select the theme for this page" ResourceKey="Theme">Theme: </Label> <Label Class="col-sm-3" For="Theme" HelpText="Select the theme for this page" ResourceKey="Theme">Theme: </Label>
<div class="col-sm-9"> <div class="col-sm-9">
<select id="Theme" class="form-select" value="@_themetype" @onchange="(e => ThemeChanged(e))"> <select id="Theme" class="form-select" value="@_themetype" @onchange="(e => ThemeChanged(e))" required>
@foreach (var theme in _themes) @foreach (var theme in _themes)
{ {
<option value="@theme.TypeName">@theme.Name</option> <option value="@theme.TypeName">@theme.Name</option>
@ -107,7 +109,7 @@
<div class="row mb-1 align-items-center"> <div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="defaultContainer" HelpText="Select the default container for the page" ResourceKey="DefaultContainer">Default Container: </Label> <Label Class="col-sm-3" For="defaultContainer" HelpText="Select the default container for the page" ResourceKey="DefaultContainer">Default Container: </Label>
<div class="col-sm-9"> <div class="col-sm-9">
<select id="defaultContainer" class="form-select" @bind="@_containertype"> <select id="defaultContainer" class="form-select" @bind="@_containertype" required>
<option value="-">&lt;@Localizer["Container.Select"]&gt;</option> <option value="-">&lt;@Localizer["Container.Select"]&gt;</option>
@foreach (var container in _containers) @foreach (var container in _containers)
{ {
@ -125,7 +127,7 @@
<div class="row mb-1 align-items-center"> <div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="Personalizable" HelpText="Select whether you would like users to be able to personalize this page with their own content" ResourceKey="Personalizable">Personalizable? </Label> <Label Class="col-sm-3" For="Personalizable" HelpText="Select whether you would like users to be able to personalize this page with their own content" ResourceKey="Personalizable">Personalizable? </Label>
<div class="col-sm-9"> <div class="col-sm-9">
<select id="Personalizable" class="form-select" @bind="@_ispersonalizable"> <select id="Personalizable" class="form-select" @bind="@_ispersonalizable" required>
<option value="True">@SharedLocalizer["Yes"]</option> <option value="True">@SharedLocalizer["Yes"]</option>
<option value="False">@SharedLocalizer["No"]</option> <option value="False">@SharedLocalizer["No"]</option>
</select> </select>
@ -148,9 +150,10 @@
@ThemeSettingsComponent @ThemeSettingsComponent
</TabPanel> </TabPanel>
} }
</TabStrip> </TabStrip>
<button type="button" class="btn btn-success" @onclick="SavePage">@SharedLocalizer["Save"]</button> <button type="button" class="btn btn-success" @onclick="SavePage">@SharedLocalizer["Save"]</button>
<button type="button" class="btn btn-secondary" @onclick="Cancel">@SharedLocalizer["Cancel"]</button> <button type="button" class="btn btn-secondary" @onclick="Cancel">@SharedLocalizer["Cancel"]</button>
</form>
@code { @code {
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin; public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin;
@ -179,6 +182,8 @@
private object _themeSettings; private object _themeSettings;
private RenderFragment ThemeSettingsComponent { get; set; } private RenderFragment ThemeSettingsComponent { get; set; }
private bool _refresh = false; private bool _refresh = false;
private ElementReference form;
private bool validated = false;
protected override async Task OnInitializedAsync() protected override async Task OnInitializedAsync()
{ {
@ -274,6 +279,10 @@
} }
private async Task SavePage() private async Task SavePage()
{
validated = true;
var interop = new Interop(JSRuntime);
if (await interop.FormValid(form))
{ {
Page page = null; Page page = null;
try try
@ -381,6 +390,11 @@
AddModuleMessage(Localizer["Error.Page.Save"], MessageType.Error); AddModuleMessage(Localizer["Error.Page.Save"], MessageType.Error);
} }
} }
else
{
AddModuleMessage(SharedLocalizer["Message.InfoRequired"], MessageType.Warning);
}
}
private void Cancel() private void Cancel()
{ {

View File

@ -7,7 +7,8 @@
@inject IStringLocalizer<Edit> Localizer @inject IStringLocalizer<Edit> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer @inject IStringLocalizer<SharedResources> SharedLocalizer
<TabStrip Refresh="@_refresh"> <form @ref="form" class="@(validated ? "was-validated" : "needs-validation")" novalidate>
<TabStrip Refresh="@_refresh">
<TabPanel Name="Settings" ResourceKey="Settings"> <TabPanel Name="Settings" ResourceKey="Settings">
@if (_themeList != null) @if (_themeList != null)
{ {
@ -15,13 +16,13 @@
<div class="row mb-1 align-items-center"> <div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="Name" HelpText="Enter the page name" ResourceKey="Name">Name: </Label> <Label Class="col-sm-3" For="Name" HelpText="Enter the page name" ResourceKey="Name">Name: </Label>
<div class="col-sm-9"> <div class="col-sm-9">
<input id="Name" class="form-control" @bind="@_name" /> <input id="Name" class="form-control" @bind="@_name" required />
</div> </div>
</div> </div>
<div class="row mb-1 align-items-center"> <div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="Parent" HelpText="Select the parent for the page in the site hierarchy" ResourceKey="Parent">Parent: </Label> <Label Class="col-sm-3" For="Parent" HelpText="Select the parent for the page in the site hierarchy" ResourceKey="Parent">Parent: </Label>
<div class="col-sm-9"> <div class="col-sm-9">
<select id="Parent" class="form-select" value="@_parentid" @onchange="(e => ParentChanged(e))"> <select id="Parent" class="form-select" value="@_parentid" @onchange="(e => ParentChanged(e))" required>
<option value="-1">&lt;@Localizer["SiteRoot"]&gt;</option> <option value="-1">&lt;@Localizer["SiteRoot"]&gt;</option>
@foreach (Page page in _pageList) @foreach (Page page in _pageList)
{ {
@ -36,7 +37,7 @@
<div class="row mb-1 align-items-center"> <div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="Move" HelpText="Select the location where you would like the page to be moved in relation to other pages" ResourceKey="Move">Move: </Label> <Label Class="col-sm-3" For="Move" HelpText="Select the location where you would like the page to be moved in relation to other pages" ResourceKey="Move">Move: </Label>
<div class="col-sm-9"> <div class="col-sm-9">
<select id="Move" class="form-select" @bind="@_insert"> <select id="Move" class="form-select" @bind="@_insert" required>
@if (_parentid == _currentparentid) @if (_parentid == _currentparentid)
{ {
<option value="=">&lt;@Localizer["ThisLocation.Keep"]&gt;</option> <option value="=">&lt;@Localizer["ThisLocation.Keep"]&gt;</option>
@ -64,7 +65,7 @@
<div class="row mb-1 align-items-center"> <div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="Navigation" HelpText="Select whether the page is part of the site navigation or hidden" ResourceKey="Navigation">Navigation? </Label> <Label Class="col-sm-3" For="Navigation" HelpText="Select whether the page is part of the site navigation or hidden" ResourceKey="Navigation">Navigation? </Label>
<div class="col-sm-9"> <div class="col-sm-9">
<select id="Navigation" class="form-select" @bind="@_isnavigation"> <select id="Navigation" class="form-select" @bind="@_isnavigation" required>
<option value="True">@SharedLocalizer["Yes"]</option> <option value="True">@SharedLocalizer["Yes"]</option>
<option value="False">@SharedLocalizer["No"]</option> <option value="False">@SharedLocalizer["No"]</option>
</select> </select>
@ -73,7 +74,7 @@
<div class="row mb-1 align-items-center"> <div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="Clickablen" HelpText="Select whether the link in the site navigation is enabled or disabled" ResourceKey="Clickable">Clickable? </Label> <Label Class="col-sm-3" For="Clickablen" HelpText="Select whether the link in the site navigation is enabled or disabled" ResourceKey="Clickable">Clickable? </Label>
<div class="col-sm-9"> <div class="col-sm-9">
<select id="Navigation" class="form-select" @bind="@_isclickable"> <select id="Navigation" class="form-select" @bind="@_isclickable" required>
<option value="True">@SharedLocalizer["Yes"]</option> <option value="True">@SharedLocalizer["Yes"]</option>
<option value="False">@SharedLocalizer["No"]</option> <option value="False">@SharedLocalizer["No"]</option>
</select> </select>
@ -103,7 +104,7 @@
<div class="row mb-1 align-items-center"> <div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="Theme" HelpText="Select the theme for this page" ResourceKey="Theme">Theme: </Label> <Label Class="col-sm-3" For="Theme" HelpText="Select the theme for this page" ResourceKey="Theme">Theme: </Label>
<div class="col-sm-9"> <div class="col-sm-9">
<select id="Theme" class="form-select" value="@_themetype" @onchange="(e => ThemeChanged(e))"> <select id="Theme" class="form-select" value="@_themetype" @onchange="(e => ThemeChanged(e))" required>
@foreach (var theme in _themes) @foreach (var theme in _themes)
{ {
<option value="@theme.TypeName">@theme.Name</option> <option value="@theme.TypeName">@theme.Name</option>
@ -114,7 +115,7 @@
<div class="row mb-1 align-items-center"> <div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="defaultContainer" HelpText="Select the default container for the page" ResourceKey="DefaultContainer">Default Container: </Label> <Label Class="col-sm-3" For="defaultContainer" HelpText="Select the default container for the page" ResourceKey="DefaultContainer">Default Container: </Label>
<div class="col-sm-9"> <div class="col-sm-9">
<select id="defaultContainer" class="form-select" @bind="@_containertype"> <select id="defaultContainer" class="form-select" @bind="@_containertype" required>
<option value="-">&lt;@Localizer["Container.Select"]&gt;</option> <option value="-">&lt;@Localizer["Container.Select"]&gt;</option>
@foreach (var container in _containers) @foreach (var container in _containers)
{ {
@ -132,7 +133,7 @@
<div class="row mb-1 align-items-center"> <div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="Personalizable" HelpText="Select whether you would like users to be able to personalize this page with their own content" ResourceKey="Personalizable">Personalizable? </Label> <Label Class="col-sm-3" For="Personalizable" HelpText="Select whether you would like users to be able to personalize this page with their own content" ResourceKey="Personalizable">Personalizable? </Label>
<div class="col-sm-9"> <div class="col-sm-9">
<select id="Personalizable" class="form-select" @bind="@_ispersonalizable"> <select id="Personalizable" class="form-select" @bind="@_ispersonalizable" required>
<option value="True">@SharedLocalizer["Yes"]</option> <option value="True">@SharedLocalizer["Yes"]</option>
<option value="False">@SharedLocalizer["No"]</option> <option value="False">@SharedLocalizer["No"]</option>
</select> </select>
@ -162,13 +163,16 @@
@ThemeSettingsComponent @ThemeSettingsComponent
</TabPanel> </TabPanel>
} }
</TabStrip> </TabStrip>
<button type="button" class="btn btn-success" @onclick="SavePage">@SharedLocalizer["Save"]</button> <button type="button" class="btn btn-success" @onclick="SavePage">@SharedLocalizer["Save"]</button>
<button type="button" class="btn btn-secondary" @onclick="Cancel">@SharedLocalizer["Cancel"]</button> <button type="button" class="btn btn-secondary" @onclick="Cancel">@SharedLocalizer["Cancel"]</button>
</form>
@code { @code {
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin; public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin;
private ElementReference form;
private bool validated = false;
private List<Theme> _themeList; private List<Theme> _themeList;
private List<ThemeControl> _themes = new List<ThemeControl>(); private List<ThemeControl> _themes = new List<ThemeControl>();
private List<ThemeControl> _containers = new List<ThemeControl>(); private List<ThemeControl> _containers = new List<ThemeControl>();
@ -350,6 +354,10 @@
} }
private async Task SavePage() private async Task SavePage()
{
validated = true;
var interop = new Interop(JSRuntime);
if (await interop.FormValid(form))
{ {
Page page = null; Page page = null;
try try
@ -481,6 +489,11 @@
AddModuleMessage(Localizer["Error.Page.Save"], MessageType.Error); AddModuleMessage(Localizer["Error.Page.Save"], MessageType.Error);
} }
} }
else
{
AddModuleMessage(SharedLocalizer["Message.InfoRequired"], MessageType.Warning);
}
}
private void Cancel() private void Cancel()
{ {

View File

@ -5,59 +5,60 @@
@inject IStringLocalizer<Edit> Localizer @inject IStringLocalizer<Edit> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer @inject IStringLocalizer<SharedResources> SharedLocalizer
<div class="container"> <form @ref="form" class="@(validated ? "was-validated" : "needs-validation")" novalidate>
<div class="container">
<div class="row mb-1 align-items-center"> <div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="name" HelpText="The name of this profile item" ResourceKey="Name">Name: </Label> <Label Class="col-sm-3" For="name" HelpText="The name of this profile item" ResourceKey="Name">Name: </Label>
<div class="col-sm-9"> <div class="col-sm-9">
<input id="name" class="form-control" @bind="@_name" /> <input id="name" class="form-control" @bind="@_name" required />
</div> </div>
</div> </div>
<div class="row mb-1 align-items-center"> <div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="title" HelpText="The title of the profile item to display to the user" ResourceKey="Title">Title: </Label> <Label Class="col-sm-3" For="title" HelpText="The title of the profile item to display to the user" ResourceKey="Title">Title: </Label>
<div class="col-sm-9"> <div class="col-sm-9">
<input id="title" class="form-control" @bind="@_title" /> <input id="title" class="form-control" @bind="@_title" required />
</div> </div>
</div> </div>
<div class="row mb-1 align-items-center"> <div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="description" HelpText="The help text displayed to the user for this profile item" ResourceKey="Description">Description: </Label> <Label Class="col-sm-3" For="description" HelpText="The help text displayed to the user for this profile item" ResourceKey="Description">Description: </Label>
<div class="col-sm-9"> <div class="col-sm-9">
<textarea id="description" class="form-control" @bind="@_description" rows="5"></textarea> <textarea id="description" class="form-control" @bind="@_description" rows="5" required></textarea>
</div> </div>
</div> </div>
<div class="row mb-1 align-items-center"> <div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="category" HelpText="The category of this profile item (for grouping)" ResourceKey="Category">Category: </Label> <Label Class="col-sm-3" For="category" HelpText="The category of this profile item (for grouping)" ResourceKey="Category">Category: </Label>
<div class="col-sm-9"> <div class="col-sm-9">
<input id="category" class="form-control" @bind="@_category" /> <input id="category" class="form-control" @bind="@_category" required />
</div> </div>
</div> </div>
<div class="row mb-1 align-items-center"> <div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="order" HelpText="The index order of where this profile item should be displayed" ResourceKey="Order">Order: </Label> <Label Class="col-sm-3" For="order" HelpText="The index order of where this profile item should be displayed" ResourceKey="Order">Order: </Label>
<div class="col-sm-9"> <div class="col-sm-9">
<input id="order" class="form-control" @bind="@_vieworder" /> <input id="order" class="form-control" @bind="@_vieworder" required />
</div> </div>
</div> </div>
<div class="row mb-1 align-items-center"> <div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="length" HelpText="The max number of characters this profile item should accept (enter zero for unlimited)" ResourceKey="Length">Length: </Label> <Label Class="col-sm-3" For="length" HelpText="The max number of characters this profile item should accept (enter zero for unlimited)" ResourceKey="Length">Length: </Label>
<div class="col-sm-9"> <div class="col-sm-9">
<input id="length" class="form-control" @bind="@_maxlength" /> <input id="length" class="form-control" @bind="@_maxlength" required />
</div> </div>
</div> </div>
<div class="row mb-1 align-items-center"> <div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="defaultVal" HelpText="The default value for this profile item" ResourceKey="DefaultValue">Default Value: </Label> <Label Class="col-sm-3" For="defaultVal" HelpText="The default value for this profile item" ResourceKey="DefaultValue">Default Value: </Label>
<div class="col-sm-9"> <div class="col-sm-9">
<input id="defaultVal" class="form-control" @bind="@_defaultvalue" /> <input id="defaultVal" class="form-control" @bind="@_defaultvalue" required />
</div> </div>
</div> </div>
<div class="row mb-1 align-items-center"> <div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="options" HelpText="A comma delimited list of options the user can select from" ResourceKey="Options">Options: </Label> <Label Class="col-sm-3" For="options" HelpText="A comma delimited list of options the user can select from" ResourceKey="Options">Options: </Label>
<div class="col-sm-9"> <div class="col-sm-9">
<input id="options" class="form-control" @bind="@_options" /> <input id="options" class="form-control" @bind="@_options" required />
</div> </div>
</div> </div>
<div class="row mb-1 align-items-center"> <div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="required" HelpText="Should a user be required to provide a value for this profile item?" ResourceKey="Required">Required? </Label> <Label Class="col-sm-3" For="required" HelpText="Should a user be required to provide a value for this profile item?" ResourceKey="Required">Required? </Label>
<div class="col-sm-9"> <div class="col-sm-9">
<select id="required" class="form-select" @bind="@_isrequired"> <select id="required" class="form-select" @bind="@_isrequired" required>
<option value="True">@SharedLocalizer["Yes"]</option> <option value="True">@SharedLocalizer["Yes"]</option>
<option value="False">@SharedLocalizer["No"]</option> <option value="False">@SharedLocalizer["No"]</option>
</select> </select>
@ -66,25 +67,28 @@
<div class="row mb-1 align-items-center"> <div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="private" HelpText="Should this profile item be visible to all users?" ResourceKey="Private">Private? </Label> <Label Class="col-sm-3" For="private" HelpText="Should this profile item be visible to all users?" ResourceKey="Private">Private? </Label>
<div class="col-sm-9"> <div class="col-sm-9">
<select id="private" class="form-select" @bind="@_isprivate"> <select id="private" class="form-select" @bind="@_isprivate" required>
<option value="True">@SharedLocalizer["Yes"]</option> <option value="True">@SharedLocalizer["Yes"]</option>
<option value="False">@SharedLocalizer["No"]</option> <option value="False">@SharedLocalizer["No"]</option>
</select> </select>
</div> </div>
</div> </div>
</div> </div>
<br /> <br />
<button type="button" class="btn btn-success" @onclick="SaveProfile">@SharedLocalizer["Save"]</button> <button type="button" class="btn btn-success" @onclick="SaveProfile">@SharedLocalizer["Save"]</button>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink> <NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
@if (PageState.QueryString.ContainsKey("id")) @if (PageState.QueryString.ContainsKey("id"))
{ {
<br /> <br />
<br /> <br />
<AuditInfo CreatedBy="@createdby" CreatedOn="@createdon" ModifiedBy="@modifiedby" ModifiedOn="@modifiedon"></AuditInfo> <AuditInfo CreatedBy="@createdby" CreatedOn="@createdon" ModifiedBy="@modifiedby" ModifiedOn="@modifiedon"></AuditInfo>
} }
</form>
@code { @code {
private int _profileid = -1; private int _profileid = -1;
private ElementReference form;
private bool validated = false;
private string _name = string.Empty; private string _name = string.Empty;
private string _title = string.Empty; private string _title = string.Empty;
private string _description = string.Empty; private string _description = string.Empty;
@ -139,6 +143,10 @@
} }
private async Task SaveProfile() private async Task SaveProfile()
{
validated = true;
var interop = new Interop(JSRuntime);
if (await interop.FormValid(form))
{ {
try try
{ {
@ -181,4 +189,9 @@
AddModuleMessage(Localizer["Error.Profile.Save"], MessageType.Error); AddModuleMessage(Localizer["Error.Profile.Save"], MessageType.Error);
} }
} }
else
{
AddModuleMessage(SharedLocalizer["Message.InfoRequired"], MessageType.Warning);
}
}
} }