mdbootstrap / TW-Elements

𝙃𝙪𝙜𝙚 collection of Tailwind MIT licensed (free) components, sections and templates 😎
https://tw-elements.com
MIT License
12.85k stars 1.62k forks source link

[Select, Input] - Select not initTe correctly. #2002

Open joelee92 opened 11 months ago

joelee92 commented 11 months ago

Currently I'm using Nuxt2 and I played around with the v-if for the Select component. Initially the select component is display well, but after i click the button the select component broken. Screenshot 2023-10-13 180338 Screenshot 2023-10-13 180422 I believe it related to the Input component, even timepicker and datepicker also encounter the same issue.

here is my package.json:

{
  "name": "my-project",
  "version": "1.0.0",
  "private": true,
  "scripts": {
    "dev": "nuxt",
    "build": "nuxt build",
    "start": "nuxt start",
    "generate": "nuxt generate",
    "lint:js": "eslint --ext \".js,.vue\" --ignore-path .gitignore .",
    "lint": "npm run lint:js",
    "lintfix": "npm run lint:js -- --fix"
  },
  "dependencies": {
    "axios": "^1.4.0",
    "core-js": "^3.25.3",
    "heroicons": "^2.0.18",
    "nuxt": "^2.15.8",
    "tw-elements": "^1.0.0",
    "vue": "^2.7.10",
    "vue-server-renderer": "^2.7.10",
    "vue-tel-input": "^5.14.0",
    "vue-template-compiler": "^2.7.10"
  },
  "devDependencies": {
    "@babel/eslint-parser": "^7.19.1",
    "@nuxtjs/eslint-config": "^11.0.0",
    "@nuxtjs/eslint-module": "^3.1.0",
    "@nuxtjs/tailwindcss": "^5.3.3",
    "autoprefixer": "^10.4.14",
    "eslint": "^8.24.0",
    "eslint-plugin-nuxt": "^4.0.0",
    "eslint-plugin-vue": "^9.5.1",
    "postcss": "^8.4.24",
    "tailwindcss": "^3.3.2"
  }
}

Here is my code:

  <template>
  <div>
    <button
      type="button"
      class="inline-block rounded bg-primary px-6 pb-2 pt-2.5 text-xs font-medium uppercase leading-normal text-white shadow-[0_4px_9px_-4px_#3b71ca] transition duration-150 ease-in-out hover:bg-primary-600 hover:shadow-[0_8px_9px_-4px_rgba(59,113,202,0.3),0_4px_18px_0_rgba(59,113,202,0.2)] focus:bg-primary-600 focus:shadow-[0_8px_9px_-4px_rgba(59,113,202,0.3),0_4px_18px_0_rgba(59,113,202,0.2)] focus:outline-none focus:ring-0 active:bg-primary-700 active:shadow-[0_8px_9px_-4px_rgba(59,113,202,0.3),0_4px_18px_0_rgba(59,113,202,0.2)] dark:shadow-[0_4px_9px_-4px_rgba(59,113,202,0.5)] dark:hover:shadow-[0_8px_9px_-4px_rgba(59,113,202,0.2),0_4px_18px_0_rgba(59,113,202,0.1)] dark:focus:shadow-[0_8px_9px_-4px_rgba(59,113,202,0.2),0_4px_18px_0_rgba(59,113,202,0.1)] dark:active:shadow-[0_8px_9px_-4px_rgba(59,113,202,0.2),0_4px_18px_0_rgba(59,113,202,0.1)]"
      @click="showSelect = !showSelect"
    >
      Button
    </button>
    <div v-if="showSelect">
      <select data-te-select-init>
        <option value="1">
          One
        </option>
        <option value="2">
          Two
        </option>
      </select>
    </div>
  </div>
</template>

<script>
import { Select, initTE } from 'tw-elements'
export default {
  name: 'Voicemail',
  data () {
    return {
      showSelect: true
    }
  },
  created () {
    initTE({ Select }, { allowReinits: true })
  }
}
</script>
AndoruKun commented 11 months ago

