Blazor - Criando um Editor RichText (Quill API)
Neste tutorial veremos como criar um editor RichText com base na API do Quill usando uma aplicação Blazor Server. |
Hoje veremos um tutorial mostrando como criar um editor RichText em uma aplicação Blazor Server usando o componente open-source Quill.
|
Todas as funcionalidades implementadas no projeto Blazor serão feitas via JS interop usando a API do Quill que você pode consultar para detalhes neste link : https://quilljs.com/docs/quickstart/
Recursos usados:
Criando o projeto Blazor Server no VS Community 2019
bra o VS 2019 Community (versão mínima 16.4) e selecione a opção Create a New Project;
A seguir selecione a opção Blazor app e clique em next;
Informe o nome do projeto : Blazor_EditorRichText, a localização e clique em Create;
A seguir teremos uma janela com duas opções :
Selecione a primeira opção - Blazor Server App. Não vamos usar autenticação e vamos habilitar o https.
Clique no botão Create para criar o projeto.
Antes de prosseguir vamos limpar o projeto excluindo os arquivos abaixo e suas referências:
Vamos também ajustar o arquivo NavMenu.razor deixando apenas a opção Home no menu.
Agora com o projeto criado e os ajustes feitos, a primeira coisa a fazer e criar um arquivo JavaScript chamdo BlazorQuill.js para acessar a API do Quill e definir as referências à API no arquivo _Host.cshtml.
Criando o arquivo javascript BlazorQuill
Crie uma pasta js dentro da pasta wwwroot do projeto e nesta pasta crie o arquivo BlazorQuill.js com o seguinte conteúdo:
(function () {
window.QuillFunctions = {
createQuill: function (quillElement) {
var options = {
debug: 'info',
modules: {
toolbar: '#toolbar'
},
placeholder: 'Digite aqui',
readOnly: false,
theme: 'snow'
};
new Quill(quillElement, options);
},
getQuillContent: function (quillControl) {
return JSON.stringify(quillControl.__quill.getContents());
},
getQuillText: function (quillControl) {
return quillControl.__quill.getText();
},
getQuillHTML: function (quillControl) {
return quillControl.__quill.root.innerHTML;
},
loadQuillContent: function (quillControl, quillContent) {
content = JSON.parse(quillContent);
return quillControl.__quill.setContents(content, 'api');
},
disableQuillEditor: function (quillControl) {
quillControl.__quill.enable(false);
}
};
})();
|
Referenciando a API do Quill
Abra o arquivo _Hosts.chtml na pasta Pages e inclua as linhas em azul que referenciam a API do Quill conforme mostrado abaixo :
@page "/"
@namespace Blazor_EditorRichText.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@{
Layout = null;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Blazor_EditorRichText</title>
<base href="~/" />
<link rel="stylesheet" href="css/bootstrap/bootstrap.min.css" />
<link href="css/site.css" rel="stylesheet" />
<link href="https://cdn.quilljs.com/1.3.6/quill.snow.css" rel="stylesheet" />
<link href="https://cdn.quilljs.com/1.3.6/quill.bubble.css" rel="stylesheet" />
</head>
<body>
<app>
<component type="typeof(App)" render-mode="ServerPrerendered" />
</app>
<div id="blazor-error-ui">
<environment include="Staging,Production">
An error has occurred. This application may no longer respond until reloaded.
</environment>
<environment include="Development">
An unhandled exception has occurred. See browser dev tools for details.
</environment>
<a href="" class="reload">Reload</a>
<a class="dismiss">🗙</a>
</div>
<script src="_framework/blazor.server.js"></script>
<script src="https://cdn.quilljs.com/1.3.6/quill.js"></script>
<script src="js/BlazorQuill.js"></script>
</body>
</html>
|
Aqui estamos usando a distribuição CDN da API do Quill e incluindo referência aos arquivos de estilo e ao arquivo da API quill.js.
Definindo o código Blazor no componente Index
Abra o arquivo Index.razor na pasta Pages e inclua o código abaixo:
@page "/"
@inject IJSRuntime JSRuntime
@if (EditorEnabled)
{
<br />
<button class="btn btn-primary" @onclick="GetText">Texto</button>
<button class="btn btn-primary" @onclick="GetHTML">HTML</button>
<button class="btn btn-primary" @onclick="GetEditorContent">Conteúdo</button>
<button class="btn btn-danger" @onclick="SaveContent">Salvar</button>
<button class="btn btn-success" @onclick="LoadContent">Carregar</button>
<button class="btn btn-info" @onclick="DisableQuillEditor">Desabilitar</button>
<br />
<div id="toolbar">
<span class="ql-formats">
<select class="ql-font">
<option selected=""></option>
<option value="serif"></option>
<option value="monospace"></option>
</select>
<select class="ql-size">
<option value="small"></option>
<option selected=""></option>
<option value="large"></option>
<option value="huge"></option>
</select>
</span>
<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>
<button class="ql-indent" value="-1"></button>
<button class="ql-indent" value="+1"></button>
<select class="ql-align">
<option selected=""></option>
<option value="center"></option>
<option value="right"></option>
<option value="justify"></option>
</select>
</span>
<span class="ql-formats">
<button class="ql-link"></button>
</span>
</div>
}
<div @ref="@divEditorElement" />
<div>
@EditorContent
</div>
<div>
@((MarkupString)@EditorHTMLContent)
</div>
@code {
private string strSavedContent = "";
private ElementReference divEditorElement;
private string EditorContent;
private string EditorHTMLContent;
private bool EditorEnabled = true;
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
await JSRuntime.InvokeAsync<string>(
"QuillFunctions.createQuill", divEditorElement);
}
}
async Task GetText()
{
EditorHTMLContent = "";
EditorContent = await JSRuntime.InvokeAsync<string>(
"QuillFunctions.getQuillText", divEditorElement);
}
async Task GetHTML()
{
EditorContent = "";
EditorHTMLContent = await JSRuntime.InvokeAsync<string>(
"QuillFunctions.getQuillHTML", divEditorElement);
}
async Task GetEditorContent()
{
EditorHTMLContent = "";
EditorContent = await JSRuntime.InvokeAsync<string>(
"QuillFunctions.getQuillContent", divEditorElement);
}
async Task SaveContent()
{
strSavedContent = await JSRuntime.InvokeAsync<string>(
"QuillFunctions.getQuillContent", divEditorElement);
}
async Task LoadContent()
{
var QuillDelta = await JSRuntime.InvokeAsync<object>(
"QuillFunctions.loadQuillContent", divEditorElement, strSavedContent);
}
async Task DisableQuillEditor()
{
EditorEnabled = false;
await JSRuntime.InvokeAsync<object>(
"QuillFunctions.disableQuillEditor", divEditorElement);
}
}
|
Agora é só alegria...
Executando o projeto teremos o resultado abaixo:
Pegue o projeto aqui: Blazor_EditorRichText.zip (sem as referências)
"Porque todos
(os cristãos) devemos comparecer ante o tribunal de Cristo, para que cada um
receba segundo o que tiver feito por meio do corpo, ou bem, ou mal."
2 Coríntios 5:10
Referências:
ASP .NET Core 2 - MiniCurso Básico - Macoratti
ASP .NET Core MVC - CRUD básico com ADO .NET - Macoratti
ASP .NET Core - Implementando a segurança com ... - Macoratti
ASP .NET Core - Iniciando com ASP .NET Core MVC e ... - Macoratti
ASP .NET Core MVC - Criando um site com MySql e EF ... - Macoratti
ASP .NET Core - Gerenciador de Despesas Pessoais com ... - Macoratti
Minicurso ASP .NET Core 2.0 - Apresentando MVC - YouTube
ASP .NET Core - Configurando o ambiente de ... - Macoratti
ASP .NET Core e EF Core - Configurando o ambiente - Macoratti
ASP .NET Core - Como configurar o AutoMapper - Macoratti