Adding Quill Editor to Laravel Livewire Forms kdion package

horaciodegiorgi profile image Horacio Degiorgi ・3 min read

In my last project i need and wysiwyg editor and a fast development environment. I want try kdion form package but there is not and implementation for this kind of fields.
Alt Text
I've made a simple class to extend the functionality of the package and other stuffs that i will describe:
First the class, I called AcheFormComponent.


namespace App\Http\Livewire;

// use Kdion4891\LaravelLivewireForms\FormComponent;
use Kdion4891\LaravelLivewireForms\Field;
use Kdion4891\LaravelLivewireForms\FormComponent;

class AcheFormComponent extends FormComponent {
    protected $listeners = [
        'save' => 'hsubmitform'];

    public function hsubmitform()
    public function render()
        // my custom code

        return $this->formView();

With this we can intercept the submit method (using $emit)

We also change the form template in resources/views/vendor/laravel-livewire-forms/form.blade.php (note that i'm using Sweet Alert2 form confirmation and alerts)

    <div class="card">
        <div class="card-body">
            @foreach($fields as $field)
            @include('laravel-livewire-forms::fields.' . $field->type)

            <div class="row">
                <div class="col-md offset-md-2">
                    <button class="btn btn-primary" id="bsave" onclick="asave()">{{ __('Save') }} </button>
                    {{-- <button class="btn btn-primary" wire:click="saveAndGoBack">{{ __('Save & Go Back') }}</button> --}}
                    <a href="{{ url()->previous() }}" class="btn btn-primary">Cancelar</a>

    // Code is inspired by Pastor Ryan Hayden
        // https://github.com/livewire/livewire/issues/106
        // Thank you, sir!
        function asave(){
            var x = document.getElementsByClassName('quillh') ; 
            // take all quill editor in page and put the data in hidden fields.
            var canti = 0; 
            if (x.length>0){

                for(i=0;i<x.length ; i++) { 

                    var xid =   x[i].id.replace('quillh','quill'); 
                   canti++ ; 
  title: 'Save the form  ?',
  text: "We will save form data.",
  showCancelButton: true,
  confirmButtonColor: '#3085d6',
  cancelButtonColor: '#d33',
  confirmButtonText: 'Save!'
}).then((result) => {
  if (result.value) {

      window.livewire.emit('save'); // emit the save value to fire the hsubmitform event

        document.addEventListener('DOMContentLoaded', function () {
            document.querySelectorAll('input[type="file"]').forEach(file => {
                file.addEventListener('input', event => {
                    let form_data = new FormData();
                    form_data.append('component', @json(get_class($this)));
                    form_data.append('field_name', file.id);

                    for (let i = 0; i < event.target.files.length; i++) {
                        form_data.append('files[]', event.target.files[i]);

                    axios.post('{{ route('laravel-livewire-forms.file-upload') }}', form_data, {
                        headers: {'Content-Type': 'multipart/form-data'}
                    }).then(response => {
                        window.livewire.emit('fileUpdate', response.data.field_name, response.data.uploaded_files);


Finally we must place the textareaeditor component in resources/views/fields/textareaeditor.blade.php

<div class="form-group row">
  <label for="{{ $field->name }}" class="col-md-2 col-form-label text-md-right">
      {{ $field->label }}

  <div class="col-md">
            id="{{ $field->name }}"
            class="form-control @error($field->key) is-invalid @enderror"
            autocomplete="{{ $field->autocomplete }}"
            placeholder="{{ $field->placeholder }}"
            wire:model.lazy="{{ $field->key }}"/>

<div class="mt-2 bg-white quillh" id="quillh{{$field->name}}" wire:ignore>
         quill{{$field->name}} = new Quill($refs.quillEditor{{$field->name}}, {theme: 'snow' });
         quill{{$field->name}}.root.innerHTML = @this.get('form_data').{{$field->name}}

         quill{{$field->name}}.on('selection-change', function(range, oldRange, source) {
          //console.log(range  ) 
          //console.log( oldRange)
          if (( range === null && oldRange !== null) || (range === null && oldRange == undefined  )) {
            console.log('tocado' + quill{{$field->name}}.root.innerHTML); 
            @this.set('form_data.{{$field->name}}', quill{{$field->name}}.root.innerHTML)  ;



    Loading ... 
    <link href="{{asset('/js/quill/quill.snow.css') }}" rel="stylesheet">

    <script src="{{asset('/js/quill/quill.js')}}"></script>

You must to put quill css and js in /public/js .

After all the class and blade things we can call the new textareaeditor input type

 Field::make('Large Html TEXT', 'texthtml')->view('fields.textareaeditor')->help('use the quill editor'),

You can even use multiple editor on the same form.

Alt Text

The kdion package is a great tool for make lavarel/livewire forms. But the development is stopped and there are several issues without resolution. I hope this will work for some developers who are using the package.
I'm developping a kdion table package fork too. If you are insterested let me know.

Posted on by:

horaciodegiorgi profile

Horacio Degiorgi


docker, development, libraries, php, laravel, postgresql


Editor guide

check this : github.com/tanthammar/tall-forms
ported from kdion with alpine integration