# wire:model

The `wire:model` directive creates two-way data binding between form inputs and component data properties. As users type or interact with form elements, the values are automatically synchronized with your server-side data, enabling reactive forms without manual event handling.

## Basic Usage

This user profile form demonstrates `wire:model` with various input types and live updating:

{% tabs %}
{% tab title="BoxLang" %}

```javascript
// wires/UserProfile.bx
class extends="cbwire.models.Component" {
    data = {
        "name": "",
        "email": "",
        "bio": "",
        "notifications": true,
        "preferences": [],
        "country": ""
    };

    function save() {
        // Save user profile
        sleep(1000);
    }
}
```

{% endtab %}

{% tab title="CFML" %}

```javascript
// wires/UserProfile.cfc
component extends="cbwire.models.Component" {
    data = {
        "name" = "",
        "email" = "",
        "bio" = "",
        "notifications" = true,
        "preferences" = [],
        "country" = ""
    };

    function save() {
        // Save user profile
        sleep(1000);
    }
}
```

{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="BoxLang" %}

```html
<!-- wires/userProfile.bxm -->
<bx:output>
<form wire:submit="save">
    <input type="text" wire:model.live.debounce.300ms="name" placeholder="Name">
    <input type="email" wire:model.blur="email" placeholder="Email">
    <textarea wire:model="bio" placeholder="Bio"></textarea>
    
    <input type="checkbox" wire:model="notifications"> Email notifications
    
    <input type="checkbox" value="updates" wire:model="preferences"> Product updates
    <input type="checkbox" value="marketing" wire:model="preferences"> Marketing
    
    <select wire:model="country">
        <option value="">Select country</option>
        <option value="US">United States</option>
        <option value="CA">Canada</option>
    </select>
    
    <button type="submit">Save Profile</button>
</form>
</bx:output>
```

{% endtab %}

{% tab title="CFML" %}

```html
<!-- wires/userProfile.cfm -->
<cfoutput>
<form wire:submit="save">
    <input type="text" wire:model.live.debounce.300ms="name" placeholder="Name">
    <input type="email" wire:model.blur="email" placeholder="Email">
    <textarea wire:model="bio" placeholder="Bio"></textarea>
    
    <input type="checkbox" wire:model="notifications"> Email notifications
    
    <input type="checkbox" value="updates" wire:model="preferences"> Product updates
    <input type="checkbox" value="marketing" wire:model="preferences"> Marketing
    
    <select wire:model="country">
        <option value="">Select country</option>
        <option value="US">United States</option>
        <option value="CA">Canada</option>
    </select>
    
    <button type="submit">Save Profile</button>
</form>
</cfoutput>
```

{% endtab %}
{% endtabs %}

## What wire:model Does

When you add `wire:model` to an input, CBWIRE automatically:

* **Binds Data**: Creates two-way binding between input values and component properties
* **Syncs Changes**: Updates server data when users interact with form elements
* **Preserves State**: Maintains input values across component re-renders
* **Handles Types**: Automatically manages different input types (text, checkbox, select, etc.)

## Available Modifiers

The `wire:model` directive supports these modifiers:

* **Live**: `.live` - Sends updates as user types (with 150ms debounce)
* **Blur**: `.blur` - Only sends updates when input loses focus
* **Change**: `.change` - Only sends updates on change event
* **Lazy**: `.lazy` - Prevents server updates until an action is called
* **Debounce**: `.debounce.Xms` - Customizes debounce timing (e.g., `.debounce.500ms`)
* **Throttle**: `.throttle.Xms` - Throttles network requests by X milliseconds
* **Number**: `.number` - Casts text input to integer on server
* **Boolean**: `.boolean` - Casts text input to boolean on server
* **Fill**: `.fill` - Uses initial HTML `value` attribute during page load

Combine modifiers as needed: `wire:model.live.debounce.500ms="username"`

## Input Types

### Text Inputs

```html
<input type="text" wire:model="name">
<input type="email" wire:model="email">
<input type="password" wire:model="password">
```

