Components

Sections or areas of your app that are reactive to user input.

Components are sections or areas of your site that you want to be reactive to user input. They can be as big or small as you like. For example, you may have a Signup form component that covers multiple steps or a button component that you reuse throughout your app.

Components generally comprise Data Properties, Computed Properties, Actions, and an HTML template.

component extends="cbwire.models.Component" {
    // Data properties
    data = {
        "counter": 0 // default value
    };
    
    // Computed properties
    function isEven() computed {
        return data.counter % 2 == 0;
    }
    
    // Actions
    function decrement() {
        data.counter--;
    }
    
    // Rendering
    function renderIt() {
        return template( "wires.myComponent" );
    }

}
<!--- wires/myComponent.cfm --->
<cfoutput>
    <div>
        <h1>My Component</h1>
        Counter: #count#<br>
        Is Even: #isEven()#
    </div>
</cfoutput>

Components should be placed in a ./wires folder in the project root by default.

Rendering Components

You can render a CBWIRE component using the wire() method.

<!--- ./layouts/Main.cfm --->
<body>
    <div>
        #wire( name="ShowPosts" )#
    </div>
</body>
<!--- ./views/posts/index.cfm --->
<cfoutput>
    <h1>My Posts</h1>
    #wire( name="ShowPosts" )#
</cfoutput>

You can call wire() from within your ColdBox layouts, ColdBox views, and also from your component templates ( nested components ).

External Components

You can render wires from folders and subfolders outside of the default ./wires folder.

<cfoutput>
    <div>
        #wire( name="myFolder.MyComponent" )#
        #wire( name="myFolder.subFolder.MyComponent" )#
    </div>
</cfoutput>

You can also reference components within another ColdBox module by using the @module syntax.

<cfoutput>
    <div>#wire( name="MyComponent@myModule" )#</div>
</cfoutput>

Passing Parameters

You can pass data into a component as an additional argument using wire().

<body>
    <div>
        #wire( name="ShowPost", params={ "post": post } )#
    </div>
</body>

By passing in parameters, you can create reusable UI components that are unique but similar in functionality. For example, you could create a Button component that you use throughout your app.

Using Parameters

Parameters are passed into your component's onMount() method. This is an optional method you can add.

<!--- ./views/posts/index.cfm --->
#wire( "ShowPost", { post: currentPost } )#
// wires/ShowPost.cfc
component extends="cbwire.models.Component" {
    data = {
        "title": ""
    };

    function onMount( params, event, rc, prc ) {
        data.title = params.post.getTitle();
    }
}

CBWIRE only executes onMount() once when the component is initially rendered. It is not executed for subsequent XHR requests of the component.

Auto Populating Data Properties

Properties that you pass into your component as params will be automatically populated if onMount() IS NOT defined, and a matching data property is found.

Passed-in properties must have a data type of string, boolean, numeric, date, array, or struct.

<!--- ./views/posts/index.cfm --->
#wire( name="ShowPost", params={ title: "Some title" } )#
component extends="cbwire.models.Component" {
    data = {
        "title": ""
    };
}
<cfoutput>
    <!--- outputs 'Title: Some title --->
    <div>Title: #title#</div>
</cfoutput>

Nesting Components

You can nest components as much as you need by simply calling wire() from within a component's template.

<!--- ./wires/showposts.cfm --->
<cfoutput>
    <div>
        <h1>Posts</h1>
        #wire( name="AddPostForm" )#
        ...
    </div>
</cfoutput>

You can conditionally render nested components.

// wires/ContactUs.cfc
component extends="cbwire.models.Component" {
    data = {
        "showForm": false
    };
    
    function renderIt() {
        return template( "wires.contactus" );
    }
}
<!--- wires/contactus.cfm --->
<cfoutput>
    <div>
        <cfif showForm>
            #wire( name="ContactForm" )#
        </cfif>    
        <button wire:click="$toggle( 'showForm' )">Toggle form</button>
    </div>
</cfoutput>

You can also pass parameters.

<!--- wires/contactus.cfm --->
<cfoutput>
    <div>
        <cfif showForm>
            #wire(
                name="ContactForm"
                params={
                    sendEmail: true,
                    validateForm: true
                }
            )#
        </cfif>    
    </div>
</cfoutput>

Next Steps

Learn more about templates.

Last updated