2

I have a simple function that manipulates a data between true and false. I use it to make my div hidden and visible like a toggle. I also have a with three element. I found out that I cannot use @click for <option> elements, I need to use @change for my <select>.

But in this way, whenever an is selected, the function is being triggered and my data toggles between true and false. Here is my <select> element;

       <select @change="isDisabled">
          <option>Please select a security type</option>
          <option>No Security</option>
          <option>Personal</option>
          <option>Enterprise</option>
       </select>

IsDisabled function takes a variable and change its values between true and false so my div becomes hidden and visible as follows;

<div v-if="noSecurity">something</div>

But here is the thing, I only want to trigger the function when the user select the "No Security" option. Now it's being triggered whenever I select an option, so it turned out to be some kind of a toggle. But I want to hide the div when I select the "No Security" option and show the div if something different is selected. What should I do?

3 Answers 3

4

I've made a CodeSandbox where you could see the result :

https://codesandbox.io/s/magical-meitner-63eno?file=/src/App.vue

But here is the explanation:

<template>
  <section>
    <select @change="isDisabled">
      <option>Please select a security type</option>
      <option>No Security</option>
      <option>Personal</option>
      <option>Enterprise</option>
    </select>
    <div v-if="noSecurity">You Choose no security, that's dangerous !</div>
  </section>
</template>

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

export default {
  name: "App",
  data() {
    return {
      noSecurity: false,
    };
  },
  methods: {
    isDisabled(e) {
      console.log("e", e.target.value);
       if (e.target.value === "No Security") {
        // do your change
        return (this.noSecurity = !this.noSecurity);
      }
     // to allow reset if another option is selected
      if (this.noSecurity) {
        return this.noSecurity = false;
      }
    },
  },
};
</script>

Basically when you use the @change handler, your function will receive an event, in this event you can catch the target value with event.target.value.

Doing so, you do a condition if the value is equal to No Security (so the selected item), you change your state, if it's not No Security, you do nothing, or you do something else you would like to do.

Appart from that, I advice you to change your method name isDisabled to a global convention name like handleChange, or onChange.

Pass id values in your option so when you get the select event you're clear that No security or whatver the name you would like to change will be the same.

Because if one day you change No security to another name, you have to update all your conditions in your app. Try to avoid conditions with strings values like this if you can.

<option value="1">No Security</option> // :value="securityType.Id" for example if coming from your database
<option value="2">Personal</option>
<option value="3">Enterprise</option>

then in your function it will be

if (e.target.value === noSecurityId) {
 // do your change
 this.noSecurity = !this.noSecurity;
}
//...
Sign up to request clarification or add additional context in comments.

Comments

3

There's no need for the additional noSecurity variable. Create your select with v-model to track the selected value. Give each option a value attribute.

<select v-model="selected">
  <option value="">Please select a security type</option>
  <option value="none">No Security</option>
  <option value="personal">Personal</option>
  <option value="enterprise">Enterprise</option>
</select>

Check that value:

<div v-if="selected === 'none'">something</div>

You can still use the noSecurity check if you prefer by creating a computed:

computed: {
  noSecurity() {
    return this.selected === 'none';
  }
}

Here's a demo showing both:

new Vue({
  el: "#app",
  data() {
    return {
        selected: ''
    }
  },
  computed: {
    noSecurity() {
      return this.selected === 'none';
    }
  },
  methods: {},
  created() {}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <select v-model="selected">
    <option value="">Please select a security type</option>
    <option value="none">No Security</option>
    <option value="personal">Personal</option>
    <option value="enterprise">Enterprise</option>
  </select>

  <div v-if="selected === 'none'">something</div>
  <div v-if="noSecurity">something</div>
</div>

Comments

1

Is using v-model instead of using a method is option for you? If it is, please try the following:

HTML:

<div id="hello-vue" class="demo">
  <select v-model="security">
    <option>Please select a security type</option>
    <option>No Security</option>
    <option>Personal</option>
    <option>Enterprise</option>
  </select>
  <div v-if="security=='No Security'">something</div>
</div>

JS:

const HelloVueApp = {
  data() {
    return {
      security: undefined
    }
  }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.