Optimal approach for choosing/emphasizing text (within a text input field) in Vue (utilizing computed properties for input value and selection range)

Our current setup involves a text input field with its value stored in Vuex, passed as props, and accessed through computed properties. Within the same Vuex store, we also have a selection range (an array of two numbers) that allows text in the input to be highlighted or selected.

Here is a simplified version of the code:

<template>
  <input type="text" v-model="value" @select="selectionHandler" />
</template>

<script>
  export default {
    props: ['props'],
    computed: {
      value: function() {
        return this.props.value // some string
      },
      selectionRange: {
        get: function () { return this.props.selectionRange }, // [number, number] 
        set: function (range) { /* dispatch store action to update, which will update props */ }
      }
    },
    methods: {
      selectionHandler(e) { 
        this.selectionRange = [e.currentTarget.selectionStart, e.currentTarget.selectionEnd]
      }
    }
  }
</script>

The objective here is to enable users to select or highlight text (from the store) and then update the store based on their selection. I am considering using setSelectionRange (docs). While I could potentially leverage refs and watchers from Vue.js, it may be more complex than necessary.

Answer №1

Upon developing my solution, I came up with a custom select function that utilized refs to choose the input/textarea text. Initially, I triggered the select function within Vue's life cycle methods: mounted and updated. The simplified version of the code looked something like this:

<template>
  <input ref="someRefName" type="text" v-model="value" @select="selectionHandler" />
</template>

<script>
  export default {
    props: ['props'],
    computed: {
      value: function() {
        return this.props.value // some string
      },
      selectionRange: {
        get: function () { return this.props.selectionRange }, // [number, number] 
        set: function (range) { /* dispatch store action to update, which will update props */ }
      }
    },
    methods: {
      selectionHandler(e) { 
        this.selectionRange = [e.currentTarget.selectionStart, e.currentTarget.selectionEnd]
      },
      select() {
        this.$refs['someRefName'].setSelectionRange(this.selectionRange[0], this.selectionRange[1])
      }
    },
    mounted: function () {
      if (this.selectionRange[1] !== 0) { this.select() }
    },
    updated: function () {
      if (this.selectionRange[1] !== 0) { this.select() }
    }
  }
</script>

Initially, it seemed like an effective solution... until I realized that "oh, that's not how browsers work." The selected or highlighted text would clear each time the input lost focus. To address this issue, I modified the approach to incorporate focus and blur handler functions. Now, the text is only selected while the element is in focus. Here's what the revised code looks like:

<template>
  <input ref="someRefName" type="text" v-model="value" @focus="focusHandler" @select="selectionHandler" @blur="blurHandler" />
</template>

<script>
  export default {
    props: ['props'],
    computed: {
      value: function() {
        return this.props.value // some string
      },
      selectionRange: {
        get: function () { return this.props.selectionRange }, // [number, number] 
        set: function (range) { /* dispatch store action to update, which will update props */ }
      }
    },
    methods: {
      focusHandler() {
        if (this.selectionRange[1] !== 0) { this.select() }
      },
      selectionHandler(e) { 
        this.selectionRange = [e.currentTarget.selectionStart, e.currentTarget.selectionEnd]
      },
      blurHandler() {
        this.selectionRange = [0, 0]
      },
      select() {
        this.$refs['someRefName'].setSelectionRange(this.selectionRange[0], this.selectionRange[1])
      }
    }
  }
</script>

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

React-redux: Data of the user is not being stored in redux post-login

Hello everyone, I am fairly new to using react-redux and I'm currently facing an issue with storing user information in the redux store after a user logs in. I am utilizing a django backend for this purpose. When I console out the user in app.js, it ...

Calculate the number of parent nodes and their respective child nodes

I am curious about how I can determine the number of children nested within parent-child relationships. For example: const parent = document.querySelectorAll('.parent'); parent.forEach(el => { const ul = el.querySelector('.child3-chi ...

Leveraging 2-dimensional indexes in collaboration with the $geoNear operator

I encountered an issue while attempting to use geoNear with aggregate as I received the following error message: errmsg: "'near' field must be point" The reason for this error is because my location field is represented as [Number]: var locati ...

Can the submission of a form be prevented in PHP after encountering a ctype_digit error?

As a new learner in PHP, I am trying to figure out how to prevent the form from submitting to MySQL if the user enters anything other than an integer in the Age field. Below is the basic form and code I have: add.html-> <form action="add.php" m ...

Manipulating and transforming data through Puppeteer's iterative process into an object structure

As a beginner with the puppetteer library, I'm trying to iterate through Amazon reviews and save each comment as an object. Although my code seems to be functioning, it only retrieves the first comment and then stops. async function scrapeProduct(ur ...

What is the best way to iterate through an array in Vue using only half the number of iterations as the total number of items?

My data is stored in an array: [ { type: select, options: [foo, bar], label: foo, required: true }, { type: text, options: [], label: bar, required: false }, { type: checkbox, options: [], lab ...

Google Maps in Angular is not showing up

My Angular Google Maps implementation seems to be working, but unfortunately, the map is not showing on my website. I have confirmed that my JS is loading the maps and I can retrieve the map properties. Interestingly, when I check the Chrome AngularJS Debu ...

Tips on obtaining a byte array from within a JSON object

I am currently facing a challenge in retrieving a PDF file from the server, which is enclosed within a JSON object. When I send a byte array of the PDF to the front-end, I can successfully read it by configuring the responseType to arraybuffer. Subsequent ...

Automatically deliver a message regularly at set intervals on Discord across all groups and guilds

Currently, I am developing an event-bot to use in multiple Discord groups. Here is the code snippet I have been working on: if (command === "init") { message.channel.send("BunnBot starting..."); var interval = setInterval (function () { me ...

Issue with retrieving relative time using Moment.js - fromNow()

I want to utilize moment.js to display relative time fromNow(), but I am encountering an issue where the values are being rounded and showing higher durations instead of exact completion times. For example, moment().subtract('s',110).fromNow() / ...

What is the best way to arrange an array or display it accurately?

Guys, here's a challenge for you: extract the values from this JSON data: [[name, brand, oem, category], [name, brand, oem, category], [name, brand, oem, category], [name, brand, oem, category]] Check out my JavaScript code: $(function(){ $('i ...

How to incorporate multiple anchor tags and hashtags into a Vue.js <router-link> or @click function

image description I am looking to create a post card similar to a Twitter post card. When any part of the post card is clicked, it should go to the post page. However, if hashtags or links are clicked, they should lead to the respective hashtag or link de ...

Timing issue with the animation callback

I have been experimenting with creating a bounce effect on my custom scroller by utilizing the translate3d method for scrolling. I managed to successfully implement it, but now I am facing an issue where if you continuously scroll out of bounds (try double ...

What is the value of x in the equation 2 raised to the power of x equals 800

Similar Question: What is the reverse of Math.pow in JavaScript? 2^x=i If i is given, how can we determine x using Javascript? ...

Unable to extract property from object in context due to its undefined status

Having trouble with the useContext hook in my React app for managing the cart state. Keep getting an error stating that the function I'm trying to destructure is undefined. I'm new to using the context API and have tried various solutions like e ...

Toggle between tabs by dynamically selecting radio buttons

On my webpage, I have numerous tabs following the same structure as seen on the angular-ui page. Each section contains tabs for both Markup and Javascript. My goal is to implement two radio buttons at the top of the page that can switch all tabs to either ...

Executing a Function within UseEffect

I need help calling the function onSaveInputValue within the useEffect to make sure that the value is passed to the childInputValue hook whenever the page loads. const onSaveInputValue = (value) => { setChildInputValue(value); consol ...

Deactivate a setInterval function within a Vue.js component

I am facing an issue in my VUE SPA where I have a component running a recursive countdown using setInterval functions. The problem is that the countdown continues running in the background even when I switch to another view, but I want to destroy the setIn ...

display upcoming schedule and time

How can I display the future date and time in the respective field components? See below for a sample code snippet: require([ "dojo/_base/lang", "dijit/registry", "dojo/ready", "dijit/form/TimeTextBox", "dojo/parser" ], function(lang, registry, ready ...

Finding the Client's Private IP Address in React or Node.js: A Comprehensive Guide

Issue I am currently facing the challenge of comparing the user's private IP with the certificate's IP. Is there a method available to retrieve the user's private IP in react or node? Attempted Solution After attempting to find the user&a ...