Introduction

CBWIRE is a ColdBox module that uses Livewire and Alpine.js to help you build modern, reactive CFML applications in record time without building backend APIs.

Your First Component

Download and install CommandBox. From your CLI, start CommandBox by typing 'box'. Then run the following:

mkdir cbwire-playground --cd
coldbox create app
install cbwire@4
server start

Let's insert a counter element into our Main layout using wire( "Counter" ).

<!--- ./layouts/Main.cfm --->
<cfoutput>
<!doctype html>
<html>
<body>
    <!--- Insert a counter here --->
    #wire( "Counter" )#
</body>
</html>
</cfoutput>

Let's define our Counter component.

// ./wires/Counter.cfc
component extends="cbwire.models.Component" {
    // Data properties
    data = {
        "counter": 0 // default value
    };
    // Action
    function increment() {
        data.counter++;
    }
}

Finally, define our counter template.

<!--- ./wires/counter.cfm --->
<cfoutput>
    <div>
        <div>Count: #counter#</div>
        <button wire:click="increment">+</button>
    </div>
</cfoutput>

You now have a reactive counter that increments when you click the plus button without any page refreshing or writing JavaScript! 🤯

What!? How?

  1. CBWIRE processes our component's HTML template, data properties, and actions, then displays the component with its initial default values (which begin at 0).

  2. When a user clicks a button, CBWIRE uses Livewire.js to detect the click and initiate a fetch request to communicate with the server.

  3. CBWIRE captures this incoming request and triggers the increment() action, which updates our data property.

  4. Following this, CBWIRE updates the HTML template and includes this revised HTML in the fetch response.

  5. CBWIRE uses Livewire.js to monitor state changes and employs JavaScript and DOM comparison techniques to refresh the display.

Awesome, right?

  • We developed a responsive counter.

  • We avoided writing any JavaScript code.

  • We didn't need to create an API.

  • There was no need for page refreshes.

  • We skipped using webpack or dealing with JavaScript compilation.

  • We stayed entirely within the CFML environment. 🤓

Even Better With Alpine

The example above shows how quickly you can create components that talk to your CFML back-end. However, you often want to use JavaScript for quick UI updates and only send server requests when needed. We don't NEED to send a request to the server to increment our counter, but we might if we want to save it. This is where CBWIRE and Alpine come together beautifully.

Alpine.js is a lightweight JavaScript framework that was built for simplicity and designed to work alongside Livewire ( and therefore CBWIRE ).

Below, let's change our component to use Alpine.js and add a method to save the counter.

// ./wires/Counter.cfc
component extends="cbwire.models.Component" {   
    data = {
        "counter": 0
    };
    function onMount() {
        // Load the counter from the session
        data.counter = session.counter ?: 0;
    }
    function save( counter ) {
        // Save the counter to the session
        session.counter = arguments.counter;
    }
}
<!--- ./wires/counter.cfm --->
<cfoutput>
    <div
        x-data="{
            counter: $wire.counter,
            increment() {
                this.counter++   
            },
            async save() {
                // Call the save method on our component
                await $wire.save( this.counter );
            }
        }"
        wire:ignore.self>
        <div>Count: <span x-text="counter"></span></div>
        <button @click="increment">+</button>
        <button @click="save">Save</button>
    </div>
</cfoutput>
```

As we increment our counter, it's incremented client-side and responds instantly. We only send a request to our server when we click the 'Save' button, which saves the value in our user's session. We use the onMount(), which fires on page load, to set our counter to what's saved in the session.

Notice that we are communicating with our component in Alpine using $wire. This blending of client- and server-side functionality gives you complete control over how and when requests are sent to your server and helps you quickly build modern applications.

CBWIRE is transforming how we build CFML apps; we think you'll love it!

Credits

CBWIRE uses Livewire and Alpine.js for its DOM diffing and client-side functionality. CBWIRE wouldn't exist without the incredible work of Caleb Porzio, the creator of both Livewire and Alpine. CBWIRE was created to bring these excellent tools into the ColdBox and CFML ecosystem.

The CBWIRE module for ColdBox is written and maintained by Grant Copley, Luis Majano, and Ortus Solutions.

Project Support

Please consider becoming one of our lovingly esteemed Patreon supporters.

Last updated