Adding Quill Editor to Laravel Livewire Forms kdion package
Tags: laravel, quilleditor, forms, livewire
Published: 2020-08-17 13:11:15

In my last [project](https://expoeducativavirtual.mendoza.edu.ar/) i need and wysiwyg editor and a fast development environment. I want try [kdion form package](https://github.com/kdion4891/laravel-livewire-forms) but there is not and implementation for this kind of fields. 
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/omzr1k49fwg4tcti1jzd.png) 
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.

```php
<?php

namespace App\Http\Livewire;

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


class AcheFormComponent extends FormComponent {
    protected $listeners = [
        'fileUpdate', 
        'save' => 'hsubmitform'];
        
    public function hsubmitform()
    {
        $this->submit();
        $this->saveAndGoBackResponse();
    }
    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](https://sweetalert2.github.io/) form confirmation and alerts)

```php
<div>
    <div class="card">
        <div class="card-body">
            @foreach($fields as $field)
            @if($field->view)
            @include($field->view)
            @else
            @include('laravel-livewire-forms::fields.' . $field->type)
            @endif
            @endforeach

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

@push('scripts')
<script>
    // 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'); 
                   window[xid].blur()
                   canti++ ; 
                }
            }
            Swal.fire({
  title: 'Save the form  ?',
  text: "We will save form data.",
  showCancelButton: true,
  focusConfirm: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);
                    });
                })
            });
        });
</script>

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

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

  <div class="col-md">
<input
            id="{{ $field->name }}"
            type="HIDDEN"
            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>
  <div  
    x-data     
x-ref="quillEditor{{$field->name}}"
       x-init="
         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); 
           $dispatch('input',quill{{$field->name}}.root.innerHTML);
            @this.set('form_data.{{$field->name}}', quill{{$field->name}}.root.innerHTML)  ;
          
          }
        });


       "
       
  >
    Loading ... 
  </div>
</div>
@include('laravel-livewire-forms::fields.error-help')
</div>
</div>
@pushonce('styles')
    <link href="{{asset('/js/quill/quill.snow.css') }}" rel="stylesheet">
@endpushonce

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

```

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 
```php
...
 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](https://dev-to-uploads.s3.amazonaws.com/i/ied6bffnjtzy8h1aec1s.png)

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](https://github.com/kdion4891/laravel-livewire-tables) fork too. If you are insterested let me know.