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
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