resolved #270 - migrated raw html entry into richtexteditor control
This commit is contained in:
parent
f07146fd50
commit
051534b80c
|
@ -3,27 +3,80 @@
|
||||||
@attribute [OqtaneIgnore]
|
@attribute [OqtaneIgnore]
|
||||||
@inject IJSRuntime JsRuntime
|
@inject IJSRuntime JsRuntime
|
||||||
|
|
||||||
@if (_filemanagervisible)
|
<div class="row" style="margin-bottom: 50px;">
|
||||||
{
|
<div class="col">
|
||||||
<FileManager @ref="_fileManager" Filter="@Constants.ImageFiles" />
|
<TabStrip>
|
||||||
@((MarkupString)_message)
|
<TabPanel Name="Rich" Heading="Rich Text Editor">
|
||||||
<br />
|
@if (_filemanagervisible)
|
||||||
}
|
{
|
||||||
<div class="row justify-content-center">
|
<FileManager @ref="_fileManager" Filter="@Constants.ImageFiles" />
|
||||||
<button type="button" class="btn btn-success" @onclick="InsertImage">Insert Image</button>
|
@((MarkupString)_message)
|
||||||
@if (_filemanagervisible)
|
<br />
|
||||||
{
|
}
|
||||||
@((MarkupString)" ")
|
<div class="row justify-content-center" style="margin-bottom: 20px;">
|
||||||
<button type="button" class="btn btn-secondary" @onclick="CloseFileManager">Close</button>
|
<button type="button" class="btn btn-secondary" @onclick="RefreshRichText">Synchronize Content</button>
|
||||||
}
|
<button type="button" class="btn btn-primary" @onclick="InsertImage">Insert Image</button>
|
||||||
</div>
|
@if (_filemanagervisible)
|
||||||
<div class="row">
|
{
|
||||||
<div class ="col">
|
@((MarkupString)" ")
|
||||||
<div @ref="@_toolBar">
|
<button type="button" class="btn btn-secondary" @onclick="CloseFileManager">Close</button>
|
||||||
@ToolbarContent
|
}
|
||||||
</div>
|
</div>
|
||||||
<div @ref="@_editorElement">
|
<div class="row">
|
||||||
</div>
|
<div class="col">
|
||||||
|
<div @ref="@_toolBar">
|
||||||
|
@if (ToolbarContent != null)
|
||||||
|
{
|
||||||
|
@ToolbarContent
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<select class="ql-header">
|
||||||
|
<option selected=""></option>
|
||||||
|
<option value="1"></option>
|
||||||
|
<option value="2"></option>
|
||||||
|
<option value="3"></option>
|
||||||
|
<option value="4"></option>
|
||||||
|
<option value="5"></option>
|
||||||
|
</select>
|
||||||
|
<span class="ql-formats">
|
||||||
|
<button class="ql-bold"></button>
|
||||||
|
<button class="ql-italic"></button>
|
||||||
|
<button class="ql-underline"></button>
|
||||||
|
<button class="ql-strike"></button>
|
||||||
|
</span>
|
||||||
|
<span class="ql-formats">
|
||||||
|
<select class="ql-color"></select>
|
||||||
|
<select class="ql-background"></select>
|
||||||
|
</span>
|
||||||
|
<span class="ql-formats">
|
||||||
|
<button class="ql-list" value="ordered"></button>
|
||||||
|
<button class="ql-list" value="bullet"></button>
|
||||||
|
</span>
|
||||||
|
<span class="ql-formats">
|
||||||
|
<button class="ql-link"></button>
|
||||||
|
</span>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
<div @ref="@_editorElement">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</TabPanel>
|
||||||
|
<TabPanel Name="Raw" Heading="Raw HTML Editor">
|
||||||
|
<div class="row justify-content-center" style="margin-bottom: 20px;">
|
||||||
|
<button type="button" class="btn btn-secondary" @onclick="RefreshRawHtml">Synchronize Content</button>
|
||||||
|
</div>
|
||||||
|
@if (ReadOnly)
|
||||||
|
{
|
||||||
|
<textarea class="form-control" @bind="@_content" rows="10" readonly></textarea>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<textarea class="form-control" @bind="@_content" rows="10"></textarea>
|
||||||
|
}
|
||||||
|
</TabPanel>
|
||||||
|
</TabStrip>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -32,10 +85,12 @@
|
||||||
private ElementReference _toolBar;
|
private ElementReference _toolBar;
|
||||||
private bool _filemanagervisible = false;
|
private bool _filemanagervisible = false;
|
||||||
private FileManager _fileManager;
|
private FileManager _fileManager;
|
||||||
|
private string _original = string.Empty;
|
||||||
|
private string _content = string.Empty;
|
||||||
private string _message = string.Empty;
|
private string _message = string.Empty;
|
||||||
|
|
||||||
[Parameter]
|
[Parameter]
|
||||||
public RenderFragment ToolbarContent { get; set; }
|
public string Content { get; set; }
|
||||||
|
|
||||||
[Parameter]
|
[Parameter]
|
||||||
public bool ReadOnly { get; set; } = false;
|
public bool ReadOnly { get; set; } = false;
|
||||||
|
@ -43,12 +98,27 @@
|
||||||
[Parameter]
|
[Parameter]
|
||||||
public string Placeholder { get; set; } = "Enter Your Content...";
|
public string Placeholder { get; set; } = "Enter Your Content...";
|
||||||
|
|
||||||
|
// parameters only applicable to rich text editor
|
||||||
|
[Parameter]
|
||||||
|
public RenderFragment ToolbarContent { get; set; }
|
||||||
|
|
||||||
[Parameter]
|
[Parameter]
|
||||||
public string Theme { get; set; } = "snow";
|
public string Theme { get; set; } = "snow";
|
||||||
|
|
||||||
[Parameter]
|
[Parameter]
|
||||||
public string DebugLevel { get; set; } = "info";
|
public string DebugLevel { get; set; } = "info";
|
||||||
|
|
||||||
|
protected override void OnInitialized()
|
||||||
|
{
|
||||||
|
_original = Content;
|
||||||
|
|
||||||
|
_content = _original;
|
||||||
|
if (string.IsNullOrEmpty(_content))
|
||||||
|
{
|
||||||
|
_content = Placeholder;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected override async Task OnAfterRenderAsync(bool firstRender)
|
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||||
{
|
{
|
||||||
if (firstRender)
|
if (firstRender)
|
||||||
|
@ -61,6 +131,10 @@
|
||||||
Placeholder,
|
Placeholder,
|
||||||
Theme,
|
Theme,
|
||||||
DebugLevel);
|
DebugLevel);
|
||||||
|
|
||||||
|
await RichTextEditorInterop.LoadEditorContent(
|
||||||
|
JsRuntime,
|
||||||
|
_editorElement, _original);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,9 +147,18 @@
|
||||||
|
|
||||||
public async Task<string> GetHtml()
|
public async Task<string> GetHtml()
|
||||||
{
|
{
|
||||||
return await RichTextEditorInterop.GetHtml(
|
if (_original != _content)
|
||||||
JsRuntime,
|
{
|
||||||
_editorElement);
|
// raw html content changed
|
||||||
|
return _content;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// return rich text content
|
||||||
|
return await RichTextEditorInterop.GetHtml(
|
||||||
|
JsRuntime,
|
||||||
|
_editorElement);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<string> GetContent()
|
public async Task<string> GetContent()
|
||||||
|
@ -85,13 +168,6 @@
|
||||||
_editorElement);
|
_editorElement);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task LoadContent(string content)
|
|
||||||
{
|
|
||||||
await RichTextEditorInterop.LoadEditorContent(
|
|
||||||
JsRuntime,
|
|
||||||
_editorElement, content);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task EnableEditor(bool mode)
|
public async Task EnableEditor(bool mode)
|
||||||
{
|
{
|
||||||
await RichTextEditorInterop.EnableEditor(
|
await RichTextEditorInterop.EnableEditor(
|
||||||
|
@ -122,7 +198,6 @@
|
||||||
_filemanagervisible = true;
|
_filemanagervisible = true;
|
||||||
_message = string.Empty;
|
_message = string.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,8 +205,21 @@
|
||||||
{
|
{
|
||||||
_filemanagervisible = false;
|
_filemanagervisible = false;
|
||||||
_message = string.Empty;
|
_message = string.Empty;
|
||||||
|
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task RefreshRichText()
|
||||||
|
{
|
||||||
|
await RichTextEditorInterop.LoadEditorContent(
|
||||||
|
JsRuntime,
|
||||||
|
_editorElement, _content);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task RefreshRawHtml()
|
||||||
|
{
|
||||||
|
_content = await RichTextEditorInterop.GetHtml(
|
||||||
|
JsRuntime,
|
||||||
|
_editorElement);
|
||||||
|
StateHasChanged();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
using Microsoft.JSInterop;
|
using Microsoft.JSInterop;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Oqtane.UI
|
namespace Oqtane.Modules.Controls
|
||||||
{
|
{
|
||||||
public static class RichTextEditorInterop
|
public static class RichTextEditorInterop
|
||||||
{
|
{
|
|
@ -7,111 +7,48 @@
|
||||||
@inject HttpClient http
|
@inject HttpClient http
|
||||||
@inject SiteState sitestate
|
@inject SiteState sitestate
|
||||||
|
|
||||||
<div class="row" style="margin-bottom: 50px;">
|
@if (_content != null)
|
||||||
<div class="col @_visibleText">
|
{
|
||||||
<textarea class="form-control" @bind="@content" rows="10"></textarea>
|
<RichTextEditor Content="@_content" @ref="@RichTextEditorHtml"></RichTextEditor>
|
||||||
</div>
|
<button type="button" class="btn btn-success" @onclick="SaveContent">Save</button>
|
||||||
|
<NavLink class="btn btn-secondary" href="@NavigateUrl()">Cancel</NavLink>
|
||||||
<div class="col @_visibleRich">
|
@if (!string.IsNullOrEmpty(_content))
|
||||||
<RichTextEditor @ref="@RichTextEditorHtml">
|
{
|
||||||
<ToolbarContent>
|
<br /><br />
|
||||||
<select class="ql-header">
|
<AuditInfo CreatedBy="@_createdby" CreatedOn="@_createdon" ModifiedBy="@_modifiedby" ModifiedOn="@_modifiedon"></AuditInfo>
|
||||||
<option selected=""></option>
|
}
|
||||||
<option value="1"></option>
|
}
|
||||||
<option value="2"></option>
|
|
||||||
<option value="3"></option>
|
|
||||||
<option value="4"></option>
|
|
||||||
<option value="5"></option>
|
|
||||||
</select>
|
|
||||||
<span class="ql-formats">
|
|
||||||
<button class="ql-bold"></button>
|
|
||||||
<button class="ql-italic"></button>
|
|
||||||
<button class="ql-underline"></button>
|
|
||||||
<button class="ql-strike"></button>
|
|
||||||
</span>
|
|
||||||
<span class="ql-formats">
|
|
||||||
<select class="ql-color"></select>
|
|
||||||
<select class="ql-background"></select>
|
|
||||||
</span>
|
|
||||||
<span class="ql-formats">
|
|
||||||
<button class="ql-list" value="ordered"></button>
|
|
||||||
<button class="ql-list" value="bullet"></button>
|
|
||||||
</span>
|
|
||||||
<span class="ql-formats">
|
|
||||||
<button class="ql-link"></button>
|
|
||||||
</span>
|
|
||||||
</ToolbarContent>
|
|
||||||
</RichTextEditor>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="col">
|
|
||||||
@if (!RichTextEditorMode)
|
|
||||||
{
|
|
||||||
<button type="button" class="btn btn-secondary" @onclick="RichTextEditor">Rich Text Editor</button>
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
<button type="button" class="btn btn-secondary" @onclick="RawHtmlEditor">Raw HTML Editor</button>
|
|
||||||
}
|
|
||||||
<button type="button" class="btn btn-success" @onclick="SaveContent">Save</button>
|
|
||||||
<NavLink class="btn btn-secondary" href="@NavigateUrl()">Cancel</NavLink>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="col">
|
|
||||||
<AuditInfo CreatedBy="@createdby" CreatedOn="@createdon" ModifiedBy="@modifiedby" ModifiedOn="@modifiedon"></AuditInfo>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
private string _visibleText = "d-none";
|
|
||||||
private string _visibleRich;
|
|
||||||
private bool _richTextEditorMode;
|
|
||||||
private RichTextEditor RichTextEditorHtml;
|
private RichTextEditor RichTextEditorHtml;
|
||||||
private string content;
|
private string _content = null;
|
||||||
private string createdby;
|
private string _createdby;
|
||||||
private DateTime createdon;
|
private DateTime _createdon;
|
||||||
private string modifiedby;
|
private string _modifiedby;
|
||||||
private DateTime modifiedon;
|
private DateTime _modifiedon;
|
||||||
|
|
||||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Edit;
|
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Edit;
|
||||||
|
|
||||||
public override string Title => "Edit Html/Text";
|
public override string Title => "Edit Html/Text";
|
||||||
|
|
||||||
public bool RichTextEditorMode
|
protected override async Task OnInitializedAsync()
|
||||||
{
|
|
||||||
get => _richTextEditorMode;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_richTextEditorMode = value;
|
|
||||||
|
|
||||||
if (_richTextEditorMode)
|
|
||||||
{
|
|
||||||
_visibleText = "d-none";
|
|
||||||
_visibleRich = string.Empty;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_visibleText = string.Empty;
|
|
||||||
_visibleRich = "d-none";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override async Task OnAfterRenderAsync(bool firstRender)
|
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (firstRender)
|
var htmltextservice = new HtmlTextService(http, sitestate);
|
||||||
|
var htmltext = await htmltextservice.GetHtmlTextAsync(ModuleState.ModuleId);
|
||||||
|
if (htmltext != null)
|
||||||
{
|
{
|
||||||
if (content == null)
|
_content = htmltext.Content;
|
||||||
{
|
_content = _content.Replace(Constants.ContentUrl, "/" + PageState.Alias.AliasId.ToString() + Constants.ContentUrl);
|
||||||
RichTextEditorMode = true;
|
_createdby = htmltext.CreatedBy;
|
||||||
await LoadText();
|
_createdon = htmltext.CreatedOn;
|
||||||
}
|
_modifiedby = htmltext.ModifiedBy;
|
||||||
|
_modifiedon = htmltext.ModifiedOn;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_content = string.Empty;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
@ -121,48 +58,10 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task LoadText()
|
|
||||||
{
|
|
||||||
var htmltextservice = new HtmlTextService(http, sitestate);
|
|
||||||
var htmltext = await htmltextservice.GetHtmlTextAsync(ModuleState.ModuleId);
|
|
||||||
if (htmltext != null)
|
|
||||||
{
|
|
||||||
content = htmltext.Content;
|
|
||||||
createdby = htmltext.CreatedBy;
|
|
||||||
createdon = htmltext.CreatedOn;
|
|
||||||
modifiedby = htmltext.ModifiedBy;
|
|
||||||
modifiedon = htmltext.ModifiedOn;
|
|
||||||
|
|
||||||
if (RichTextEditorMode)
|
|
||||||
{
|
|
||||||
await RichTextEditorHtml.LoadContent(content);
|
|
||||||
StateHasChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task RichTextEditor()
|
|
||||||
{
|
|
||||||
RichTextEditorMode = true;
|
|
||||||
await RichTextEditorHtml.LoadContent(content);
|
|
||||||
StateHasChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task RawHtmlEditor()
|
|
||||||
{
|
|
||||||
content = await this.RichTextEditorHtml.GetHtml();
|
|
||||||
RichTextEditorMode = false;
|
|
||||||
StateHasChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task SaveContent()
|
private async Task SaveContent()
|
||||||
{
|
{
|
||||||
if (RichTextEditorMode)
|
string content = await RichTextEditorHtml.GetHtml();
|
||||||
{
|
content = content.Replace("/" + PageState.Alias.AliasId.ToString() + Constants.ContentUrl, Constants.ContentUrl);
|
||||||
content = await RichTextEditorHtml.GetHtml();
|
|
||||||
}
|
|
||||||
|
|
||||||
content = content.Replace(((PageState.Alias.Path == string.Empty) ? "/~" : PageState.Alias.Path) + Constants.ContentUrl, Constants.ContentUrl);
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -190,5 +89,4 @@
|
||||||
AddModuleMessage("Error Saving Content", MessageType.Error);
|
AddModuleMessage("Error Saving Content", MessageType.Error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
if (htmltext != null)
|
if (htmltext != null)
|
||||||
{
|
{
|
||||||
content = htmltext.Content;
|
content = htmltext.Content;
|
||||||
content = content.Replace(Constants.ContentUrl, ((PageState.Alias.Path == "") ? "/~" : PageState.Alias.Path) + Constants.ContentUrl);
|
content = content.Replace(Constants.ContentUrl, "/" + PageState.Alias.AliasId.ToString() + Constants.ContentUrl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user