Home

4 minute read

Using Ace Editor with Livewire

Tony Lea

Using Ace Editor with Livewire

Using the Ace Editor, we can easily add a code editor inside of any application built with Laravel and Livewire.

Here is a quick example of what we'll be creating in this tutorial.

ace-editor-livewire.gif

Let's start off from the very beginning and create a new Laravel Livewire application.

Install a new Livewire app

First we'll need to create a new laravel application using the Laravel installer.

laravel new ace-livewire

After installing our new laravel app we will install livewire:

composer require livewire/livewire

Next, we'll add the Livewire styles and scripts to the default welcome.blade.php file with the following contents:

<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">

        <title>Ace Editor and Livewire</title>

        @livewireStyles
    </head>
    <body class="antialiased">

        <script src="js/app.js"></script>
        @livewireScripts
    </body>
</html>

Great! Now, that we have our new livewire application installed we can add the Ace Editor to our project.

Installing Ace Editor

We can install the Ace Editor via NPM with the following command:

Checkout our latest product - the ultimate tailwindcss page creator 🚀
npm i ace-builds

Next, we'll want to include the ace-editor library inside of our resources/js/app.js file, and we'll also want to create an editor instance if we have an element with an id="editor":

import 'ace-builds';
import 'ace-builds/webpack-resolver';

let editorElement = document.getElementById('editor');

// If we have an editor element
if(editorElement){
    // pass options to ace.edit
    let editor = ace.edit(document.getElementById('editor'), {
        mode: "ace/mode/html",
        theme: "ace/theme/dracula",
        maxLines: 50,
        minLines: 10,
        fontSize: 18
    })
    // use setOptions method to set several options at once
    editor.setOptions({
        autoScrollEditorIntoView: true,
        copyWithEmptySelection: true,
    });
}

Because we are creating this from a blank Laravel application we will also need to install all the default NPM packages.

npm install

Next, we can add a new <div id="editor"></div> element to our welcome.blade.php file:

<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">

        <title>Ace Editor and Livewire</title>

        @livewireStyles
    </head>
    <body class="antialiased">

        <script src="js/app.js"></script>
        @livewireScripts
    </body>
</html>

And, if we load our application we'll see a Code Editor in front of us.

ace-editor.gif

Creating our Livewire Editor Component

Finally we'll want to create a new livewire component that utilizes our code editor. We'll start off by creating a new component:

php artisan make:livewire editor

This will create our livewire component inside of app/Http/Livewire/Editor.php, and our component view located at resources/views/livewire/editor.blade.php.

Inside of our Component class we will add the following code, which contains 2 event listeners codeUpdate and showCode:

<?php

namespace App\Http\Livewire;

use Livewire\Component;

class Editor extends Component
{
    public $code = '';

    protected $listeners = [
        'codeUpdated',
        'showCode'
    ];

    public function codeUpdated($payload)
    {
        $this->code = $payload['code'];
    }

    public function showCode(){
        dd($this->code);
    }

    public function render()
    {
        return view('livewire.editor');
    }
}

The codeUpdated function will update our $code variable in our component, and the showCode function is just used for debugging purposes and will die and dump the value of $code.

Next, inside of our component view, we can add the following code:

<div>
    <div wire:ignore id="editor"></div>
    <button onclick="window.clear()">Clear</button>
    <button onclick="window.livewire.emit('showCode')">Show The Code</button>
    <pre><code>{{ $code }}</code></pre>
</div>

Inside our component view we have 2 buttons. One button to Clear the contents of the editor and the other to Show The Code. We'll also output the value of $code inside of some <pre><code> tags.

In our app.js, we'll need to add our javascript function to call our codeUpdated function and to clear the contents of the editor:

editor.on("change", function(e){
    window.livewire.emit('codeUpdated', { code : editor.getValue() });
});

window.clear = function(){
    editor.session.setValue('');
}

Here is our full app.js file:

import 'ace-builds';
import 'ace-builds/webpack-resolver';

let editorElement = document.getElementById('editor');

// If we have an editor element
if(editorElement){
    // pass options to ace.edit
    let editor = ace.edit(document.getElementById('editor'), {
        mode: "ace/mode/html",
        theme: "ace/theme/dracula",
        maxLines: 50,
        minLines: 10,
        fontSize: 18
    })
    // use setOptions method to set several options at once
    editor.setOptions({
        autoScrollEditorIntoView: true,
        copyWithEmptySelection: true,
    });

    editor.on("change", function(e){
        window.livewire.emit('codeUpdated', { code : editor.getValue() });
    });

    window.clear = function(){
        editor.session.setValue('');
    }
}

Lastly, we need to add our component to our welcome.blade.php file:

<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">

        <title>Ace Editor and Livewire</title>

        @livewireStyles
    </head>
    <body class="antialiased">

        <livewire:editor></livewire:editor>

        <script src="js/app.js"></script>

        @livewireScripts
    </body>
</html>

If we load our application we can now see that we have a code editor that updates our Livewire component as the code is changed.

Here is the final demo output of our application.

ace-editor-livewire.gif

I hope this helps you out when you need to implement a code editor in your Laravel Livewire application 🤘