Vue show and hide form elements
Published: 2023-10-05 20:07:40

---
title: Vue show and hide form elements
published: true
date: 2023-10-04 07:07:20 UTC
tags: 
canonical_url: https://dcblog.dev/vue-show-and-hide-form-elements
---

## Introduction

When working with forms, it is common to display or conceal various fields based on the options selected.

I'll use Vue to conditionally show or hide form elements.

In this example, I'm going to use an SFC (Single File Component) for ease of us. You'll see this in full in the putting it all together section below.

For this to work it does not need to use a SFC, the HTML and JS will work when used in traditional setups i.e. having JS in javascript blocks and the HTML in a page's body.

## Creating the form elements

Here I have 2 select elements, imagine the `insurance type` should only be displayed if the answer to `Do you want insurance?` was `Yes`

```html
<div>
  <label for="insurance">Do you want insurance?</label>
  <select id="insurance">
    <option value="">Select</option>
    <option>Yes</option>
    <option>No</option>
  </select>
</div>

<div>
  <label for="insuranceType">Insurance Type</label>
  <select id="insuranceType">
    <option value="">Select</option>
    <option>Home</option>
    <option>Travel</option>
  </select>
</div>
```

## Binding Form Elements

First, we need to create variables to bind the elements. Inside a script tag define a const for each element.

```javascript
<script setup>
import {ref} from "vue";

const insurance = ref();
const insuranceType = ref();
</script>
```

Notice that `ref` is imported from Vue, as by default, no directives are available for variables.

`ref()` allows the variable to be reactive, meaning that Vue will monitor it and re-render the action whenever its state changes.

To bind the elements with the variables use `v-model` this creates a 2-way binding.

```html
<div>
  <label for="insurance">Do you want insurance?</label>
  <select id="insurance" v-model="insurance">
    <option value="">Select</option>
    <option>Yes</option>
    <option>No</option>
  </select>
</div>

<div>
  <label for="insuranceType">Insurance Type</label>
  <select id="insuranceType" v-model="insuranceType">
    <option value="">Select</option>
    <option>Home</option>
    <option>Travel</option>
  </select>
</div>
```

## Show / Hide elements select

Now to only show the `insurance type` when the question `Do you want insurance?` is set to `Yes`

This can be accomplished by wrapping the second select in a div and using a `v-show` directive.

```html
<div v-show="insurance === 'Yes'">
```

`v-show` takes a condition that has a truthy value, this must equate to true or false. When true the body of the div will be displayed, otherwise its not rendered to the page.

```html
<div>
<label for="insurance">Do you want insurance?</label>
<select id="insurance" v-model="insurance">
  <option value="">Select</option>
  <option>Yes</option>
  <option>No</option>
</select>
</div>

<div v-show="insurance === 'Yes'">

  <div>
    <label for="insuranceType">Insurance Type</label>
    <select id="insuranceType" v-model="insuranceType">
      <option value="">Select</option>
      <option>Home</option>
      <option>Travel</option>
    </select>
  </div>

</div>
```

Taking this a step further have additional select elements that only appear when an `insurance type` is selected.

I have 2 divs that will only render when the `insuranceType` value matches either `Home` or `Travel` which matches the option selected from the `Insurance Type` select menu.

```html
<div>
  <label for="insuranceType">Insurance Type</label>
  <select id="insuranceType" v-model="insuranceType">
    <option value="">Select</option>
    <option>Home</option>
    <option>Travel</option>
  </select>
</div>

<div v-show="insuranceType === 'Home'">
  <p>Home Details</p>
</div>

<div v-show="insuranceType === 'Travel'">
  <p>Travel Details</p>
</div>
```

## Show or hide checkbox

What about when you have a checkbox that should render markup but only when it's checked, how may that work?

Let's create a input element with a type of checkbox, we'll v-model bind a variable called `addAComment`:

```html
<div>
  <label for="addAComment">Add a comment?</label>
  <input id="addAComment" type="checkbox" v-model="addAComment">
</div>
```

Update the Javascript:

```javascript
const addAComment = ref();
```

Now add a `v-model` to the `checkbox`

Next, create a div with a `v-show` this time it only needs the variable, when the checkbox is set it will have a value otherwise it will not. This is enough to activate `v-show`

```html
<div>
  <label for="addAComment">Add a comment?</label>
  <input id="addAComment" type="checkbox" v-model="addAComment">
</div>

<div v-show="addAComment">

  <div>
    <label for="comment">Comment</label><br>
    <textarea id="comment" v-model="comment"></textarea><br>
    {{ comment }}
  </div>

</div>
```

## Putting it all together

```html
<script setup>
import {ref} from "vue";

const insurance = ref();
const insuranceType = ref();
const addAComment = ref();
const comment = ref();
</script>

<template>

  <div>
    <label for="insurance">Do you want insurance?</label>
    <select id="insurance" v-model="insurance">
      <option value="">Select</option>
      <option>Yes</option>
      <option>No</option>
    </select>
  </div>

  <div v-show="insurance === 'Yes'">

    <div>
      <label for="insuranceType">Insurance Type</label>
      <select id="insuranceType" v-model="insuranceType">
        <option value="">Select</option>
        <option>Home</option>
        <option>Travel</option>
      </select>
    </div>

    <div v-show="insuranceType === 'Home'">
      <p>Home Details</p>
    </div>

    <div v-show="insuranceType === 'Travel'">
      <p>Travel Details</p>
    </div>

  </div>

  <div>
    <label for="addAComment">Add a comment?</label>
    <input id="addAComment" type="checkbox" v-model="addAComment">
  </div>

  <div v-show="addAComment">

    <div>
      <label for="comment">Comment</label><br>
      <textarea id="comment" v-model="comment"></textarea><br>
      {{ comment }}
    </div>

  </div>

</template>

<style>
label {
  padding-right: 5px;
}
</style>
```

### **How v-show differs from v-if**

It's important to note that `v-show` and `v-if` serve similar purposes in controlling element visibility, but they have some key differences:

`v-show`: The element is always rendered in the DOM, but its CSS display property is toggled between none and the original value (e.g., block, inline, etc.) to show or hide it. This makes it more efficient for elements that frequently toggle between visible and hidden states.

`v-if`: The element is conditionally created or destroyed in the DOM. When the condition is false, the element is completely removed from the DOM. This can be more efficient when you have elements that are rarely used or have complex rendering logic, as they are not in the DOM until needed.