How to open other input block by selecting other option in VueJs
Tags: vue, javascript, webdev, codenewbie
Published: 2021-12-04 16:40:56

Hello artisan,

In today's blog I am going to show you how we can open a other option block by selecting other option in various input type like radio, select, checkbox. 

This is helpful when we do not have options listed in given options and we want you put our own answer/option in that.

So let's begin the code.

First we need to create component named as `ExampleComponent.vue` and add the below code

```js
<template>
  <div class="bg-white p-7 shadow h-screen mx-auto">
    <h2 class="text-center my-2 p-3 border-b">Example</h2>
    <div class="w-full border shadow">
      <select
        v-model="form.data"
        class="border border-indigo-300 rounded-lg shadow-lg px-3 py-2 w-1/4"
        @change="onSelectChange(form.data)"
      >
        <option :value="null" selected>Select Option</option>
        <option
          v-for="option in options"
          :key="option.id"
          :value="getOptionValue(option)"
        >
          {{ getOptionDisplayName(option) }}
        </option>
      </select>
      <input
        id="otherFiled"
        v-model="form.others"
        type="text"
        class="border px-4 py-2 my-4 border border-indigo-300 rounded-lg shadow-lg w-1/4"
        placeholder="Please specify your option"
        style="display: none"
      />
      {{ form.data }} - {{ form.others }}
      <div class="border-t mt-4 py-4">
        <form @submit.prevent="saveCheckboxValues">
          <input v-model="checkedFruits.option" type="checkbox" value="apple" />
          <label>apple</label>
          <input
            v-model="checkedFruits.option"
            type="checkbox"
            value="orange"
          />
          <label>orange</label>
          <input v-model="checkedFruits.option" type="checkbox" value="grape" />
          <label>grape</label>
          <input
            v-model="checkedFruits.other"
            type="checkbox"
            value="other"
            @change="getCheckedValue(checkedFruits.other)"
          />
          <!-- @change="getCheckedValue($event)" -->
          <label>{{ getRadioOtherOption("other") }}</label>
          <input
            id="otherCheckedOption"
            v-model="checkedFruits.other"
            type="text"
            class="border px-4 py-2 my-4 border border-indigo-300 rounded-lg shadow-lg w-1/4"
            placeholder="Please specify your option"
            style="display: none"
          />
          <button
            type="submit"
            class="border shadow border-indigo-300 p-2 ml-6 rounded-lg"
          >
            Save
          </button>
        </form>
      </div>
      <p>{{ checkedFruits }}</p>

      <div class="border-t mt-4 py-4">
        <form @submit.prevent="saveRadioValue">
          <input v-model="selectedColors.value" type="radio" value="yellow" />
          <label>yellow</label>
          <input v-model="selectedColors.value" type="radio" value="orange" />
          <label>orange</label>
          <input v-model="selectedColors.value" type="radio" value="pink" />
          <label>pink</label>
          <input
            v-model="selectedColors.value"
            type="radio"
            value="other"
            @change="getRadioOptionValue(selectedColors.value)"
          />
          <label>{{ getRadioOtherOption("other") }}</label>
          <input
            id="otherOption"
            v-model="selectedColors.value"
            type="text"
            class="border px-4 py-2 my-4 border border-indigo-300 rounded-lg shadow-lg w-1/4"
            placeholder="Please specify your option"
            style="display: none"
          />
          <button
            type="submit"
            class="border shadow border-indigo-300 p-2 ml-6 rounded-lg"
          >
            Save
          </button>
        </form>
      </div>
      <p>{{ selectedColors }}</p>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      options: ["yes", "no", "both", "other | Other (please specify)"],
      form: {
        data: [],
        others: [],
      },
      checkedFruits: {
        option: [],
        other: "",
      },
      selectedColors: {
        value: "",
        // other: '',
      },
    };
  },
  methods: {
    // this fn will only change the display name if it has other field
    getOptionDisplayName(option) {
      return option.replace("other | ", "");
    },

    // checks if value starts other | option so we can replace it with other so that we can use it for other answers by users
    getOptionValue(option) {
      if (option.startsWith("other | ")) {
        return "other";
      }
      return option;
    },

    // if selected option has other option selected then it will display other box and its value will be stored in other array
    onSelectChange(data) {
      if (data === "other") {
        document.getElementById("otherFiled").style.display = "block";
      } else {
        document.getElementById("otherFiled").style.display = "none";
      }
    },
    // ex radio other option
    getRadioOtherOption(option) {
      if (option === "other") {
        return "Other";
      } else {
        return option;
      }
    },

    getRadioOptionValue(option) {
      if (option === "other") {
        document.getElementById("otherOption").style.display = "block";
      } else {
        document.getElementById("otherOption").style.display = "none";
      }
    },

    getCheckedValue(option) {
      console.log(option);
      if (option === true) {
        document.getElementById("otherCheckedOption").style.display = "block";
      } else {
        document.getElementById("otherCheckedOption").style.display = "none";
      }
    },
    saveRadioValue() {
      this.$inertia.post(this.route("ex.store"), this.selectedColors);
    },
    saveCheckboxValues() {
      this.$inertia.post(
        this.route("example.storeCheckbox"),
        this.checkedFruits
      );
    },
  },
};
</script>

```

Now add this component to `App.vue` as given below.

```javascript
<template>
  <div id="app">
    <ExampleComponent />
  </div>
</template>

<script>
import ExampleComponent from "./components/ExampleComponent";

export default {
  name: "App",
  components: {
    ExampleComponent,
  },
};
</script>

<style>
#app {
  font-family: "Avenir", Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>
```

You can check the functionality on given code block.

{% codesandbox open-other-options-on-various-input-type-mre4c %}

Happy Reading.. :heart: :unicorn: