CBWIRE is a ColdBox module that makes building modern, reactive CFML apps a breeze without needing JavaScript frameworks such as Vue or React, and without the hassle of creating unnecessary APIs. In this session, we will learn CBWIRE, how to use it, and why you would want to. We also cover CBWIRE version 3, which brings a greatly simplified component syntax and many other requested features from the community.
Intended Audience
This session is intended for developers looking to build modern applications with less JavaScript. Attendees will need familiarity with ColdBox and CFML.
2. GRANT COPLEY
SPEAKER AT ITB2023
“”If at first you don’t succeed, call it version 1.0.” - Unknown
• Senior Dev @ Ortus
• CFML since Allaire 3.1
• CBWIRE Lead
• Nashville, TN USA
• Proud dad, husband
• Guitar noodler,
beat-maker
3. What is CBWIRE?
■ ColdBox module
■ Simplifies building modern, reactive CFML apps
■ Removes need for JavaScript frameworks
● Vue, React
■ Removes creating unnecessary APIs
■ Built on Livewire
■ Integrates with AlpineJS
4. Let’s Code
■ Create a Counter component
■ Add a button that when clicked increments the counter by 1
6. Components
■ Self-isolated, reactive UI elements
■ Components placed in ./wires folder
■ Components defined as .cfm file ( New Syntax )
■ Single outer element <div> or alternate
■ Contain a HTML block ( <cfoutput> ) and a blueprint ( <cfscript> )
■ Rendered using wire( “ComponentName” ).
10. Data Properties
■ Component state
● Assigned default values
■ Declared using data = { “propertyName”: “defaultValue” }
● CFSCRIPT block
■ Can be modified when Actions are called
■ Tracked by JavaScript
11. Data Properties
■ Values must be JavaScript friendly data types
● Strings, Numbers, Arrays, Structs, Booleans
● No complex CFML data types ( Queries, Object instances )
■ Defined using double or single quotes
■ Reference in HTML using #propertyName#
■ Reference in CFSCRIPT using data.propertyName
12. Let’s Code
■ Create a resetCounter action that sets the counter back to 0
■ Use data.counter = 0
■ Use reset() instead
13. Data Properties & Security
■ Values of data properties are included with each XHR response
■ NEVER store sensitive data
● Passwords
● SSNs
15. Actions
■ Actions
● Modify our component’s state
○ Alter the component’s rendered HTML
● Perform some task ( sending email )
■ Declared as function actionName() {} in the CFSCRIPT block
■ Triggered by Directives
● wire:click=”actionName”
16. Actions
■ Can pass parameters
● wire:click=”actionName( ‘param1’, ‘param2’ )”
■ Parameters are passed to your actions
● function actionName( param1, param2 ) {}
■ Params must be JavaScript friendly data types
17. Let’s Code
■ Add a button that increments the counter by a set amount.
■ Pass the number to your action as a parameter. incrementBy( 100 )
■ Button click increments counter by the given amount
19. Computed Properties
■ Invokes only during component rendering
■ Declare using computed = { propertyName: function () {} } within CFSCRIPT block
■ Return any CFML data type
■ Good for returning derived values
● Queries, ORM objects, etc…
■ Not parsed by JavaScript
20. Computed Properties
■ Reference in HTML using #propertyName()#
■ Reference in Actions using computed.propertyName().
■ Only invoked when called
■ Cached when invoked the first time
● Prevent caching by passing false. #propertyName( false )#
21. Let’s Code
■ Add an isEven() computed property
● Displays if counter value is even or odd
■ Display result on the page
24. onMount
■ Fires only when a component is initially rendered
● Not on subsequent renders
■ Pass parameters when calling wire() that
● Intercept with onMount()
■ wire( “Counter”, { “someParam” : “someValue” } )
27. Data Binding
■ Bind input elements with Data Properties using wire:model
● <input wire:model=”dataProperty” type=”text”>
● <input wire:model=”dataProperty” type=”checkbox” value=”true”>
● <input wire:model=”dataProperty” type=”radio” value=”1”>
● <select wire:model=”dataProperty”>
● <textarea wire:model=”dataProperty”>
■ As the user types or enters data, the component re-renders
28. Let’s Code
■ Create a form component
● Firstname and lastname input fields
■ Use wire:model to bind the inputs to data properties
■ Display the data properties on the page to see the updates
29. Let’s Code
■ Use wire:model.debounce to slow down server updates
■ Use wire:model.lazy to prevent server update until user clicks away from input
■ Use wire:model.defer to prevent server update until an action is called
33. Events & Listeners
■ Components communicate using events and listeners
■ Emit events within actions using emit( “eventName” )
■ Listen for events using listeners = { “eventName” : “action” } in CFSCRIPT block
34. Coding Challenge
■ Emit an event from the Counter component
■ Listen for the event in another component