Merge pull request #3652 from thabaum/ENH-Adds-Profile-Autocomplete-Setting

Enh: Autocomplete Attribute Enhancement
This commit is contained in:
Shaun Walker 2024-01-19 15:25:13 -05:00 committed by GitHub
commit ab08732ba8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 131 additions and 36 deletions

View File

@ -69,7 +69,7 @@
<h2>@Localizer["ApplicationAdmin"]</h2><br />
<div class="container">
<div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="username" HelpText="Provide a username for the primary user accountt" ResourceKey="Username">Username:</Label>
<Label Class="col-sm-3" For="username" HelpText="Provide a username for the primary user account" ResourceKey="Username">Username:</Label>
<div class="col-sm-9">
<input id="username" type="text" class="form-control" @bind="@_hostUsername" />
</div>

View File

@ -76,6 +76,12 @@
<input id="validation" class="form-control" @bind="@_validation" maxlength="200" />
</div>
</div>
<div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="autocomplete" HelpText="The HTML autocomplete attribute allows you to specify browser behavior for automated assistance in filling out form field values, with a character limit of 30 to ensure concise and effective usage." ResourceKey="Autocomplete">Autocomplete: </Label>
<div class="col-sm-9">
<input id="autocomplete" class="form-control" @bind="@_autocomplete" maxlength="30" />
</div>
</div>
<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>
<div class="col-sm-9">
@ -89,7 +95,7 @@
<br />
<button type="button" class="btn btn-success" @onclick="SaveProfile">@SharedLocalizer["Save"]</button>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
@if (PageState.QueryString.ContainsKey("id"))
@if (PageState.QueryString.ContainsKey("id"))
{
<br />
<br />
@ -111,6 +117,7 @@
private string _defaultvalue = string.Empty;
private string _options = string.Empty;
private string _validation = string.Empty;
private string _autocomplete = string.Empty;
private string _isrequired = "False";
private string _isprivate = "False";
private string createdby;
@ -142,6 +149,7 @@
_defaultvalue = profile.DefaultValue;
_options = profile.Options;
_validation = profile.Validation;
_autocomplete = profile.Autocomplete;
_isrequired = profile.IsRequired.ToString();
_isprivate = profile.IsPrivate.ToString();
createdby = profile.CreatedBy;
@ -187,8 +195,10 @@
profile.DefaultValue = _defaultvalue;
profile.Options = _options;
profile.Validation = _validation;
profile.Autocomplete = _autocomplete;
profile.IsRequired = (_isrequired == null ? false : Boolean.Parse(_isrequired));
profile.IsPrivate = (_isprivate == null ? false : Boolean.Parse(_isprivate));
if (_profileid != -1)
{
profile = await ProfileService.UpdateProfileAsync(profile);

View File

@ -103,44 +103,91 @@
<div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="@p.Name" HelpText="@p.Description">@p.Title</Label>
<div class="col-sm-9">
@if (!string.IsNullOrEmpty(p.Options))
@if (!string.IsNullOrEmpty(p.Options))
{
<select id="@p.Name" class="form-select" @onchange="@(e => ProfileChanged(e, p.Name))">
@foreach (var option in p.Options.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
{
@if (GetProfileValue(p.Name, "") == option || (GetProfileValue(p.Name, "") == "" && p.DefaultValue == option))
@if (!string.IsNullOrEmpty(p.Autocomplete))
{
<select id="@p.Name" class="form-select" @onchange="@(e => ProfileChanged(e, p.Name))" autocomplete="@p.Autocomplete">
@foreach (var option in p.Options.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
{
<option value="@option" selected>@option</option>
@if (GetProfileValue(p.Name, "") == option || (GetProfileValue(p.Name, "") == "" && p.DefaultValue == option))
{
<option value="@option" selected>@option</option>
}
else
{
<option value="@option">@option</option>
}
}
else
</select>
}
else
{
<select id="@p.Name" class="form-select" @onchange="@(e => ProfileChanged(e, p.Name))">
@foreach (var option in p.Options.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
{
<option value="@option">@option</option>
@if (GetProfileValue(p.Name, "") == option || (GetProfileValue(p.Name, "") == "" && p.DefaultValue == option))
{
<option value="@option" selected>@option</option>
}
else
{
<option value="@option">@option</option>
}
}
}
</select>
</select>
}
}
else
{
@if (p.Rows == 1)
{
@if (p.IsRequired)
if (!string.IsNullOrEmpty(p.Autocomplete))
{
<input id="@p.Name" class="form-control" maxlength="@p.MaxLength" value="@GetProfileValue(p.Name, p.DefaultValue)" required @onchange="@(e => ProfileChanged(e, p.Name))" />
@if (p.IsRequired)
{
<input id="@p.Name" class="form-control" maxlength="@p.MaxLength" value="@GetProfileValue(p.Name, p.DefaultValue)" required @onchange="@(e => ProfileChanged(e, p.Name))" autocomplete="@p.Autocomplete" />
}
else
{
<input id="@p.Name" class="form-control" maxlength="@p.MaxLength" value="@GetProfileValue(p.Name, p.DefaultValue)" @onchange="@(e => ProfileChanged(e, p.Name))" autocomplete="@p.Autocomplete" />
}
}
else
{
<input id="@p.Name" class="form-control" maxlength="@p.MaxLength" value="@GetProfileValue(p.Name, p.DefaultValue)" @onchange="@(e => ProfileChanged(e, p.Name))" />
@if (p.IsRequired)
{
<input id="@p.Name" class="form-control" maxlength="@p.MaxLength" value="@GetProfileValue(p.Name, p.DefaultValue)" required @onchange="@(e => ProfileChanged(e, p.Name))" />
}
else
{
<input id="@p.Name" class="form-control" maxlength="@p.MaxLength" value="@GetProfileValue(p.Name, p.DefaultValue)" @onchange="@(e => ProfileChanged(e, p.Name))" />
}
}
}
else
{
@if (p.IsRequired)
if (!string.IsNullOrEmpty(p.Autocomplete))
{
<textarea id="@p.Name" class="form-control" maxlength="@p.MaxLength" rows="@p.Rows" value="@GetProfileValue(p.Name, p.DefaultValue)" required @onchange="@(e => ProfileChanged(e, p.Name))"></textarea>
@if (p.IsRequired)
{
<textarea id="@p.Name" class="form-control" maxlength="@p.MaxLength" rows="@p.Rows" value="@GetProfileValue(p.Name, p.DefaultValue)" required @onchange="@(e => ProfileChanged(e, p.Name))" autocomplete="@p.Autocomplete"></textarea>
}
else
{
<textarea id="@p.Name" class="form-control" maxlength="@p.MaxLength" rows="@p.Rows" value="@GetProfileValue(p.Name, p.DefaultValue)" @onchange="@(e => ProfileChanged(e, p.Name))" autocomplete="@p.Autocomplete"></textarea>
}
}
else
{
<textarea id="@p.Name" class="form-control" maxlength="@p.MaxLength" rows="@p.Rows" value="@GetProfileValue(p.Name, p.DefaultValue)" @onchange="@(e => ProfileChanged(e, p.Name))"></textarea>
@if (p.IsRequired)
{
<textarea id="@p.Name" class="form-control" maxlength="@p.MaxLength" rows="@p.Rows" value="@GetProfileValue(p.Name, p.DefaultValue)" required @onchange="@(e => ProfileChanged(e, p.Name))"></textarea>
}
else
{
<textarea id="@p.Name" class="form-control" maxlength="@p.MaxLength" rows="@p.Rows" value="@GetProfileValue(p.Name, p.DefaultValue)" @onchange="@(e => ProfileChanged(e, p.Name))"></textarea>
}
}
}
}
@ -360,10 +407,10 @@
photofileid = -1;
photo = null;
}
var sitesettings = await SettingService.GetSiteSettingsAsync(SiteState.Alias.SiteId);
_ImageFiles = SettingService.GetSetting(settings, "ImageFiles", Constants.ImageFiles);
settings = await SettingService.GetUserSettingsAsync(PageState.User.UserId);
var sitesettings = await SettingService.GetSiteSettingsAsync(SiteState.Alias.SiteId);
_ImageFiles = SettingService.GetSetting(settings, "ImageFiles", Constants.ImageFiles);
await LoadNotificationsAsync();
@ -561,12 +608,12 @@
await NotificationService.DeleteNotificationAsync(Notification.NotificationId);
}
await logger.LogInformation("Notification Deleted {Notification}", Notification);
}
}
await logger.LogInformation("Notifications Permanently Deleted");
await LoadNotificationsAsync();
ModuleInstance.HideProgressIndicator();
StateHasChanged();
StateHasChanged();
}
catch (Exception ex)
{
@ -574,21 +621,19 @@
AddModuleMessage(ex.Message, MessageType.Error);
ModuleInstance.HideProgressIndicator();
}
}
private void TogglePassword()
{
if (_passwordtype == "password")
{
_passwordtype = "text";
_togglepassword = SharedLocalizer["HidePassword"];
}
else
{
_passwordtype = "password";
_togglepassword = SharedLocalizer["ShowPassword"];
}
}
{
if (_passwordtype == "password")
{
_passwordtype = "text";
_togglepassword = SharedLocalizer["HidePassword"];
}
else
{
_passwordtype = "password";
_togglepassword = SharedLocalizer["ShowPassword"];
}
}
}

