How to setup tinymce with livewire

Thanks for Your help, but unfortunatelly I can’t make it working.
I would need 5 different HTML editor, what i have ordered into tabs. Only 1 tab is active orhers are hidden.
But even with this one can’t I reach the HTML editable field.

Do you have maybe a full sample with the JS includes too?
Do we don’t need wire:ignore?
Thx
Gergely

I don’t have honestly. But you can split the tabs onto livewire subcomponents and deal with them with call method and events to manage your parent component. And the example above remain the same just try to change the IDs on each editor.

For more information take a look here:

app\http\livewire\controller.php

public function edit_page($id)
    {
          // Browser's event for transmission content to wysiwyg editor
          $this->dispatchBrowserEvent('wysiwyg-updated', ['content' => $this->page_text]);
    }

Thanks, I will check. Actually, I could managed 99% to implement the trix editor. but I can’t reach that the initial value will be appear.

Question
< x-trixeditor id=“aexpectations” wire:model.lazy=“aexpectations” :initialvalue="$aexpectations"/ >
could this work with HTML value?
I checked, if I’m sending plain text in the variable $aexpectations then I’m receiving that in nested component. but HTML is disappering… :frowning:

This is my 99% solution, only the initial value (what should be important is not working :frowning: )

<div id="div_{{$id}}"
 class="rounded-md shadoe-sm"
 wire:ignore
 x-data
 @trix-blur="$dispatch('change', $event.target.value); Livewire.emit('setvalue','{{$id}}',$event.target.value);"
>
{{$initialvalue}}
<input id="input{{$id}}"
       name="{{$id}}"
       wire:model="{{$id}}"
       wire:key="wk{{$id}}"
       value="{{ $initialvalue }}"
       type="text"
       name="{{$id}}"
/>

----

{{$initialvalue}} <<<< ===== nothing to show if HTML
----
<trix-editor input="input{{$id}}"
             class="form-textarea block w-full transition duration-150 ease-in-out sm:text sm:leading">
</trix-editor>

Hi!
Thank You for your permanent help,
Now, I rebuilt with your code. Sorry It is not fully cleare how I have to implement this funtction.
I gues it should be used after it was rendered. But then I have to call it from alpine from the component?
Thanks

Ps: what is if I have 3 editors on the same page? Should it work too?

Hello,
Thanx @Schwan I have followed your comments and the TinyMCE works good.
But after saving or cancelling the modal window with the TinyMCE editor and then reopen another modal without refreshing the browser I get only a plain textarea.
Why is this happening?

Dear Sirs!
It works. (first page load :slight_smile: )
The problem was, with Jetsream model, that it loaded as well if the modal was closed only hidden.
Of course the editor was initialised with null value.
Now i check in the blade is_open and if not i ignore the modal’s blade.
Thank You agan for yout help.
br.
Gergely

Ps: I’m also trying to get working on second use too.
I found this but no result yet: https://github.com/turbolinks/turbolinks/issues/191
If sombody has working solution, please don’t hasitate to share :slight_smile:

Hi!
I created a working solution:

In the controller file after saving, before close the modal:

$this->dispatchBrowserEvent('openjobsaved');

In the blade file
We are looking for active editors till we kill al of them…

please check it too!

    window.addEventListener('openjobsaved', function() {
        tinymceActive=true;
        while (tinymceActive) {
            tinymceActive = (typeof tinyMCE != 'undefined') && tinyMCE.activeEditor && !tinyMCE.activeEditor.isHidden();
            if (tinymceActive) {
                id=tinyMCE.activeEditor.id;
                tinyMCE.activeEditor.remove();
                alert('killed'+ id);
            }
        }

    });
</ js>

@faxunil I can’t manage to enable TinyMCE once I close the modal and I don’t refresh the browser.

Hi!
Are You using jet-modal? in that case first enable the form only if the modal is openen
@if($isOpen)
@include(‘livewire.openjobs.create’)
@endif
For me was error that initialized with empty data all the time, becouse before filling with data was initialized. With this this error was eliminated.

On the controller after saving the data you should put the
$this->dispatchBrowserEvent(‘openjobsaved’);

and in the blade file you can with @push(‘at the end of file’) inject the javascript code what is checking the active editors and destroys them.

