iamstevendao / vue-tel-input

International Telephone Input with Vue
https://iamstevendao.com/vue-tel-input/
MIT License
818 stars 342 forks source link

Is it possible to teleport the dropdown to another component? #365

Open yukosgiti opened 2 years ago

yukosgiti commented 2 years ago

When the component is rendered at the end of a container, the opening dropdown is clipped by the container. Is it possible to teleport the dropdown to another compnent to fix this issue? Something like this

<container1>
    <container2>
        <vue-tel-input teleportDropdownTo="#target"/>
    </container2>
    <div id="#target"/> //The dropdown is rendered here
</container1>
MiguelQueiroz commented 1 year ago

Yes, sadly ugly since this should be handled by the component.

I solved using this css class:

/ Fix int phone css /

ul.vti__dropdown-list {
  position: absolute;
  width: 100%;
  border-radius: 1px !important;
  outline: none;
  background-color: white;
  padding-left: 0px !important;
}

And on the vue component:

 <vue-tel-input
              ref="vue-tel-input"
              v-model="client.phone"
              @validate="validatePhone"
              @open="vueTelInputDropDownOpen($refs['vue-tel-input'].$refs)"
              mode="international"
              :dropdownOptions="{ showFlags: true, showSearchBox: true, showDialCodeInList: true }"
              :inputOptions="{ showDialCode: true, placeholder: 'Phone' }"
            >
            </vue-tel-input>

and the vue template methods:

 methods: {
    vueTelInputDropDownOpen ($refs) {

  /* By the way, need the timeout because, the event open of the dropdown is before the ul is created, so the ul is not available, need to wait a frame, hence the timeout, to catch the right reference "$ref" to the input*/
   setTimeout(() => {
        let listElement = $refs.list
        let targetPosition=$refs.list.parentElement.closest('li') //modify as needed

        //detach and re-attach to another position.
        let detached= listElement.parentNode.removeChild(listElement);  
        targetPosition.appendChild(detached);
      })

    },

Or go full height / width CSS:

ul.vti__dropdown-list {
  position: fixed; 
  min-height: 100%;
  width: 100%;
  border-radius: 1px !important;
  outline: none;
  padding-left: 0px !important;
  z-index: 1000;
}