Я новичок в 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?
Вы можете избежать обновления 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",
});
});
});
Странно, я протестировал ваш код со своей модификацией, и он работает хорошо, выпадающий список обрабатывается правильно и не перестает работать. Можете ли вы объяснить лучше, с какими проблемами вы сталкиваетесь?
Мой код такой же, как предоставленный ранее. так что никаких серьезных изменений нет, просто исправили атрибуты и добавили провод: игнорировать в div и обернуть его вокруг поля ввода. он ведет себя так же. Однако после отправки формы на обновление функции JavaScript прекратились, в результате чего поле лишилось своей предполагаемой функциональности. Стоит отметить использование Vite для компиляции JavaScript и CSS. Все функции JavaScript объединены в файле app.js.
Да, я использовал сборку npm run для компиляции ресурсов. -- Обратите внимание, что вставка Wire:ignore в <input> не работает, поскольку им манипулирует intl-tel-input, необходим внешний тег. На этом этапе может быть полезно просмотреть вашу форму.
Примечание: чтобы правильно включить CSS, который я использовал import 'intl-tel-input/build/css/intlTelInput.css'
в app.js.
Спасибо за добрый ответ. Конечно, это 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?
Вот как это выглядит, когда оно только что загружено ссылка После отправки формы превратите ее в ссылку 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/datepicker.min.js"></script> @vite('resources/js/app.js')
При нажатии Tab она не ломается.
Если Wire:ignore не сработала, выход из поля с помощью Tab должен нарушить представление (из-за модификатора .blur), поэтому я подозреваю, что есть какой-то другой элемент, который создает проблемы при отправке формы. Вы должны опубликовать соответствующий код формы, а не изображения. Я вижу, что вы используете Flowbite, у него иногда случаются сбои с Livewire. Я все еще не вижу intlTelInput.css
Я удалил Flowbite и протестировал его. Проблема все еще та же, intleTelInput.css. Я импортировал его в app.css, например @import 'intl-tel-input/build/css/intlTelInput.css';
Вот ссылка на форму на github ссылка
Я увидел ваш код и обнаружил проблему. Я отредактировал свой ответ, внеся некоторые исправления.
Очень хорошо! Если хотите, можете принять ответ и закрыть вопрос.
Спасибо за ваш любезный ответ. Однако я попытался использовать Wire:ignore внутри обернутого <div>, но это оказалось неэффективно. Изучив Wire:ignore в Livewire 3, я обнаружил известные проблемы, связанные с его функциональностью в этой версии.