Hai, im has same issue but i can resolve this issue

in <script>

<template>
<div>
  <button
    type="button"
    class="inline-block rounded bg-primary px-6 pb-2 pt-2.5 text-xs font-medium uppercase leading-normal text-white shadow-[0_4px_9px_-4px_#3b71ca] transition duration-150 ease-in-out hover:bg-primary-600 hover:shadow-[0_8px_9px_-4px_rgba(59,113,202,0.3),0_4px_18px_0_rgba(59,113,202,0.2)] focus:bg-primary-600 focus:shadow-[0_8px_9px_-4px_rgba(59,113,202,0.3),0_4px_18px_0_rgba(59,113,202,0.2)] focus:outline-none focus:ring-0 active:bg-primary-700 active:shadow-[0_8px_9px_-4px_rgba(59,113,202,0.3),0_4px_18px_0_rgba(59,113,202,0.2)] dark:shadow-[0_4px_9px_-4px_rgba(59,113,202,0.5)] dark:hover:shadow-[0_8px_9px_-4px_rgba(59,113,202,0.2),0_4px_18px_0_rgba(59,113,202,0.1)] dark:focus:shadow-[0_8px_9px_-4px_rgba(59,113,202,0.2),0_4px_18px_0_rgba(59,113,202,0.1)] dark:active:shadow-[0_8px_9px_-4px_rgba(59,113,202,0.2),0_4px_18px_0_rgba(59,113,202,0.1)]"
    @click="showSelectComp"
  >
    Button
  </button>
  <div v-if="showSelect">
    <select id="selectTW" data-te-select-init>
      <option value="1">
        One
      </option>
      <option value="2">
        Two
      </option>
    </select>
  </div>
</div>
</template>

