Docs›Componentes (Admin)›mad-html-editor-field
Componentes (Admin)

mad-html-editor-field

Editor rico (Quill snow) para HTML formatado.

Editor de texto rico baseado em TinyMCE 5 (self-hosted, sem CDN/API key). Gera conteudo HTML e armazena num <textarea> oculto sincronizado via mad:model — integra direto com MadForm sem codigo extra.

Props

Prop Tipo Default Descricao
name string '' Nome do campo (obrigatorio)
label string '' Label do campo
value string '' HTML inicial (sobrescrito pelo MadRenderContext quando o form estiver populado)
height int/string 300 Altura da area de edicao em px
placeholder string '' Texto placeholder dentro do editor
hint string '' Texto de ajuda
error string '' Mensagem de erro
required bool false Campo obrigatorio
disabled bool false Editor somente leitura (readonly no TinyMCE)
attrs string '' Atributos HTML extras no <textarea> interno
width / max-width string '' Largura do wrapper (CSS)
locale string '' (= pt_BR) Idioma da UI: pt_BR, pt_PT, en, es. en e nativo; demais carregam /langs/{locale}.js
toolbar string '' (preset completo) Override total da string de toolbar do TinyMCE
plugins string '' (preset completo) Override total da lista de plugins do TinyMCE
menubar string|bool '' (= preset ativo) false desliga o menubar; string custom troca os menus
statusbar bool true Mostra a barra inferior (contador de palavras etc)
skin string '' (= oxide) Skin do TinyMCE — aceita oxide-dark
content_css string '' (= default) CSS do iframe de conteudo — aceita dark

O id do <textarea> e gerado automaticamente (mad_{name}_{rand}), nao e uma prop configuravel.

Presets default (usados quando toolbar/plugins/menubar ficam vazios):

  • plugins: advlist autolink lists link image charmap preview anchor searchreplace visualblocks visualchars code fullscreen insertdatetime media table paste help wordcount codesample hr nonbreaking pagebreak quickbars directionality
  • toolbar: undo redo | blocks fontsize | bold italic underline strikethrough | forecolor backcolor | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image media table codesample | removeformat searchreplace fullscreen code preview | help
  • menubar: file edit view insert format tools table help

Uso basico

<mad-html-editor-field name="descricao" label="Descricao" />

Com altura customizada

<mad-html-editor-field name="mensagem" label="Mensagem" height="200" required />

Com placeholder

<mad-html-editor-field name="reply_message"
    placeholder="Escreva sua resposta..." height="100" />

Dentro de formulario

<mad-form submit="onSave">
    <mad-form-section title="Conteudo" icon="file-text">
        <mad-input-field name="titulo" label="Titulo" required />
        <mad-html-editor-field name="conteudo" label="Conteudo" height="300" required />
    </mad-form-section>

    <mad-form-actions>
        <mad-btn type="submit" variant="primary" icon="save">Salvar</mad-btn>
    </mad-form-actions>
</mad-form>
use Illuminate\Support\Facades\DB;

public function onSave(): MadResponse
{
    try {
        $this->form->validate(Artigo::rules($this->registroId));

        DB::connection('business')->transaction(function () {
            $artigo = Artigo::findOrNew($this->registroId);
            $this->form->save($artigo); // $artigo->conteudo recebe o HTML do TinyMCE
            $this->registroId = (int) $artigo->id;
        });

        return (new MadResponse())
            ->toast('Salvo!', 'success')
            ->closeDrawer();
    } catch (MadValidationException $e) {
        return $e->asModal();
    } catch (\Throwable $e) {
        return MadMessage::error('Erro', $e->getMessage());
    }
}

Carregar valor existente (onEdit)

O editor le do MadRenderContext automaticamente — basta form->fill($record).

public function onEdit(int $id): void
{
    $artigo = Artigo::findOrFail($id);
    $this->registroId = (int) $artigo->id;
    $this->form->fill($artigo); // o HTML de $artigo->conteudo aparece no editor
}

Sync em detail-form

O _syncFormInputs() do madDetailForm precisa de tratamento especial para o html-editor: ao re-popular linhas do detail (ex: ao reabrir um drawer/modal de edicao de item), o conteudo e injetado via tinymce.get(textarea.id).setContent(html) (resolvido pelo id do <textarea> interno). Isso ja e feito automaticamente pelo framework — nao precisa codigo extra. Basta declarar o campo no detail normalmente:

<mad-detail-form name="paragrafos" model="ArtigoParagrafo" foreign-key="artigo_id" mode="drawer">
    <mad-input-field name="titulo" label="Titulo" required />
    <mad-html-editor-field name="texto" label="Texto" height="250" />
</mad-detail-form>

Validacao

O valor do textarea oculto (HTML do TinyMCE) e enviado normalmente no POST. Validacao via Modelo::rules() funciona igual aos demais campos:

public static function rules($id = null): array
{
    return [
        'titulo'   => 'required|max:200',
        'conteudo' => 'required',
    ];
}

Observacao: o TinyMCE pode enviar markup "vazio" (ex: <p>&nbsp;</p>) quando o usuario apaga todo o conteudo, dependendo do navegador. Se precisar tratar isso como vazio, normalize na validacao customizada ou no onSave.

NUNCA fazer

{{-- ERRADO: usar textarea para campos com HTML rico --}}
<mad-textarea-field name="descricao" label="Descricao" />

{{-- CERTO --}}
<mad-html-editor-field name="descricao" label="Descricao" />

{{-- ERRADO: instanciar TinyMCE manualmente --}}
<textarea id="meu-editor"></textarea>
<script>
    tinymce.init({ target: document.getElementById('meu-editor') });
    document.querySelector('form').addEventListener('submit', function() {
        document.getElementById('meu-input').value = tinymce.get('meu-editor').getContent();
    });
</script>

{{-- CERTO --}}
<mad-html-editor-field name="conteudo" label="Conteudo" />

{{-- ERRADO: manipular a instancia do TinyMCE via JS externo para setar valor --}}
<script>
    tinymce.get('algum-id').setContent('<p>texto</p>');
</script>

{{-- CERTO: setar via PHP (auto-bind) --}}
$this->form->set('conteudo', '<p>texto</p>');

{{-- ERRADO: input type=hidden recebendo HTML serializado a mao --}}
<input type="hidden" name="conteudo" value="{{ $html }}">

{{-- CERTO --}}
<mad-html-editor-field name="conteudo" :value="$html" />