Display or conceal HTML content based on the input's property type

Looking to toggle the visibility of an icon on my input based on the prop type.

If the type is set to password, the icon will be displayed for toggling between visible and hidden password; if the type is not password, the icon should be hidden by setting v-show to false.

Below is the HTML code snippet with v-show showPwIcon used to control the visibility of the icon:

<input
  ref="textField"
  v-model="textField"
  :placeholder="placeholder"
  :type="type"
>
<span v-show="showPwIcon" @click="switchVisibility">
  <i :class="[pwIcon ? 'ri-eye-line' : 'ri-eye-off-line']"></i>
</span>

And here is the JS code, without CSS included for simplicity, where v-show showPwIcon is initially set to false:

export default {
  props:{
    placeholder: {
      type: String,
      value: ''
    },
    type: {
      type: String,
      value: '',
      required: true
    }
  },
  data() {
    return {
      textField: '',
      showPwIcon: false,
      pwIcon: true
    }
  },
  watch: {
    type: function (password) {
      const inputType = this.$refs.textField.type
      if (inputType === 'password') {
        this.showPwIcon = true
      } else {
        this.showPwIcon = false
      }
    }
  },
  methods: {
    switchVisibility() {
      this.$emit('input', {
        type: this.$refs.textField.type = this.$refs.textField.type === 'password' ? 'text' : 'password'
      })
      if (this.$refs.textField.type === 'password') {
        this.pwIcon = true
      } else {
        this.pwIcon = false
      }
    }
  }
}

The issue I'm facing currently is:

When the type is set to text, the icon does not show up.

<text-field-icon
  placeholder="Placeholder here"
  type="text"
/>

Even when the type is set to password, the v-show is not getting triggered.

<text-field-icon
  placeholder="Placeholder here"
  type="password"
/>

I've tried to monitor the input type using this.$refs.textField.type but facing difficulties in getting the correct input type.

For a sample code, check out https://codesandbox.io/s/vue-tailwind-template-dteq4

Any suggestions or ideas?

Answer №1

To achieve this, we do not need to use the watcher or $refs.

It is important to remember that $refs do not reactively update.

<input
  v-model="textField"
  :placeholder="placeholder"
  :type="inputType"
>
<span v-show="showPwIcon" @click="switchVisibility">
  <i :class="[pwIcon ? 'ri-eye-line' : 'ri-eye-off-line']"></i>
</span>
export default {
  props: {
    placeholder: {
      type: String,
      value: ""
    },
    type: {
      type: String,
      value: "",
      required: true
    }
  },
  data() {
    return {
      textField: "",
      pwIcon: false,
      inputType: this.type
    };
  },
  computed: {
    showPwIcon() {
      return this.type === "password";
    }
  },
  methods: {
    switchVisibility() {
      this.inputType = this.inputType === "password" ? "text" : "password";
      this.$emit("input", {
        type: this.inputType
      });
      this.pwIcon = this.inputType === "text";
      console.log(this.inputType, this.pwIcon);
    }
  }
};

Answer №2

For a simpler solution, consider the concept of UI = Function(State). Instead of accessing the type directly from the input element using this.$refs.textField.type, rely on the type prop.

Here is a straightforward approach:

<input
  v-model="textField"
  :placeholder="placeholder"
  :type="(showPwIcon && !pwIcon) ? 'text' : type">

<span v-show="showPwIcon" @click="switchVisibility">
  <i :class="[pwIcon ? 'ri-eye-line' : 'ri-eye-off-line']"></i>
</span>
export default {

  // Declaration of Props and Data...

  watch: {
    type: function (newVal) {
      if (newVal === 'password') {
        this.showPwIcon = true

        // Initially set password visibility to false
        this.pwIcon = true
      } else {
        this.showPwIcon = false
      }
    }
  },

  methods: {
    switchVisibility() {

      // Toggle Visibility
      this.pwIcon = !this.pwIcon;

      this.$emit('input', {
        type: this.pwIcon ? 'text' : 'password'
      })
    }
  }
}

Keep in mind that your component instance should be the source of truth, not the DOM. Using $refs to read values creates a secondary source of truth. $refs is more suitable for non-Vue compatible libraries like Charting or Video players where direct interaction with the DOM is needed.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Steps for creating a personalized @click function for a <router-link> element

I am currently working on a VueJS 3 application that includes a router-link element. I am trying to implement a custom click-handler where instead of redirecting to the href URL, it will trigger a function in my pinia-store. <router-link ...

`Trigger a page reload when redirecting`

Currently, I am tackling some bug fixes on an older Zend Framework 1.10 project and encountering difficulties with redirection and page refresh. The issue: The task at hand is to make an AJAX call, verify if a person has insurance assigned, and prevent de ...

Is there a way to identify the top five elements that are most frequently occurring in the array?