<script>
export default {
name: 'Voicemail',
data () {
  return {
    showSelect: true,
    selectComponent: ''  <--- this variable use for define initFE variable
  }
},
async mounted() {
const { Animate, initTE } = await import('tw-elements');
initTE({ Select })
},
methods: {
  async initSelectComponent() {
    const { Animate, initTE } = await import('tw-elements');
    initTE({ Select })
    let selectEl = document.getElementById('selectTW')
    if (typeof this.selectComponent == 'string') this.selectComponent = new Select(selectEl)
    else this.selectComponent = Select.getInstance(selectEl)
  },
  showSelectComp() {
    this.initSelectComponent()
    this.showSelect = !this.showSelect
  }
}
</script>

this resolve code i use in my procject and i work very well i recommend you to create this select on folder Component so you just call it the component

joelee92 commented 11 months ago

Hai, im has same issue but i can resolve this issue

in <script>

<template>
<div>
  <button
    type="button"
    class="inline-block rounded bg-primary px-6 pb-2 pt-2.5 text-xs font-medium uppercase leading-normal text-white shadow-[0_4px_9px_-4px_#3b71ca] transition duration-150 ease-in-out hover:bg-primary-600 hover:shadow-[0_8px_9px_-4px_rgba(59,113,202,0.3),0_4px_18px_0_rgba(59,113,202,0.2)] focus:bg-primary-600 focus:shadow-[0_8px_9px_-4px_rgba(59,113,202,0.3),0_4px_18px_0_rgba(59,113,202,0.2)] focus:outline-none focus:ring-0 active:bg-primary-700 active:shadow-[0_8px_9px_-4px_rgba(59,113,202,0.3),0_4px_18px_0_rgba(59,113,202,0.2)] dark:shadow-[0_4px_9px_-4px_rgba(59,113,202,0.5)] dark:hover:shadow-[0_8px_9px_-4px_rgba(59,113,202,0.2),0_4px_18px_0_rgba(59,113,202,0.1)] dark:focus:shadow-[0_8px_9px_-4px_rgba(59,113,202,0.2),0_4px_18px_0_rgba(59,113,202,0.1)] dark:active:shadow-[0_8px_9px_-4px_rgba(59,113,202,0.2),0_4px_18px_0_rgba(59,113,202,0.1)]"
    @click="showSelectComp"
  >
    Button
  </button>
  <div v-if="showSelect">
    <select id="selectTW" data-te-select-init>
      <option value="1">
        One
      </option>
      <option value="2">
        Two
      </option>
    </select>
  </div>
</div>
</template>

<script>
export default {
name: 'Voicemail',
data () {
  return {
    showSelect: true,
    selectComponent: ''  <--- this variable use for define initFE variable
  }
},
async mounted() {
const { Animate, initTE } = await import('tw-elements');
initTE({ Select })
},
methods: {
  async initSelectComponent() {
    const { Animate, initTE } = await import('tw-elements');
    initTE({ Select })
    let selectEl = document.getElementById('selectTW')
    if (typeof this.selectComponent == 'string') this.selectComponent = new Select(selectEl)
    else this.selectComponent = Select.getInstance(selectEl)
  },
  showSelectComp() {
    this.initSelectComponent()
    this.showSelect = !this.showSelect
  }
}
</script>

this resolve code i use in my procject and i work very well i recommend you to create this select on folder Component so you just call it the component

Hi, thanks for the reply. I already tried your method, it seems like working fine for the first button click. But after first button click the issue is still persist. Have you encountered that too?

juujisai commented 11 months ago

Hi @joelee92 . Instead of the created method use mounted. It should work fine then.

Hello @AndoruKun . Try adding allowReinits option to the initTE method

mounted () {
  initTE({ Select }, { allowReinits: true })
}

or with asyncs

async mounted() {
const { Select, initTE } = await import('tw-elements');
initTE({ Select }, { allowReinits: true })
},
joelee92 commented 11 months ago

async mounted() { const { Select, initTE } = await import('tw-elements'); initTE({ Select }, { allowReinits: true }) },

<template>
  <div>
    <button
      type="button"
      class="inline-block rounded bg-primary px-6 pb-2 pt-2.5 text-xs font-medium uppercase leading-normal text-white shadow-[0_4px_9px_-4px_#3b71ca] transition duration-150 ease-in-out hover:bg-primary-600 hover:shadow-[0_8px_9px_-4px_rgba(59,113,202,0.3),0_4px_18px_0_rgba(59,113,202,0.2)] focus:bg-primary-600 focus:shadow-[0_8px_9px_-4px_rgba(59,113,202,0.3),0_4px_18px_0_rgba(59,113,202,0.2)] focus:outline-none focus:ring-0 active:bg-primary-700 active:shadow-[0_8px_9px_-4px_rgba(59,113,202,0.3),0_4px_18px_0_rgba(59,113,202,0.2)] dark:shadow-[0_4px_9px_-4px_rgba(59,113,202,0.5)] dark:hover:shadow-[0_8px_9px_-4px_rgba(59,113,202,0.2),0_4px_18px_0_rgba(59,113,202,0.1)] dark:focus:shadow-[0_8px_9px_-4px_rgba(59,113,202,0.2),0_4px_18px_0_rgba(59,113,202,0.1)] dark:active:shadow-[0_8px_9px_-4px_rgba(59,113,202,0.2),0_4px_18px_0_rgba(59,113,202,0.1)]"
      @click="showSelect = !showSelect"
    >
      Button
    </button>
    <div v-if="showSelect">
      <select data-te-select-init>
        <option value="1">
          One
        </option>
        <option value="2">
          Two
        </option>
      </select>
    </div>
  </div>
</template>

<script>
export default {
  name: 'Voicemail',
  data () {
    return {
      showSelect: true
    }
  },
  async mounted () {
    const { Select, initTE } = await import('tw-elements')
    initTE({ Select }, { allowReinits: true })
  }

}
</script>

Hi, I had tried both mounted or async mounted. It is still not resolve my issue

joelee92 commented 11 months ago
<template>
  <div>
    <button
      type="button"
      class="inline-block rounded bg-primary px-6 pb-2 pt-2.5 text-xs font-medium uppercase leading-normal text-white shadow-[0_4px_9px_-4px_#3b71ca] transition duration-150 ease-in-out hover:bg-primary-600 hover:shadow-[0_8px_9px_-4px_rgba(59,113,202,0.3),0_4px_18px_0_rgba(59,113,202,0.2)] focus:bg-primary-600 focus:shadow-[0_8px_9px_-4px_rgba(59,113,202,0.3),0_4px_18px_0_rgba(59,113,202,0.2)] focus:outline-none focus:ring-0 active:bg-primary-700 active:shadow-[0_8px_9px_-4px_rgba(59,113,202,0.3),0_4px_18px_0_rgba(59,113,202,0.2)] dark:shadow-[0_4px_9px_-4px_rgba(59,113,202,0.5)] dark:hover:shadow-[0_8px_9px_-4px_rgba(59,113,202,0.2),0_4px_18px_0_rgba(59,113,202,0.1)] dark:focus:shadow-[0_8px_9px_-4px_rgba(59,113,202,0.2),0_4px_18px_0_rgba(59,113,202,0.1)] dark:active:shadow-[0_8px_9px_-4px_rgba(59,113,202,0.2),0_4px_18px_0_rgba(59,113,202,0.1)]"
      @click="showSelectComp"
    >
      Button
    </button>
    <div v-if="showSelect">
      <select id="selectTW" data-te-select-init>
        <option value="1">
          One
        </option>
        <option value="2">
          Two
        </option>
      </select>
    </div>
  </div>
</template>

<script>
export default {
  name: 'Voicemail',
  data () {
    return {
      showSelect: true,
      selectComponent: ''
    }
  },
  async mounted () {
    const { Select, initTE } = await import('tw-elements')
    initTE({ Select }, { allowReinits: true })
  },
  methods: {
    async initSelectComponent () {
      const { Select, initTE } = await import('tw-elements')
      initTE({ Select }, { allowReinits: true })
      const selectEl = document.getElementById('selectTW')
      if (typeof this.selectComponent === 'string') { this.selectComponent = new Select(selectEl) } else { this.selectComponent = Select.getInstance(selectEl) }
    },
    showSelectComp () {
      this.initSelectComponent()
      this.showSelect = !this.showSelect
    }
  }
}
</script>

here is my final code, the initialize issue is fixed. but when first click the button, it will display duplicate selection. image after first click, the selection is back to normal.

AndoruKun commented 11 months ago
<template>
  <div>
    <button
      type="button"
      class="inline-block rounded bg-primary px-6 pb-2 pt-2.5 text-xs font-medium uppercase leading-normal text-white shadow-[0_4px_9px_-4px_#3b71ca] transition duration-150 ease-in-out hover:bg-primary-600 hover:shadow-[0_8px_9px_-4px_rgba(59,113,202,0.3),0_4px_18px_0_rgba(59,113,202,0.2)] focus:bg-primary-600 focus:shadow-[0_8px_9px_-4px_rgba(59,113,202,0.3),0_4px_18px_0_rgba(59,113,202,0.2)] focus:outline-none focus:ring-0 active:bg-primary-700 active:shadow-[0_8px_9px_-4px_rgba(59,113,202,0.3),0_4px_18px_0_rgba(59,113,202,0.2)] dark:shadow-[0_4px_9px_-4px_rgba(59,113,202,0.5)] dark:hover:shadow-[0_8px_9px_-4px_rgba(59,113,202,0.2),0_4px_18px_0_rgba(59,113,202,0.1)] dark:focus:shadow-[0_8px_9px_-4px_rgba(59,113,202,0.2),0_4px_18px_0_rgba(59,113,202,0.1)] dark:active:shadow-[0_8px_9px_-4px_rgba(59,113,202,0.2),0_4px_18px_0_rgba(59,113,202,0.1)]"
      @click="showSelectComp"
    >
      Button
    </button>
    <div v-if="showSelect">
      <select id="selectTW" data-te-select-init>
        <option value="1">
          One
        </option>
        <option value="2">
          Two
        </option>
      </select>
    </div>
  </div>
</template>

<script>
export default {
  name: 'Voicemail',
  data () {
    return {
      showSelect: true,
      selectComponent: ''
    }
  },
  async mounted () {
    const { Select, initTE } = await import('tw-elements')
    initTE({ Select }, { allowReinits: true })
  },
  methods: {
    async initSelectComponent () {
      const { Select, initTE } = await import('tw-elements')
      initTE({ Select }, { allowReinits: true })
      const selectEl = document.getElementById('selectTW')
      if (typeof this.selectComponent === 'string') { this.selectComponent = new Select(selectEl) } else { this.selectComponent = Select.getInstance(selectEl) }
    },
    showSelectComp () {
      this.initSelectComponent()
      this.showSelect = !this.showSelect
    }
  }
}
</script>

here is my final code, the initialize issue is fixed. but when first click the button, it will display duplicate selection. image after first click, the selection is back to normal.

try this one

showSelectComp () {
      let elSelectId = document.getElementById('selectTW');
      let checkInitTW = Select.getInstance(elSelectId)
      if (checkIniTW == null) this.initSelectComponent()
      this.showSelect = !this.showSelect
}

i hope this code help you

joelee92 commented 11 months ago

try this one

showSelectComp () {
      let elSelectId = document.getElementById('selectTW');
      let checkInitTW = Select.getInstance(elSelectId)
      if (checkIniTW == null) this.initSelectComponent()
      this.showSelect = !this.showSelect
}

i hope this code help you

I edited some of the code to resolve the issue. Thanks for the reply, appreciate that!

<template>
  <div>
    <button
      type="button"
      class="inline-block rounded bg-primary px-6 pb-2 pt-2.5 text-xs font-medium uppercase leading-normal text-white shadow-[0_4px_9px_-4px_#3b71ca] transition duration-150 ease-in-out hover:bg-primary-600 hover:shadow-[0_8px_9px_-4px_rgba(59,113,202,0.3),0_4px_18px_0_rgba(59,113,202,0.2)] focus:bg-primary-600 focus:shadow-[0_8px_9px_-4px_rgba(59,113,202,0.3),0_4px_18px_0_rgba(59,113,202,0.2)] focus:outline-none focus:ring-0 active:bg-primary-700 active:shadow-[0_8px_9px_-4px_rgba(59,113,202,0.3),0_4px_18px_0_rgba(59,113,202,0.2)] dark:shadow-[0_4px_9px_-4px_rgba(59,113,202,0.5)] dark:hover:shadow-[0_8px_9px_-4px_rgba(59,113,202,0.2),0_4px_18px_0_rgba(59,113,202,0.1)] dark:focus:shadow-[0_8px_9px_-4px_rgba(59,113,202,0.2),0_4px_18px_0_rgba(59,113,202,0.1)] dark:active:shadow-[0_8px_9px_-4px_rgba(59,113,202,0.2),0_4px_18px_0_rgba(59,113,202,0.1)]"
      @click="showSelectComp('selectTW')"
    >
      Button
    </button>
    <div v-if="showSelect">
      <select id="selectTW" data-te-select-init>
        <option value="1">
          One
        </option>
        <option value="2">
          Two
        </option>
      </select>
    </div>
  </div>
</template>

<script>
import 'tw-elements/dist/css/tw-elements.min.css'
import {
  Select
} from 'tw-elements'
export default {
  name: 'Voicemail',
  data () {
    return {
      showSelect: true
    }
  },
  async mounted () {
    const { Select, initTE } = await import('tw-elements')
    initTE({ Select }, { allowReinits: true })
  },
  methods: {
    async initSelectComponent (id) {
      const { Select, initTE } = await import('tw-elements')
      initTE({ Select }, { allowReinits: true })
      const selectEl = document.getElementById(id)
      Select.getInstance(selectEl)
    },
    showSelectComp (id) {
      const elSelectId = document.getElementById(id)
      const checkIniTW = Select.getInstance(elSelectId)
      if (checkIniTW == null) { this.initSelectComponent(id) }
      this.showSelect = !this.showSelect
    }
  }
}
</script>