Conditional Input Fields in Livewire: This or That but Never Both
Tags: webdev, tutorial, laravel, livewire
Published: 2024-03-06 20:07:28

Have you ever had two conflicting pieces of data that you want to collect using the same form? OK, let me back up. I am building a car bazaar website and came across an interesting use case for conditional input fields in Livewire (I am using the TALL stack to build the platform).

Here’s what I needed: a form that collects car details, including whether the car is gas-powered or electric. Once you know the car type, use the form to collect the fuel or tank capacity if it is a gas powered car or the range if it is electric.

It is obvious that it would not make sense to collect the fuel capacity for an electric car or the range for a gas-powered one (OK, there are instances you may want to, but it is not a common scenario.)

## Conditional Livewire Input Fields
To handle the above scenario using Livewire, you need to dynamically show and hide the relevant input fields (the fuel capacity and range inputs) based on the user's selection (gasoline or electric). 

First, we have to run 
```
php artisan make:livewire AddCar
```
to create the Livewire component and its corresponding Blade view. The component will be called “**AddCar.php**” and the Blade view will be “**addcar.blade.php**”. _Your terminal will show you the file paths for the two files once they are created._

The first thing we will do is add the variables we will work with and that we want to save in our database to our component. Here’s a sample of what that might look like.

![Component file with the variables we will save added](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xaxte28kanyn5ptgue72.png)

Livewire has a few interesting directives that we will use for this implementation. But first, we have to build the HTML form.

That is easy enough:

![Basic HTML form with two radio buttons](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lxq1cgg7c08y4ceas1qm.png)

I am using radio buttons here, but you can do this with a select element and it would work the same.

Now, we have to bind each input to a livewire model. For this, we will use the “wire:model” directive and add it to the radio inputs.

![The HTML form with the wire:model binds added](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3rq3u0jr44vo0o6vs5i8.png)

If you have used Livewire before, you may know that “**wire:model**” only binds the data on submit or after taking an action with the form. However, we need the binding to happen immediately so choosing the right input field can work as expected. To make this happen, we instead use “**wire:model.live**”.

## Conditional Rendering
Because we are using “**wire:model.live**” we know that “fuel” will be equal to either “gasoline” or “electric” once we click a radio button. These values are set by the “value” attribute added to our inputs.

Knowing this, we can now use “if” statements to show the right input field.

![Blade template with html form and Livewire binds added](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ybngb0pyhqk9vphgh22t.png)

Here’s what we have added:

1. Conditional Fields: We use two @if statements to conditionally display the input fields based on the selected carType.
If carType is "gasoline", the fuelCapacity input field is displayed.
2. If carType is "electric", the range input field is displayed.
Save Button: Clicking the button triggers the saveCar method (defined in your Livewire component) to save the car information to the database.
 

We have wired the values entered into both fields to “fuelCapacity” and “range” that we can save to the database when adding a new car or editing an existing one.

You can also style the radio buttons, input fields and labels as needed for your project.

Here's how the logic works on my implementation:

![How the implementation works](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y7j05bjr0dy9znq2uzff.gif)

## Saving to Database
When creating your database, ensure the related values are nullable. In this example, fuel capacity and range are nullable. This means one can have a value while the other remains null. 

If you do not do this, you will have an error saying you do not have a default value, you cannot save a null value or a similar error. If you leave the ability to add both, you will create the conflict this whole exercise was supposed to prevent.

Also, always validate all form data before saving it to the database. In this case, you want to ensure "fuel_capacity" is required and a number if you select "gasoline" as fuel, and "range" to be required and number if you choose "electric" as the fuel.

For this, you can use the "required_if" validation rule. Your validations will look something like this.

![Conditional validation](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2kbrvn1evnqtswguzht2.png)

You can [learn more about conditional validation on related fields here](https://laraveldaily.com/post/laravel-conditional-validation-other-fields-examples) or through the [Laravel documentation](https://laravel.com/docs/10.x/validation#rule-required) here.

Have you ever faced a situation where you had to use such an implementation? Let me know below!