How do I achieve this inline input field effect

Screenshot 2024-04-03 124519
Where ‘22’ is editable. This data will be used to filter a series of results.

hi @karn0n check MDN for attribute contenteditable

I have missed this part, in this case just use standard text input. :man_shrugging:

1 Like

Hi Stan.

Thanks for interacting. I have attempted to create the site but I am having some issues.

https://preview.webflow.com/preview/desk-stretcher?utm_medium=preview_link&utm_source=designer&utm_content=desk-stretcher&preview=f2777e8cec548dfee282d78233da5e55&workflow=preview

Here you can see that when the user types anything in the input field, it begins to disappear.

https://desk-stretcher.webflow.io/

I want the max input to be 30, and if the user enters a double digit, it should ‘push’ the word minutes along so that the sentence doesn’t get crowded.

Thanks in advance.

So you need number input type number

The user is still able to type anything they want in the field (I did already add custom attribute max=“30”). And my main issue is that the field gets cramped within the sentence rather than the user feeling like they are purely editing the sentence (the word ‘minutes’ needs to move along).

When you your input is type="text" try to use pattern="[0-9]{2}" this will limit text to two numbers. but there is no max in text so number can be over 30

here is simple example with type:number and max="30"

<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      span {
        font-size: 2rem;
      }
      div {
        display: flex;
      }
      input {
        font-size: 2rem;
        border: none;
        display: inline-flex;
        max-width: max-content;
        text-align: center;
        border-bottom: 4px solid rgb(192, 192, 192);
        margin: 0;
        padding: 0;

        &::placeholder {
          color: rgb(152, 152, 152);
        }
      }
      input[type='submit'] {
        border: none;
        padding: 0.5rem 1rem;
        border-radius: 5px;
        background: rgb(178, 65, 182);
        color: white;
        text-transform: uppercase;
        letter-spacing: 0.05em;
        cursor: pointer;
      }

      input::-webkit-outer-spin-button,
      input::-webkit-inner-spin-button {
        -webkit-appearance: none;
        margin: 0;
      }

      /* Firefox */
      /* input[type='number'] {
        -moz-appearance: textfield;
      } */
    </style>
  </head>
  <body>
    <form action="" method="post">
      <div>
        <span>I am</span>
        <input
          type="number"
          name="age"
          id="age"
          value=""
          min="18"
          max="30"
          size="2"
          pattern="[0-9]{2}"
          maxlength="2"
          placeholder="22"
        />
        <span>years old</span>
      </div>
      <br />
      <input type="submit" value="submit" />
    </form>
  </body>
</html>

Keep in mind it is not perfect as have just created it on the fly and there are attributes that do not have impact. Think about it as starting point. :face_with_hand_over_mouth:

Thanks this is effectively what I have. My main desire is that it will look completely native to the sentence and so if the user inputs a value that is an increase in characters on the placeholder, the sentence should ‘extend’; the words after the input field should be pushed along.

I have got this from your screenshot and here is what is rendered in my test where input is number so browser validator kits out when value is over max.

Main issue is that max value doesn’t apply in input type="text and validator doesn’t recognise it, at least I’m not aware how to validate it.

Here is an example. Where step 1. there is no interaction. The user then enters 5. When the user enters a second digit, 5 again, it moves ‘minutes’ along.

ok, IMO this can be done with texteditable ( result: moving “minutes” text) but you will need custom JS validator to limit to two digits and numbers only.

The issue is that AFIK input has no dynamic width but there may be a way “how to”.

here is an article you can read so it may give you an idea.

1 Like

Hi @karn0n here’s some extra information because I’m unsure of your familiarity with web development.

As previously discussed, you can apply the contenteditable attribute to a <span> element. However, note that this content won’t be included upon form submission, unlike input values. One workaround is to create a hidden input and trigger a custom function to transfer the <span> value to this input upon submission. This way, the value will be included in the form data.

Additionally, I’ve mentioned the option of implementing a custom validator, such as using regular expressions.

1 Like

Thanks, I am primarily a designer so you are correct in assuming my unfamiliarity.

The article you sent was very helpful and, stylistically, I was able to achieve the desired affect. I was already looking at ways of transferring the data from the <span> values to the input. I am just wondering how to do this :joy:

Thanks again for your help and patience so far.

1 Like

ok @karn0n

Here is a extended version that works with standatrd text. It is simple but has all basic functionality (only 2 nums, primitive validation & error msg)

<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      span {
        font-size: 2rem;
      }
      div {
        display: flex;
      }
 
      input[type='submit'] {
        border: none;
        padding: 0.5rem 1rem;
        border-radius: 5px;
        background: rgb(178, 65, 182);
        color: white;
        text-transform: uppercase;
        letter-spacing: 0.05em;
        cursor: pointer;
      }

      input::-webkit-outer-spin-button,
      input::-webkit-inner-spin-button {
        -webkit-appearance: none;
        margin: 0;
      }

      /* Firefox */
      /* input[type='number'] {
        -moz-appearance: textfield;
      } */
      .minutes {
        color: rgb(178, 65, 182);
        padding-inline: 0.5rem;
        border-bottom: 2px solid rgb(178, 65, 182);
      }
      .error-msg span {
        color: red;
        font-size: 1rem;
      }
    </style>
  </head>
  <body>
    <form action="" method="post">
      <div>
        <span>I have</span>
        <span class="minutes" id="minutes" contenteditable="true"></span>
        <span>minutes</span>
        <!-- hidden input with value from minutes-->
        <input type="hidden" name="minutes" id="hiddenInput" value="" />
      </div>
      <div id="spnError" class="error-msg">
        <!-- your error msg -->
        <span>Only numbers allowed you moron ;)</span>
      </div>
      <br />
      <input type="submit" value="submit" />
    </form>
    <script>
      const form = document.querySelector('form')
      const minutesInput = document.querySelector('#minutes')
      const hiddenInput = document.querySelector('#hiddenInput')
      const errMsg = document.getElementById('spnError')
      // set init value
      const initNumValue = 5
      // apply init value
      minutesInput.innerText = initNumValue
      // hide error msg on init
      errMsg.style.display = 'none'

      // simple numbers validator
      const numsOnly = (value) => {
        const regex = /^[0-9\s]*$/
        const isValid = regex.test(value)
        // toggle err mgs
        if (!isValid) {
          minutesInput.innerText = ''
          errMsg.style.display = 'block'
        } else {
          errMsg.style.display = 'none'
        }
        return isValid
      }
      // validate on keyUp
      minutesInput.addEventListener('keyup', (e) => {
        let clientInput = e.target.innerText
        numsOnly(clientInput)

        if (clientInput.length > 2) {
          minutesInput.innerText = clientInput.slice(0, 2)
          //  you can add err msg here
        }
      })

      form.addEventListener('submit', (event) => {
        event.preventDefault()
        // get the value of the minutes input
        const minutes = minutesInput.innerText
        // set the value of the hidden input
        hiddenInput.value = minutes
        // form data
        const formData = new FormData(form)
        // get the form data
        const data = Object.fromEntries(formData)
        console.log(data)
        // submit the form
        //  ... your code here
      })
    </script>
  </body>
</html>

1 Like

Thanks so much - I am working with this now