### Textarea

```html
<textarea wire:model="content"></textarea>
```

{% hint style="warning" %}
Don't initialize textarea content with the property value in the template:

```html
<!-- ❌ Don't do this -->
<textarea wire:model="content">#content#</textarea>

<!-- ✅ Do this instead -->
<textarea wire:model="content"></textarea>
```

{% endhint %}

### Single Checkbox

```html
<input type="checkbox" wire:model="receiveUpdates">
```

The checkbox will be checked if the data property is `true`, unchecked if `false`.

### Multiple Checkboxes

{% tabs %}
{% tab title="BoxLang" %}

```javascript
// Component data
data = {
    "selections": []
};
```

{% endtab %}

{% tab title="CFML" %}

```javascript
// Component data
data = {
    "selections" = []
};
```

{% endtab %}
{% endtabs %}

```html
<input type="checkbox" value="email" wire:model="selections">
<input type="checkbox" value="sms" wire:model="selections">
<input type="checkbox" value="notification" wire:model="selections">
```

### Radio Buttons

```html
<input type="radio" value="yes" wire:model="sendEmail">
<input type="radio" value="no" wire:model="sendEmail">
```

### Select Dropdowns

```html
<select wire:model="state">
    <option value="AL">Alabama</option>
    <option value="AK">Alaska</option>
    <option value="AZ">Arizona</option>
</select>
```

Livewire automatically adds the `selected` attribute to the matching option.

### Dynamic Select Options

{% tabs %}
{% tab title="BoxLang" %}

```javascript
function getStates() {
    return queryExecute("select id, label from states");
}
```

{% endtab %}

{% tab title="CFML" %}

```javascript
function getStates() {
    return queryExecute("select id, label from states");
}
```

{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="BoxLang" %}

```html
<select wire:model="state">
    <option disabled value="">Select a state</option>
    <bx:loop array="#getStates()#" index="state">
        <option value="#state.id#">#state.label#</option>
    </bx:loop>
</select>
```

{% endtab %}

{% tab title="CFML" %}

```html
<select wire:model="state">
    <option disabled value="">Select a state</option>
    <cfloop array="#getStates()#" index="state">
        <option value="#state.id#">#state.label#</option>
    </cfloop>
</select>
```

{% endtab %}
{% endtabs %}

### Dependent Dropdowns

Use `wire:key` to ensure dependent dropdowns update properly:

{% tabs %}
{% tab title="BoxLang" %}

```html
<!-- State selector -->
<select wire:model.live="state">
    <option disabled value="">Select a state</option>
    <bx:loop array="#getStates()#" index="state">
        <option value="#state.id#">#state.label#</option>
    </bx:loop>
</select>

<!-- City selector (depends on state) -->
<select wire:model.live="city" wire:key="#state#">
    <option disabled value="">Select a city</option>
    <bx:loop array="#getCities(state)#" index="city">
        <option value="#city.id#">#city.label#</option>
    </bx:loop>
</select>
```

{% endtab %}

{% tab title="CFML" %}

```html
<!-- State selector -->
<select wire:model.live="state">
    <option disabled value="">Select a state</option>
    <cfloop array="#getStates()#" index="state">
        <option value="#state.id#">#state.label#</option>
    </cfloop>
</select>

<!-- City selector (depends on state) -->
<select wire:model.live="city" wire:key="#state#">
    <option disabled value="">Select a city</option>
    <cfloop array="#getCities(state)#" index="city">
        <option value="#city.id#">#city.label#</option>
    </cfloop>
</select>
```

{% endtab %}
{% endtabs %}

### Multi-Select Dropdowns

```html
<select wire:model="states" multiple>
    <option value="AL">Alabama</option>
    <option value="AK">Alaska</option>
    <option value="AZ">Arizona</option>
</select>
```

{% hint style="info" %}
By default, `wire:model` only sends updates when actions are performed. Use `wire:model.live` for real-time validation or immediate server updates as users type.
{% endhint %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://cbwire.ortusbooks.com/template-directives/wire-model.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