In my fomr I have 7 tabs with 5 editors. This JS is go from one to one and killing them.
After new opening the form thay will reinitialised an @ Schwan managed it perfectly.

JS code:
indent preformatted text by 4 spaces
window.addEventListener(‘closemodal’, function() {
tinymceActive=true;
while (tinymceActive) {
tinymceActive = (typeof tinyMCE != ‘undefined’) && tinyMCE.activeEditor && !tinyMCE.activeEditor.isHidden();
if (tinymceActive) {
id=tinyMCE.activeEditor.id;
tinyMCE.activeEditor.remove();
}
}
});

Yes I am using the jet-modal method with the $isOpen clause.
I have followed your example but put the code at the end of the livewire blade component as script /script and after I close the modal I get an error as image below and once I reopen the modal I get plain textarea.
How to put is as @push?

Before closing the modal did You fired the event to kill the editors?
after store and befor closing modal.
place alert into JS to see the while loop is finding any editor
In my case all for the textareas i give the same class “tinyeditor” and in any editor getting unique wire:key from the parent blade: wire:key=“fieldname{{Str::random(10)}}”

I have the tinymce js at the head section after app.js and the killer script at before tag.
If it is not the order i think you can get JS errors.

I’m using chrome, but now checked my page with Firefox & Edge too and works.

the js script you are using it on the modal blade or the component blade that calls the modal?

I think you can fix it to the layout’s end.
I have using it in the index.blade from them I’m calling the modal.
In may case is in the layout

@stack(‘modals’)
@livewireScripts

@stack(‘bottom’)

And I'm using in the index blade: @push('bottom') So at the end of the day my JS is at the end of the full rendered html I inject it, to have not on every page, only where I need the editor

Alright, I found the mistake, now it’s working perfect.
I put the wire:key and removed id from the textarea.

:slight_smile: it was for me 3 day with help of @Schwan thanx again!

I had the same problem. Especially with switching between tabs.

My solution was to embed a page.

Note: The variable in this case is… $this->text_email

This code i placed in my form:

        <div class="mb-3 row">
            <label for="text_email" class="col-sm-2 col-form-label">Email message</label>
            <div class="col-sm-10">
                @php $wysiwygFieldName = 'text_email'; @endphp
                @include('includes.wysiwyg')
            </div>
        </div>

This is the code in my include (resources/views/includes/wysiwyg.blade.php)

  <div>
    <script>
      var tinyConfig{{ $wysiwygFieldName }} = {
        path_absolute: '/',
        selector: '#wysiwyg{{ $wysiwygFieldName }}',
        plugins: 'paste print preview  searchreplace autolink directionality visualblocks visualchars fullscreen image link media template codesample table charmap hr pagebreak nonbreaking anchor toc insertdatetime advlist lists wordcount imagetools textpattern help code',
        toolbar1: 'formatselect | bold italic strikethrough forecolor backcolor permanentpen formatpainter | link image media pageembed | alignleft aligncenter alignright alignjustify  | numlist bullist outdent indent | removeformat | addcomment',
        schema: 'html5',
        relative_urls: false,
        remove_script_host: true,
        document_base_url: '{{config('app.url')}}/',
        min_height: 350,
        autoresize_min_height: 350,
          setup: function (editor) {
            var toggleState = false;               
            editor.on('init change', function () {
              editor.save();
            });
            editor.on('change', function (e) {
              @this.set('{{ $wysiwygFieldName }}', editor.getContent());
            });
          },
      };
      tinymce.init(tinyConfig{{ $wysiwygFieldName }});
    </script>
    <div wire:ignore>
      <textarea 
        id="wysiwyg{{ $wysiwygFieldName }}" 
        rows="20" 
        wire:model="{{ $wysiwygFieldName }}"
        wire:key="wysiwyg{{ time().$wysiwygFieldName }}"></textarea>
    </div>
    <script>
      if ((typeof tinyMCE != 'undefined') && (typeof tinyMCE.get("wysiwyg{{ $wysiwygFieldName }}").initialized !== null)) {
          tinyMCE.get("wysiwyg{{ $wysiwygFieldName }}").remove();
          tinyMCE.execCommand("mceToggleEditor", false, "wysiwyg{{ $wysiwygFieldName }}");
      }
    </script>
  </div>