I've successfully found the element that appears the most in an array, but now I'm facing a new challenge where I need to identify the top 5 elements that appear most frequently. Here is the array: [ "fuji", "acros", &q ...

Is it possible to activate the jQuery .click() function for a button with specific text?

Here's a dilemma I'm facing: $('.add_to_cart span:contains("Choose a Size")').click(function() { console.log("it has been clicked") }); <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></s ...

Is there a way to convert a button into clickable text that performs the same function as the original button?

Seeking a solution to transform a button into clickable text with the same functionality. Explored resources like Google, StackOverFlow, and Youtube for answers. This is the current code snippet representing the button: <button onclick="mainApp.l ...

Do you notice a discrepancy in the number returned by Javascript's Date.getUTCDate() when the time component is set to

Consider the following code snippet: const d = new Date('2010-10-20'); console.log(d.getUTCDate()); If you run this, the console will output 20. However, if you modify the code like so: const d = new Date('2010-10-20'); d.setHours(0, ...

What is the most effective method for creating posts, pages, and their corresponding URLs using Next.js and MongoDB

Here's a glimpse of my MongoDB data: { "_id": { "$oid": "630f3c32c1a580642a9ff4a0" }, "title": "this is a title", "paragraph": "this is a paragraph" } Now, let's t ...

setting a deadline for rendezvous with quasar version 1

Utilizing the quasar date component with restricted dates poses a challenge. In order to accomplish this, the documentation suggests utilizing the options prop which should be provided with an array or function. <template> <div class="q-pa- ...

Access information through token-based verification

Just starting out in this area of development, a colleague shared some information with me on how to retrieve the database. I'm feeling a bit lost as to what to do next. curl -X GET -H "Authorization: Token token=xxxxxxxxxxxxxxxxxxxxxxxxx" "https://w ...

Synchronizing client information in real-time: tips, tricks, and expert advice

Currently, I am developing a PHP backend and utilizing JS/Jquery for the front end of an application that aims to facilitate near real-time communication among users. My main concern right now is determining the most effective approach to achieve this goal ...

multiple elements sharing identical CSS styling

For each component, I made separate CSS files and imported them accordingly. However, despite the individual styling efforts, all components seem to have the same appearance. I specifically worked on styling an image differently for two components, but w ...

The removal of an object becomes unsuccessful when objects with lower indices have been deleted beforehand

Attempting to construct a multi-layer object representing a program; check out my progress here http://codepen.io/Irish1/pen/lbjdw Imagine adding 3 weeks, each with 3 days, and each day having 3 sessions. Removing these objects is feasible as long as caut ...

"Combining HTML, PHP, and JavaScript for Dynamic Web

Here is the PHP function that retrieves the visitor's profile image thumbnail: <?php echo voip_profile_image($visitorid,'thumb'); ?> The issue lies in the fact that $visitorid is stored in JavaScript under the sRemoteid parameter. Wi ...

What methods can I use to conceal #! from showing on the browser's address bar?

Imagine you have the below link: www.someurl.com/#!?page=index How would you convert it into one of these options: www.someurl.com/#!/index (using mod_rewrite) www.someurl.com/ajax/index (also using mod_rewrite, but replacing #! with ajax) www.someurl. ...

Using the fetch method to consume a RapidAPI JSON response

Currently, I am in the process of learning React Native and have initiated a project for that purpose. In this project, I have integrated RapidAPI (link: ) to fetch necessary data. Upon hitting the API, I receive a 200OK status, but unfortunately, I am fa ...

The issue of AngularJS failing to bind object properties to the template or HTML element

Just dipping my toes into angularJS, following Todd Motto's tutorials, and I'm having trouble displaying object properties on the page. function AddCurrentJobs($scope){ $scope.jobinfo = [{ title: 'Building Shed', description: ...

Combining a JavaScript NPM project with Spring Boot Integration

Recently, I built a frontend application in React.js using NPM and utilized IntelliJ IDEA as my IDE for development. Additionally, I have set up a backend system using Spring Boot, which was also developed in IntelliJ IDEA separately. My current goal is t ...

Executing a NestJs cron job at precise intervals three times each day: a guide

I am developing a notifications trigger method that needs to run three times per day at specific times. Although I have reviewed the documentation, I am struggling to understand the regex code and how to customize it according to my requirements! Current ...

What is the best way to access HTML attributes within a JavaScript function when working with a dynamic element?

When a user interacts with an HTML element on my website, I aim to display the attributes of that specific element in a new browser tab. An example of such an HTML element is: <a id="d0e110" onclick="GetWordFile(this.id)" attr1="attr1_value" attr2="at ...

Search field in DataTables appears to be misaligned

I'm in the process of developing a small website using JSP and DataTables (currently only for the first table). Here's what I have so far: As you can observe, there seems to be an alignment issue with the search field position. I'm n ...