简体   繁体   中英

How i can pass data with Livewire and CkEditor 4?

i cant pass data with my code. how can i do? I've tried many editors but none of them worked properly.

<div wire:ignore>
    <textarea wire:model="content" id="editor"></textarea>
    <script>
        CKEDITOR.replace('editor', {
            // Define the toolbar groups as it is a more accessible solution.
            toolbarGroups: [{
                "name": "basicstyles",
                "groups": ["basicstyles"]
            },
                {
                    "name": "links",
                    "groups": ["links"]
                }
            ],
            callbacks: {
                onChange: function(contents, $editable) {
                @this.set('content', contents);
                }
            },
            // Remove the redundant buttons from toolbar groups defined above.
            removeButtons: 'Underline,Strike,Subscript,Superscript,Anchor,Styles,Specialchar,Blockquote'
        });
    </script>
</div>

I will show you my two versions.

  1. Vanilla Javascript.

     <div wire:ignore> <textarea id="description" wire:key="ckeditor-1">{{ $description }}</textarea> <script> CKEDITOR.replace('description'); CKEDITOR.instances.description.on('change', function() { @this.set('description', this.getData()); }); </script> </div>

@this.set continuously sends data on every change event. You can use 'blur' event instead of change. But I faced the problem, when user fills the CKEditor area and immediately clicks the submit button. Then the property won't be set.

Btw you can see, I am not using wire:model at all, because @this.set is doing the work instead. I am using wire:key (especially for an ignored parts, replaced with third party libraries) - but most of the time will work even without wire:key.

  1. AlpineJS

The reason I am using AlpineJS version is: I don't want my CKEditors to be live synchronized with backend properties on every change. With Alpine version I am using wire:model properly and I can use wire:model.defer (which causes the data will be send on the next network request - when I submit the form).

<div wire:ignore>
  <textarea id="description"
    wire:model.defer="product.description"
    wire:key="ckeditor-1"
    x-data
    x-init="
      CKEDITOR.replace('description');
      CKEDITOR.instances.description.on('change', function() {
        $dispatch('input', this.getData());
      });"
  >
    {{ $description }}
  </textarea>
</div>

This one is also hooked on the 'change' event of the CKEditor. The Alpine's helper directive $dispatch synchronizes/sends CKEditor's data with the wire:model property.

If you use wire:model without defer, the data will by synchronized with each change in the CKEditor - similar to vanilla JS version.

for CKEDITOR-5

<form wire:submit.prevent="SendMail" enctype="multipart/form-data">
    @csrf
    <div wire:ignore class="form-group row">
        <x-label class="col-md-3 col-form-label" for="message" :value="__('Compose message')" />
        <div class="col-md-9">
            <textarea wire:model="message" data-message="@this" class="form-control required" name="message"
                id="message"></textarea>
            <x-error-message :value="__('message')" />
        </div>
    </div>
    
    <button wire:loading.attr="disabled" type="submit"
        class="btn btn-primary float-right" id="submit">Create</button>
</form>

scripts

<script>
    ClassicEditor
        .create(document.querySelector('#message'))
        .then(editor => {
            editor.model.document.on('change:data', () => {
                     const textareaValue = $('#message').data('message');
                     eval(textareaValue).set('message', editor.getData());
            })
        })
        .catch(error => {
            console.error(error);
        });
</script>

OR alternate scripts, while click event

<script>
    ClassicEditor
        .create(document.querySelector('#message'))
        .then(editor => {
            document.querySelector('#submit').addEventListener('click', () => {
                let textareaValue = $('#message').data('message');
                eval(textareaValue).set('message', editor.getData());
            })
        })
        .catch(error => {
            console.error(error);
        });
</script>

Note: don't forgot to add data-message="@this" in textarea tag. Both scripts are working you can choose whatever you want.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM