1

I'm trying to change the input width dynamically as the client types.

I've tried getting width of the input content...

Template:

<span ref="totCitSpan" id="hide">{{myReactivedata}}</span>
<input @input="resize()" ref="totCitInput" class="title" id="txt" type="number" v-model="myReactivedata" >  

script

let totCitSpan = ref(null);
let totCitInput = ref(null);

var hide = totCitSpan;
var txt = totCitInput;
const resize = (_value) => {
   hide.textContent = txt.value;
   txt.style.width = hide.offsetWidth + "px";
}

And then use some css to hide the span and push the content like in this example (Auto-scaling input[type=text] to width of value?

), but Vue handles refs reactivity with proxys so this is a no go and something simple is becoming a monumental task using refs, onmounted hooks, creating new data properties. In an ideal world this type of things could even be done through html or css but from what I researched there's no off the shelf solution...

any thoughts and clever ideas are very welcome.

1 Answers1

1

Solution (using ch units):

input.reactive {
  width: 5ch; /* starting width with 2 more ch  than the word - my word had 3 characters 'abc' */
}
<input 
  class="title reactive" 
  type='number' 
  value="abc"  
  onkeydown="this.style.width = (this.value.length + 2 ) + 'ch';">


  

I've added two more characters on the inline function to make space for the up/down arrows but you can remove them and style freely.

I hope this is useful.

more about ch units: https://meyerweb.com/eric/thoughts/2018/06/28/what-is-the-css-ch-unit/

  • 1
    Worked for me! I'd suggest using keyup over keydown for performance reasons since keydown runs endlessly while the key is down and keyup will just run once. It doesn't feel quite as responsive though. – Chris Hayes May 19 '21 at 15:06