Проблемы Laravel Livewire DOM с пользовательским JS

Я новичок в Laravel Livewire. Я пытаюсь сохранить поле формы, в котором я использую JS-библиотеку intlTelInput, чтобы добавить код страны перед номером телефона.

Я добавил код JS в app.js, что-то вроде этого.

import intlTelInput from 'intl-tel-input';
const elementsWithPhoneId = document.querySelectorAll('[id = "phone"]');
elementsWithPhoneId.forEach(element => {

    const iti = intlTelInput(element, {
        initialCountry: "bh",
        separateDialCode: true,
        onlyCountries: ['bh', 'sa', 'ae', 'qa', 'kw', 'om', 'us', 'gb'],
        utilsScript: "https://cdn.jsdelivr.net/npm/[email protected]/build/js/utils.js",
    });
});

Поля в компоненте выглядят так

<div class = "flex flex-wrap lg:flex-nowrap justify-center w-full">
    <div class = "w-full py-2 lg:w-1/2 md:w-1/2 px-2 grid grid-cols-1">
        <label for = "inputC1P1" class = "w-full font-medium py-1">Primary Phone : <span class = "text-red-600"> *</span></label>
        <input
            required
            type = "tel"
            class = "form-input border border-1 rounded-md w-full my-1 border-gray-300 shadow-md hover:transition-all"
            id = "phone"
            placeholder = "3344 5566"
            wire:model.blur = "C1PrimaryContact"
        />
        <div>
            @error('C1PrimaryContact') <p class = "text-red-600 font-light text-xs antialiased italic">{{ $message }}</p>  @enderror
        </div>
    </div>
    <div class = "w-full py-2 lg:w-1/2 md:w-1/2 px-2 grid grid-cols-1">
        <label for = "inputC1P2" class = "w-full font-medium py-1">Secondary Phone :</label>
        <input
            type = "tel"
            class = "form-input border border-1 rounded-md w-full my-1 border-gray-300 shadow-md hover:transition-all"
            id = "phone"
            placeholder = "3344 5566"
            wire:model.blur = "C1SecondaryContact"
        />
        <div>
            @error('C1SecondaryContact') <p class = "text-red-600 font-light text-xs antialiased italic">{{ $message }}</p> @enderror
        </div>
    </div>
</div>

Он прекрасно загружается при первой загрузке компонента. Однако как только мы что-то изменяем или отправляем форму, она перестает работать, и весь app.js перестает работать.

Я сделал несколько альтернатив, таких как добавление JS-кода внутрь компонента с помощью директив Blade или даже применил его.

document.addEventListener('livewire:init', () => {})

Пока нужно что-то другое. Что-то мне не хватает или мне нужно что-то настроить в настройках Livewire?

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Поиск нового уровня в Laravel с помощью MeiliSearch и Scout
Поиск нового уровня в Laravel с помощью MeiliSearch и Scout
Laravel Scout - это популярный пакет, который предоставляет простой и удобный способ добавить полнотекстовый поиск в ваше приложение Laravel. Он...
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
В последние годы архитектура микросервисов приобрела популярность как способ построения масштабируемых и гибких приложений. Laravel , популярный PHP...
Как построить CRUD-приложение в Laravel
Как построить CRUD-приложение в Laravel
Laravel - это популярный PHP-фреймворк, который позволяет быстро и легко создавать веб-приложения. Одной из наиболее распространенных задач в...
1
0
203
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Вы можете избежать обновления DOM с помощью Livewire, используя Wire:ignore, например, окружив входы <div>:

<div class = "w-full py-2 lg:w-1/2 md:w-1/2 px-2 grid grid-cols-1">

    <label .... > .... </label>
    
    <div class = "...." wire:ignore>
       <input .... />
    <div>

    .....

Обратите внимание, что вы назначаете один и тот же идентификатор обоим входам: это не очень хорошая практика, идентификатор должен быть уникальным. Вы можете выбрать другой атрибут для выбора входных данных, например:

const elementsWithPhoneId = document.querySelectorAll("input[type=tel]");

конкретный класс может быть другим вариантом.

Кроме того, атрибуты for ваших меток не соответствуют соответствующему входному идентификатору.

Редактировать

Глядя на ваш репозиторий, я вижу, что вы используете redirectRoute() с опцией навигации: true. Это приводит к обновлению тела без фактического обновления документа браузера, поэтому внешние библиотеки должны быть вынуждены повторно инициализировать связанные элементы. Чтобы добиться этого, мы можем переместить код, который инициализирует входные данные type-tel, в прослушиватель событий для события livewire:navigated:

document.addEventListener('livewire:navigated', () => {

    const elementsTypePhone = document.querySelectorAll("input[type=tel]");

    elementsTypePhone.forEach(element => {

        // console.info ("element: ", element);

        const iti = intlTelInput(element, {

            initialCountry: "bh",
            strictMode: true,
            separateDialCode: true,
            onlyCountries: ['bh', 'sa', 'ae', 'qa', 'kw', 'om', 'us', 'gb'],
            utilsScript: "https://cdn.jsdelivr.net/npm/[email protected]/build/js/utils.js",
        });
    });
});

