In this blade template file, we're setting up a textarea element for TinyMCE, a popular WYSIWYG editor.
<!-- resources\views\form.blade.php -->
<div x-data="tinyMCE(@entangle('content'))" wire:ignore>
<textarea :id="$id('textarea')" placeholder="Write something..." x-ref="tinymce"></textarea>
</div>
We're using Alpine.js to handle the interaction with the editor.
The x-data directives initializes the Alpine component tinyMCE.
The @entangle('content') directive syncs the content variable between Livewire and Alpine.js. This means that any changes made to the content variable in Livewire will be reflected in Alpine.js and vice-versa.
The textarea element is used for the TinyMCE editor.
The $id('textarea') attribute generates a unique ID for the textarea element, ensuring its uniqueness when using frameworks like Alpine.js that might manipulate the DOM.
In this Javascript file, an Alpine.js component named tinyMCE is defined.
// resources\js\app.js
Alpine.data('tinyMCE', (entangle) => ({
value: entangle,
editor:null,
init() {
tinymce.init({
// ...TinyMCE configuration
target: this.$refs.tinymce,
setup: (editor) => {
editor.on('blur', (e) => {
this.value = editor.getContent()
})
editor.on('init', (e) => {
if (this.value != null) {
editor.setContent(this.value)
}
})
this.editor = editor
}
})
// Or, this.editor = tinymce.get(this.$refs.tinymce.id)
if (this.editor ) {
this.$watch('value', (newValue) => {
if (newValue !== this.editor.getContent()) {
this.editor.resetContent(newValue || '')
this.putCursorToEnd()
}
})
}
},
putCursorToEnd() {
this.editor.selection.select(this.editor.getBody(), true)
this.editor.selection.collapse(false)
}
}))
The entangle parameter holds the Livewire state varibale content.
The init() and tinymce.init() initializes the TinyMCE editor on the textarea, and we pass in the configuration options. The target option specifies the textarea to convert into a TinyMCE editor.
In the setup callback, we set up event listeners for the TinyMCE editor. When the editor loses focus (blur event), the value is updated with the content of the editor. Similarly, when the editor is initialized (init event), if there's a value already in the Livewire state (content), it sets the content of the editor.
this.editor holds the TinyMCE editor instance.
The this.$watch('value', ...) method watches for changes in the value (Livewire state) and updates the editor's content accordingly.
The putCursorToEnd() method moves the cursor to the end of the editor content.
To merge the TinyMCE component with other input components to make it more flexible.
<div x-data="tinyMCE(@entangle('content'))" wire:ignore>
<x-input label="Content" type="textarea" name="content" placeholder="Write something..." x-ref="tinymce" />
</div>
<x-input label="Content" type="textarea" name="content" placeholder="Write something..." x-ref="tinymce" :attr="['x-data' => 'tinyMCE($wire.entangle(\'content\'))', 'wire:ignore' => '']" />
Any Question / Leave a comment ?
--- Thank you for your attention! ---