xslain/livewire-jodit-text-editor
Install the package:
composer require xslain/livewire-jodit-text-editor
Include Jodit assets in your layout or view (as shown in README):
<link rel="stylesheet" href="//unpkg.com/jodit@4.1.16/es2021/jodit.min.css">
<script src="//unpkg.com/jodit@4.1.16/es2021/jodit.min.js"></script>
Use the component in a Livewire blade view:
<livewire:jodit-editor wire:model="content" />
wire:model binds the editor content to a Livewire property (e.g., $content).Define the property in your Livewire component:
public $content = '';
BlogPostEditor) with a $content property.<livewire:jodit-editor wire:model="content" /> in the blade view.public function savePost()
{
$this->validate(['content' => 'required']);
// Save to database (e.g., $this->post->content = $this->content)
}
Dynamic Configuration:
Customize editor options via the config prop:
<livewire:jodit-editor
wire:model="content"
config='{"buttons": ["bold", "italic", "underline", "image"]}'
/>
@json):
config='@json($editorConfig)'
Integration with Forms:
wire:model for two-way binding.protected $rules = ['content' => 'required|min:10'];
Handling Images/Uploads:
uploadImage callback (via config):
config='{
"uploadImage": {
"url": "/api/upload",
"params": {"token": "{{ auth()->token() }}"}
}
}'
StoreImageAction).Reusable Components:
class RichPostEditor extends JoditEditor
{
public function mount()
{
$this->config = [
'buttons' => ['bold', 'strike', 'quote', 'code'],
'enter' => 'p',
];
}
}
<livewire:rich-post-editor wire:model="postContent" />
Livewire Events:
contentChanged):
<livewire:jodit-editor
wire:model="content"
@content-changed="handleContentChange"
/>
public function handleContentChange()
{
$this->emit('editor:content-changed', $this->content);
}
Asset Loading Order:
@stack('scripts') in layouts to avoid race conditions:
@stack('scripts')
@push('scripts')
<script src="//unpkg.com/jodit@4.1.16/es2021/jodit.min.js"></script>
@endpush
Livewire 3 Compatibility:
composer require livewire/livewire:^3.0
Configuration Overrides:
config='@json(array_merge([
"buttons" => ["bold", "italic"],
"toolbarButtonSize" => "small",
], $this->defaultConfig))'
Image Uploads:
php artisan serve --host=0.0.0.0
Storage facade:
public function uploadImage(Request $request)
{
$path = $request->file('file')->store('uploads');
return response()->json(['location' => $path]);
}
Performance:
config='{
"plugins": {
"table": { "lazy": true },
"file": { "lazy": true }
}
}'
Console Errors:
wire:model bindings with:
console.log(Livewire.find('component-id').data);
Livewire Logs:
config/livewire.php:
'log' => env('APP_DEBUG'),
storage/logs/livewire.log for binding issues.Configuration Validation:
Custom Plugins:
config:
config='{
"plugins": {
"customPlugin": {
"path": "/path/to/plugin.js",
"init": function(editor) { /* logic */ }
}
}
}'
Theming:
.jodit classes in your global CSS:
.jodit .jodit-toolbar {
background: #f0f0f0;
}
Server-Side Processing:
use Illuminate\Support\Str;
$this->content = Str::of($this->content)->replaceMatches('/<script.*?>/i', '');
laravel-html-sanitizer for stricter rules.Fallback for Non-JS Users:
@if(config('app.debug') && !request()->wantsJson())
<textarea wire:model="content">{{ $content }}</textarea>
@endif
```markdown
## Additional Notes
- **Testing**: Use Laravel’s `Livewire\Livewire::test()` to simulate editor interactions:
```php
Livewire::test(JoditEditor::class)
->set('content', '<p>Test</p>')
->assertSet('content', '<p>Test</p>');
<link rel="stylesheet" href="{{ asset('vendor/jodit/jodit.min.css') }}">
<script src="{{ asset('vendor/jodit/jodit.min.js') }}"></script>
npm run prod # If using Laravel Mix
How can I help you explore Laravel packages today?