Спасибо за ваш любезный ответ. Однако я попытался использовать Wire:ignore внутри обернутого <div>, но это оказалось неэффективно. Изучив Wire:ignore в Livewire 3, я обнаружил известные проблемы, связанные с его функциональностью в этой версии.

Shkaib Nazar 11.04.2024 04:09

Странно, я протестировал ваш код со своей модификацией, и он работает хорошо, выпадающий список обрабатывается правильно и не перестает работать. Можете ли вы объяснить лучше, с какими проблемами вы сталкиваетесь?

TUPKAP 11.04.2024 14:52

Мой код такой же, как предоставленный ранее. так что никаких серьезных изменений нет, просто исправили атрибуты и добавили провод: игнорировать в div и обернуть его вокруг поля ввода. он ведет себя так же. Однако после отправки формы на обновление функции JavaScript прекратились, в результате чего поле лишилось своей предполагаемой функциональности. Стоит отметить использование Vite для компиляции JavaScript и CSS. Все функции JavaScript объединены в файле app.js.

Shkaib Nazar 12.04.2024 00:34

Да, я использовал сборку npm run для компиляции ресурсов. -- Обратите внимание, что вставка Wire:ignore в <input> не работает, поскольку им манипулирует intl-tel-input, необходим внешний тег. На этом этапе может быть полезно просмотреть вашу форму.

TUPKAP 12.04.2024 01:14

Примечание: чтобы правильно включить CSS, который я использовал import 'intl-tel-input/build/css/intlTelInput.css' в app.js.

TUPKAP 12.04.2024 01:24

Спасибо за добрый ответ. Конечно, это JS в моем app.js.

import intlTelInput from 'intl-tel-input';
document.addEventListener('livewire:init', () => {
    const elementsWithPhoneId = document.querySelectorAll('input[type=tel]');
    elementsWithPhoneId.forEach(element => {

        const iti = intlTelInput(element, {
            initialCountry: "bh",
            strictMode: true,
            separateDialCode: true,
            onlyCountries: ['bh', 'sa', 'ae', 'qa', 'kw', 'om', 'us', 'gb'],
            utilsScript: "https://cdn.jsdelivr.net/npm/[email protected]/build/js/utils.js",
        });
    });
});

Это мой компонент в шаблоне лезвия

<div class = "w-full py-2 lg:w-1/2 md:w-1/2 px-2 grid grid-cols-1" >
    <label for = "inputC1P1" class = "w-full font-medium py-1">Primary Phone : <span class = "text-red-600"> *</span></label>
    <div wire:ignore>
        <input
            type = "tel"
            id = "inputC1P1"
            class = "@error('C1PrimaryContact') bg-red-200 @enderror form-input border border-1 rounded-md w-full my-1 border-gray-300 shadow-md hover:transition-all"
            placeholder = "3344 5566"
            wire:model.blur = "C1PrimaryContact"
            required
        />
    </div>
    <div>
        @error('C1PrimaryContact') <p class = "text-red-600 font-light text-xs antialiased italic">{{ $message }}</p>  @enderror
    </div>
</div>

Кажется, все в порядке. Поскольку у нас есть Wire:model.blur, входное значение немедленно отправляется на серверную часть, когда он теряет фокус: что происходит, когда вы выходите из поля? (например, с помощью клавиши Tab) В этом случае раскладка сохраняется или ломается? Есть ли у вас форма, которая обертывает входные данные? Могу я увидеть это? Как вы включили CSS?

TUPKAP 12.04.2024 02:16

Вот как это выглядит, когда оно только что загружено ссылка После отправки формы превратите ее в ссылку CSS и JS добавлены вот так @vite('resources/css/app.css') <title>{{ $title ?? 'Page Title' }} - {{env('APP_NAME')}}</title><script src = "https://cdnjs.cloudflare.com/ajax/libs/flowbite/2.3.0/d‌​atepicker.min.js"></‌​script> @vite('resources/js/app.js') При нажатии Tab она не ломается.

Shkaib Nazar 12.04.2024 02:49

Если Wire:ignore не сработала, выход из поля с помощью Tab должен нарушить представление (из-за модификатора .blur), поэтому я подозреваю, что есть какой-то другой элемент, который создает проблемы при отправке формы. Вы должны опубликовать соответствующий код формы, а не изображения. Я вижу, что вы используете Flowbite, у него иногда случаются сбои с Livewire. Я все еще не вижу intlTelInput.css

TUPKAP 12.04.2024 03:21

Я удалил Flowbite и протестировал его. Проблема все еще та же, intleTelInput.css. Я импортировал его в app.css, например @import 'intl-tel-input/build/css/intlTelInput.css';

Shkaib Nazar 12.04.2024 03:32

Вот ссылка на форму на github ссылка

Shkaib Nazar 12.04.2024 03:51

Я увидел ваш код и обнаружил проблему. Я отредактировал свой ответ, внеся некоторые исправления.

TUPKAP 12.04.2024 16:51

Очень хорошо! Если хотите, можете принять ответ и закрыть вопрос.

TUPKAP 12.04.2024 20:43

Другие вопросы по теме