Проверка и сохранение на основе выбора переключателя и аутентификации
Я столкнулся с тремя проблемами, которые все связаны с тем, что я изо всех сил пытаюсь добавить событие.
@click="isQuestion = true"
на радиостанциях в цикле и проверять при определенных условиях, в зависимости от того, какой переключатель выбран, например, если аутентифицирован, то сохраните идентификатор пользователя, но если не его анонимный отзыв, если дополнительный адрес электронной почты не предоставлен.
В базе данных есть четыре записи для типа билета, см. Изображение для лучшего объяснения:
Мне нужна помощь по трем вопросам:
- Показывать только если пользователь аутентифицирован
- Показать и скрыть, и если выбран переключатель, если выбрано что-то еще, показать и скрыть
subject
- Проверять и сохранять информацию только в зависимости от выбора переключателя
- Если выбран какой-либо переключатель, кроме проверки и сохранения и
- Если выбран, подтвердить и сохранить все, кроме
email
иdata_protection
ПОЖАЛУЙСТА, ОБРАТИТЕ ВНИМАНИЕ : большая часть логики уже используется, чтобы скрыть определенные поля, если нет
I have a question
радио-кнопка выбирается, делая это
x-show="!isQuestion"
просто не уверен как привязать его к переключателям.
Любая помощь или руководство приветствуются
Создать компонент Livewire тикета
<div x-data="{ isOpen: false, isQuestion: false, send: false }" @keydown.window.escape="isOpen = false" x-init="
@this.on('change-send', () => {
send = !send;
})
">
<div class="fixed bottom-0 right-0 top-0 flex items-center">
<div class="transform -rotate-90 origin-bottom-right">
<x-jet-button @click="isOpen = !isOpen" class="!rounded-none !rounded-t-lg !p-3">
{{ __('Feedback') }}
</x-jet-button>
</div>
</div>
<div class="fixed inset-0 overflow-hidden pointer-events-none" x-cloak>
<div class="absolute inset-0 overflow-hidden">
<div x-show="isOpen" x-description="Background overlay, show/hide based on slide-over state." x-transition:enter="ease-in-out duration-500" x-transition:enter-start="opacity-0" x-transition:enter-end="opacity-100" x-transition:leave="ease-in-out duration-500" x-transition:leave-start="opacity-100" x-transition:leave-end="opacity-0" class="absolute inset-0 bg-gray-500 bg-opacity-75 transition-opacity" aria-hidden="true"></div>
<section class="absolute inset-y-0 right-0 pl-10 max-w-full flex" aria-labelledby="slide-over-heading">
<div x-show="isOpen" x-description="Slide-over panel, show/hide based on slide-over state." x-transition:enter="transform transition ease-in-out duration-500 sm:duration-700" x-transition:enter-start="translate-x-full" x-transition:enter-end="translate-x-0" x-transition:leave="transform transition ease-in-out duration-500 sm:duration-700" x-transition:leave-start="translate-x-0" x-transition:leave-end="translate-x-full" class="relative w-screen max-w-md pointer-events-auto">
<div x-show="isOpen" x-description="Close button, show/hide based on slide-over state." x-transition:enter="ease-in-out duration-500" x-transition:enter-start="opacity-0" x-transition:enter-end="opacity-100" x-transition:leave="ease-in-out duration-500" x-transition:leave-start="opacity-100" x-transition:leave-end="opacity-0" class="absolute top-0 left-0 -ml-8 pt-4 pr-2 flex sm:-ml-10 sm:pr-4">
<button type="button" @click="isOpen = !isOpen" class="rounded-md text-gray-300 hover:text-white focus:outline-none focus:ring-2 focus:ring-white">
<span class="sr-only">Close panel</span>
<!-- Heroicon name: outline/x -->
<svg class="h-6 w-6" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" aria-hidden="true">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
</svg>
</button>
</div>
<div class="h-full flex flex-col py-6 bg-white shadow-xl overflow-y-scroll">
<div x-show="!send" class="px-4 sm:px-6">
<h2 id="slide-over-heading" class="text-lg font-medium text-gray-900">
{{ __('Do you have any feedback?') }}
</h2>
<p class="text-sm leading-5 text-gray-700">
{{__('We appreciate your feedback. Would you change something? Do you think something is good? We look forward to any kind of feedback.')}}
</p>
</div>
<div x-show="send" class="mt-6 relative flex-1 flex px-4 sm:px-6 justify-center items-center">
<div class="flex flex-col justify-center">
<div class="flex justify-center">
<!-- Heroicon name: outline/emoji-happy -->
<svg class="h-24 w-24" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1" d="M14.828 14.828a4 4 0 01-5.656 0M9 10h.01M15 10h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path>
</svg>
</div>
<h3 class="text-lg leading-6 font-medium text-gray-900 px-3 mt-4 text-center">
{{ __('Thanks') }}
</h3>
<p class="p-3 text-center">
{{ __('Thank you for your feedback, it was saved successfully.') }}
</p>
</div>
</div>
<div x-show="!send" class="mt-6 relative flex-1 flex flex-col justify-between px-4 sm:px-6">
<div class="px-4 divide-y divide-gray-200 sm:px-6">
<fieldset class="space-y-2 my-4">
<x-jet-label for="feedback_type">
{{ __('Type of feedback') }}
</x-jet-label>
<div class="space-y-5">
@foreach ($ticket_types as $ticket_type)
<div>
<div class="relative flex items-start">
<div class="absolute flex items-center h-5">
<x-radio-button wire:model="ticket_type" @click="isQuestion = false" id="{{ $ticket_type->id }}" aria-describedby="{{ $ticket_type->id }}_description" value="{{ $ticket_type->id }}" class="h-4 w-4 transition duration-150 ease-in-out" />
</div>
<div class="pl-7 text-sm leading-5">
<x-jet-label for="{{ $ticket_type->id }}_title">
{{ $ticket_type->title }}
</x-jet-label>
<p id="{{ $ticket_type->id }}_description" class="text-gray-500">
{{ $ticket_type->description }}
</p>
</div>
</div>
</div>
@endforeach
</div>
<x-input-error for="ticket_type" />
</fieldset>
<div class="space-y-6 pt-6 pb-5">
<div class="space-y-1" x-show="isQuestion">
<x-jet-label for="subject">{{ __('Subject') }}</x-jet-label>
<x-jet-input wire:model="subject" id="subject" class="block mt-1 w-full" type="text" name="subject" aria-describedby="subject" />
<x-input-error for="description" />
</div>
<div class="space-y-1">
<x-jet-label for="description">
{{ __('Feedback') }}
</x-jet-label>
<x-textarea wire:model="description" id="description" rows="4" class="block mt-1 w-full"></x-textarea>
<x-input-error for="description" />
</div>
<div class="space-y-1" x-show="!isQuestion">
<div class="flex justify-between">
<x-jet-label for="email_optional">{{ __('E-mail address') }}</x-jet-label>
<span id="email_optional" class="font-normal text-sm leading-5 text-gray-500">
{{ __('optional') }}
</span>
</div>
<x-jet-input wire:model="email_optional" id="email_optional" class="block mt-1 w-full" type="email" name="email_optional" aria-describedby="email_optional" />
</div>
<div class="space-y-1" x-show="!isQuestion">
<label for="data_protection" class="flex items-center">
<x-jet-checkbox wire:model="data_protection" id="data_protection" name="data_protection" />
<span class="ml-2 text-sm text-gray-600">{{ __('I have read the privacy policy and accept it.') }}</span>
</label>
</div>
</div>
<div class="space-y-4 pt-4 pb-6" x-show="!isQuestion">
<div class="text-sm leading-5" x-data="{extra: false}">
<a href="#" x-on:click.prevent="extra = !extra" class="group space-x-2 inline-flex items-center text-gray-500 hover:text-gray-900 transition ease-in-out duration-150">
<svg class="h-5 w-5 text-gray-400 group-hover:text-gray-500 transition ease-in-out duration-150" viewBox="0 0 20 20" fill="currentColor">
<path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-8-3a1 1 0 00-.867.5 1 1 0 11-1.731-1A3 3 0 0113 8a3.001 3.001 0 01-2 2.83V11a1 1 0 11-2 0v-1a1 1 0 011-1 1 1 0 100-2zm0 8a1 1 0 100-2 1 1 0 000 2z" clip-rule="evenodd"></path>
</svg>
<span>
{{ __('Why should you provide your email address?') }}
</span>
</a>
<div x-show.transition="extra">
<p class="ml-7">
{{ __('If you include your email address, we will give you feedback on your feedback. We will never use your email address for any other purpose.') }}
</p>
</div>
</div>
</div>
</div>
</div>
<div x-show="!send" class="flex-shrink-0 px-4 py-4 space-x-4 flex justify-end">
<span class="inline-flex rounded-md shadow-sm">
<x-jet-secondary-button @click="isOpen = false">
{{ __('cancel') }}
</x-jet-secondary-button>
</span>
<span class="inline-flex rounded-md shadow-sm">
<x-jet-button wire:click="send">
{{ __('send') }}
</x-jet-button>
</span>
</div>
<div x-show="send" class="flex-shrink-0 px-4 py-4 space-x-4 flex justify-end">
<span class="inline-flex rounded-md shadow-sm">
<x-jet-secondary-button @click="isOpen = false">
{{ __('close') }}
</x-jet-secondary-button>
</span>
</div>
</div>
</div>
</section>
</div>
</div>
</div>
Логика серверной части Livewire
<?php
namespace App\Http\Livewire\Tickets;
use App\Models\Ticket;
use App\Rules\SpamFree;
use Livewire\Component;
class CreateTicketSlideOver extends Component
{
public $ticket_type;
public $subject;
public $description;
public $email_optional;
public $data_protection = false;
public $currentPage;
public function mount()
{
$this->currentPage = url()->current();
}
public function send()
{
$this->validate([
'ticket_type' => 'required',
'subject' => ['required', new SpamFree],
'description' => ['required', new SpamFree],
'email_optional' => ['nullable', 'email'],
'data_protection' => 'accepted',
]);
Ticket::create([
'user_id' => auth()->id(),
'ticket_type' => $this->ticket_type_id,
'slug' => $this->subject,
'subject' => $this->subject,
'description' => $this->body,
'email' => $this->email,
'url' => $this->currentPage,
]);
$this->emitSelf('change-send');
}
public function render()
{
return view('tickets.create-ticket-slide-over');
}
}
Перенос базы данных для заявки
Schema::create('tickets', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id');
$table->foreignId('ticket_type_id');
$table->string('slug')->unique();
$table->string('title');
$table->text('body');
$table->string('email')->nullable();
$table->string('url')->nullable();
$table->boolean('locked')->default(false);
$table->unsignedInteger('visits')->default(0);
$table->timestamps();
});