Editor html CkEditor en laravel

Para dar usabilidad a un textarea, se tienen que utilizar componentes adicionales, como el caso de Ckeditor, que permite dar formato html a los textos de un formulario

Índice
  1. Instalar CkEditor laravel
  2. Incluir CkEditor en el layout
  3. Inicializar CkEditor
  4. Asignar el CkEditor al texto

Instalar CkEditor laravel

Hay que ir a la web oficial de Ckeditor, y en este caso vamos a utilizarlo con su CDN. Acceder a https://ckeditor.com/ckeditor-5/download/ y copiar el código CDN

La versión en el momento de escribir este post es la 30.0.0, y el código es:

<script src="https://cdn.ckeditor.com/ckeditor5/30.0.0/classic/ckeditor.js"></script>

Este código lo vamos a copiar para pegarlo después en la vista, dentro de la directiva push para javascript.

Pero antes preparamos el layout.

Incluir CkEditor en el layout

La plantilla principal o layout que vamos a incluir es la app, pero lo puedes incluir en la que vayas a usar el CkEditor.

resources\views\layouts\app.blade.php

Stacks en el layout

En el header se coloca el stack que tiene que ver con estilos, dándole un nombre por ejemplo css, justo debajo de la directiva livewireStyles

@livewireStyles
@stack('css')

En el body se coloca el stack que tiene que ver con los javascript, dándole un nombre por ejemplo js, justo debajo de la directiva livewireScripts

@livewireScripts
@stack('js')

Push en la vista

En la vista hay que incluir al final del código la directiva push.

@push('js')
<script src="https://cdn.ckeditor.com/ckeditor5/30.0.0/classic/ckeditor.js">
<script>
ClassicEditor
.create( document.querySelector( '#editor' ) )
.catch( error => {
console.error( error );
});
</script>

@endpush

Todo lo que vaya dentro de la directiva de blade @push, se ejecutará en el layout principal donde se ha definido el @stack('js'). En este ejemplo ponemos el CDN del CkEditor.

Inicializar CkEditor

Accediendo a la documentación, se puede pegar el código para inicializar el CkEditor. Se coloca también dentro de la directiva push.

https://ckeditor.com/docs/ckeditor5/latest/builds/guides/quick-start.html

@push('js')
<script src="https://cdn.ckeditor.com/ckeditor5/30.0.0/classic/ckeditor.js">
<script>
ClassicEditor
.create( document.querySelector( '#editor' ) )
.catch( error => {
console.error( error );
});
</script>

@endpush

El id que se asignará al área de texto será en este caso #editor

Asignar el CkEditor al texto

En la vista se asigna el ID correspondiente al CkEditor, al elemento de texto ya sea inpunt o textarea.

<textarea 
id="editor"
wire:model="content"
class="form-control w-full" rows="6"
</textarea
>

De esta forma el elemento del textarea se muestra con las opciones de formatear y estilizar texto html.

Especificar botones a mostrar

Por defecto muestra todos los botones, pero se pueden mostrar solo algunos. Solamente hay que indicar cúales son.

En la documentación de configuración de CkEditor se puede ver cómo utilizar el código

ClassicEditor
    .create( document.querySelector( '#editor' ), {
        toolbar: [ 'heading', '|', 'bold', 'italic', 'link', 'bulletedList', 'numberedList', 'blockQuote' ],
        heading: {
            options: [
                { model: 'paragraph', title: 'Paragraph', class: 'ck-heading_paragraph' },
                { model: 'heading1', view: 'h1', title: 'Heading 1', class: 'ck-heading_heading1' },
                { model: 'heading2', view: 'h2', title: 'Heading 2', class: 'ck-heading_heading2' }
            ]
        }
    } )
    .catch( error => {
        console.log( error );
    } );

Quitando las opciones que no se deseen, es suficiente para que no aparezcan, por ejemplo quitar las listas quedaría el toolbar definido así:

toolbar: [ 'heading', '|', 'bold', 'italic', 'link', 'blockQuote' ],

Mantener funcionalidades después de renderizar

El código anterior tiene la contrariedad de que al volver a renderizar la página, el textarea pierde la funcionalidad de CkEditor, por ejemplo al hacer clic en el botón Crear, y no pasar las validaciones, vuelve a mostrar el formulario pero sin cargar el CkEditor.

Por tanto para evitar renderizar el componente utiliza el método wire:ignore. De esta forma se recarga toda la página menos lo que esté dentro del método ignore.

Para el ejemplo se añade el wire:ignore al div que contiene el textarea

<div class="mb-4"  wire:ignore>
<textarea id="editor" wire:model="content" class="form-control w-full" rows="6">
</textarea>
</div>

Inconveniente de utilizar wire:ignore

El inconveniente que tiene utilizar el método wire:ignore es que no se van a refrescar los datos del área de texto en el componente/controlador, ya que se indica que no se renderize.

Solución al refresco del contenido

Aprovechando que se usa javascritp en esta página, se puede llamar al método mágico set, para informar del contenido del área de texto al componente/controlador.

Hay que añadir el siguiente texto al método ya insertado de CkEditor después de create

.then(function(editor){
editor.model.document.on('change:data', () => {
@this.set('content', editor.getData())
})
})

El significado de este código es, que después del método create, se captura el editor con una función y dentro de la misma se hace referencia al editor.

.then(function(editor){

Indicando que cada vez que cambie algo, genere una acción y que escuche solo el campo data.

editor.model.document.on('change:data', () => {

Finalmente se indica la acción que va a ocurrir, que en este caso es, cambiar el valor de la propiedad content con lo que haya en el editor.

@this.set('content', editor.getData())

Entonces el script entero para que funcione correctamente el editor de texto CkEditor es:

<script>
            ClassicEditor
                .create( document.querySelector( '#editor' ) )
                .then(function(editor){
                    editor.model.document.on('change:data', () => {
                        @this.set('content', editor.getData())
                    })
                })
                .catch( error => {
                    console.error( error );
                } );
</script>

Espero te sirva de ayuda.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Subir