DEV Community

Cover image for Conditional Input Fields in Livewire: This or That but Never Both
Kennedy Gitahi
Kennedy Gitahi

Posted on • Updated on

Conditional Input Fields in Livewire: This or That but Never Both

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
Enter fullscreen mode Exit fullscreen mode

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

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

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

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

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

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

You can learn more about conditional validation on related fields here or through the Laravel documentation here.

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

Top comments (2)

Collapse
 
dimitrim profile image
Dimitri Mostrey

The conditional radio will work. Extracting the table fields in their own properties is the correct way as well. Your proposal is elegant and easy to read/maintain. The other way is with actions, which is sometimes an overkill.

It seems your code is not 'LiveWire saveable' because there is no validation. I guess you probably know that. Hence the title of your post.

Collapse
 
kengitahi profile image
Kennedy Gitahi

Yes, I did not add the validation because the focus was on the input functionality. Perhaps I should have noted the validation when mentioning saving the data to the database