DEV Community

Horacio Degiorgi
Horacio Degiorgi

Posted on

6 2

Adding Quill Editor to Laravel Livewire Forms kdion package

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.

<?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();
    }
}
Enter fullscreen mode Exit fullscreen mode

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>
    <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
Enter fullscreen mode Exit fullscreen mode

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

Enter fullscreen mode Exit fullscreen mode

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'),
...

Enter fullscreen mode Exit fullscreen mode

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.

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

Top comments (2)

Collapse
 
weppami profile image
weppami

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

Collapse
 
horaciodegiorgi profile image
Horacio Degiorgi

Thanks

Image of Docusign

🛠️ Bring your solution into Docusign. Reach over 1.6M customers.

Docusign is now extensible. Overcome challenges with disconnected products and inaccessible data by bringing your solutions into Docusign and publishing to 1.6M customers in the App Center.

Learn more