Home > Enterprise >  Nuxt3: Why does this text input element not respect the maxlength attribute?
Nuxt3: Why does this text input element not respect the maxlength attribute?

Time:11-04

I am using Nuxt3 and for some reason, the maxlength="70" attribute specified in the below HTML input element is not respected (I can type more than 70 characters). Does anyone know why?

<input
  type="text"
  
  id="title"
  placeholder="title"
  v-model.trim="formData.title"
  required
  maxlength="70"
  aria-describedby="titleCount"
/>

I am able to reproduce this with a minimal production here: https://stackblitz.com/edit/nuxt-starter-kmrpo9?file=app.vue

The full code:

<template>
  <section>
    <div >
      <div >
        <div ></div>
        <div >
          <main >
            <form  @keydown.enter.prevent="">
              <div >
                <input
                  type="text"
                  
                  id="title"
                  placeholder="title"
                  v-model.trim="formData.title"
                  required
                  maxlength="70"
                  aria-describedby="titleCount"
                />
                <div id="titleCount" >
                  {{ titleLimit - formData.title.length }}
                  characters remaining
                </div>
                <label for="title">Title</label>
              </div>
            </form>
          </main>
        </div>
      </div>
    </div>
  </section>
</template>

<script setup lang="ts">
const props = defineProps({
  post: {
    type: Object,
    default: () => ({
      caption: '',
      title: '',
      content: '',
      source: '',
      tags: [],
      imageFileName: '',
      imagePath: '',
      width: null,
      height: null,
    }),
  },
});
const formData = reactive({ ...props.post });
// Limit the number of title characters to 70
const titleLimit = computed(() => {
  const limit = 70;
  const titleLength = formData.title.length;
  return limit - titleLength;
});
</script>

CodePudding user response:

Since you're using v-model.trim="formData.title" here, you are probably overriding the default behavior of the HTML tag thanks to the power of Vue.

Either remove that one or handle the logic yourself by not allowing the user to type more characters but in Vue, with an @input checking the length for example.


Here is your example as a working demo.

<template>
  <section>
    <div >
      <div >
        <div ></div>
        <div >
          <main >
            <form  @keydown.enter.prevent="">
              <div >
                <input
                  type="text"
                  
                  id="title"
                  placeholder="title"
                  :value="formData.title"
                  @input.trim="updateIfPossible"
                  required
                  maxlength="70"
                  aria-describedby="titleCount"
                />
                <div id="titleCount" >
                  {{ titleLimit }}
                  characters remaining
                </div>
                <label for="title">Title</label>
              </div>
            </form>
          </main>
        </div>
      </div>
    </div>
  </section>
</template>

<script setup lang="ts">
const props = defineProps({
  post: {
    type: Object,
    default: () => ({
      caption: '',
      title: '',
      content: '',
      source: '',
      tags: [],
      imageFileName: '',
      imagePath: '',
      width: null,
      height: null,
    }),
  },
});
const formData = reactive({ ...props.post });
// Limit the number of title characters to 70
const titleLimit = computed(() => {
  const limit = 70;
  const titleLength = formData.title.trim().length;
  return limit - titleLength;
})

function updateIfPossible(e) {
  if (formData.title.trim().length > 70) return 
  formData.title = e.target.value
}
</script>
  • Related