Tengo un formulario con un campo de entrada de búsqueda como componente laravel livewire. Quiero buscar sugerencias (otro componente) para que se muestren si el usuario hace clic en el campo o si el usuario toca el campo. Así que agregué wire:focus="handleFocus" , que emite un evento para que lo muestre el componente de sugerencias. Funciona bien hasta ahora.
Si el campo tiene foco y el usuario vuelve a hacer clic en el campo, las sugerencias deberían volver a ocultarse. wire:focus no se activa, así que agregué wire:click="handleClick". Así que terminé con
<input type="text" wire:model="searchTerm" wire:focus="handleFocus" wire:click="handleClick">Funciona para el caso de que un usuario toque el campo: aparecen sugerencias, luego hace clic en el campo: las sugerencias desaparecen. Bien.
Problema : si un usuario hace clic en el campo, ambos controladores de eventos wire:focus y wire:click se activan para que el campo aparezca y desaparezca inmediatamente de nuevo.
Ya pasé horas jugando con rebote, prevención, agregando temporizador a mi componente pero sin ningún éxito. En CSS hay: focus-visible que resolvería el problema en realidad, pero no pude encontrar algo como para Javascript.
Mi pila también incluye Javascript/AlpineJS si ayuda a encontrar una solución.
Su problema reside en el hecho de que el evento de click activa un foco. Por suerte para ti, Livewire tiene acceso a los métodos y datos de JS, por lo que puedes acceder al elemento activo. Si combinamos el evento mousedown con su evento de click , podemos pasar algunos datos para determinar si handleClick debe procesarse:
<input type="text" wire:model="searchTerm" wire:focus="handleFocus" wire:mousedown="handleMousedown(document.activeElement.getAttribute('id')" wire:click="handleClick($event.currentTarget.getAttribute('id'))">Luego, en tu componente:
public $activeElementId = null; public function handleMousedown($activeElementId) { $this->activeElementId = $activeElementId; } public function handleClick($inputId) { if ($this->activeElementId == $inputId) { // Do Stuff } } Esto funciona porque mousedown dispara antes de enfocar el elemento. Esto enviará la identificación del elemento activo a su componente. Si esto es lo mismo que su entrada, entonces sabe que la entrada ya estaba enfocada.