View File

@ -195,4 +195,10 @@
<data name="Rows.Text" xml:space="preserve">
<value>Rows: </value>
</data>
<data name="Autocomplete.HelpText" xml:space="preserve">
<value>The HTML autocomplete attribute allows you to specify browser behavior for automated assistance in filling out form field values, with a character limit of 30 to ensure concise and effective usage.</value>
</data>
<data name="Autocomplete.Text" xml:space="preserve">
<value>Autocomplete: </value>
</data>
</root>

View File

@ -0,0 +1,28 @@
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Oqtane.Databases.Interfaces;
using Oqtane.Migrations.EntityBuilders;
using Oqtane.Repository;
namespace Oqtane.Migrations.Tenant
{
[DbContext(typeof(TenantDBContext))]
[Migration("Tenant.05.00.01.03")]
public class AddProfileAutocomplete : MultiDatabaseMigration
{
public AddProfileAutocomplete(IDatabase database) : base(database)
{
}
protected override void Up(MigrationBuilder migrationBuilder)
{
var profileEntityBuilder = new ProfileEntityBuilder(migrationBuilder, ActiveDatabase);
profileEntityBuilder.AddStringColumn("Autocomplete", 50, true);
}
protected override void Down(MigrationBuilder migrationBuilder)
{
// not implemented
}
}
}

View File

@ -78,5 +78,11 @@ namespace Oqtane.Models
/// Optional number of rows (textarea)
/// </summary>
public int Rows { get; set; }
/// <summary>
/// Autocomplete setting for the property.
/// If set, enable autocomplete for the corresponding input field.
/// </summary>
public string Autocomplete { get; set; }
}
}