31
loading...
This website collects cookies to deliver better user experience
php artisan livewire:make DyanmicInputs
// DynamicInputs.php
public Collection $inputs;
public function addInput()
{
$this->inputs->push(['email' => '']);
}
// Taking advantage of Laravel Collections, we are simply
// pushing an array with a key of email and an empty string
// value to the inputs collection.
// This method will be called when we click the add input link.
// DynamicInputs.php
public function removeInput($key)
{
$this->inputs->pull($key);
}
// Again, I'm using Laravel Collections here and I am using
// the pull method to remove the array with the specified key.
// This will be called when we click the remove input link.
//DynamicInputs.php
public function mount()
{
$this->fill([
'inputs' => collect([['email' => '']]),
]);
}
// I am using the Livewire fill method to populate the inputs
// collection when the page loads. This is how we display our
// initial input field.
<div class="max-w-xl w-full">
@foreach($inputs as $key => $input)
<div class="mt-12">
<div class="w-full">
<label for="input_{{$key}}_email" class="sr-only">Email</label>
<input type="email" id="input_{{$key}}_email" wire:model.defer="inputs.{{$key}}.email" class="shadow-sm border-0 focus:outline-none p-3 block w-full sm:text-sm border-gray-300 rounded-md" placeholder="[email protected]" autocomplete="off">
@error('inputs.'.$key.'.email') <span class="text-xs text-red-600">{{ $message }}</span> @enderror
</div>
@if($key > 0)
<div wire:click="removeInput({{$key}})" class="flex items-center justify-end text-red-600 text-sm w-full cursor-pointer">
<svg class="w-4 h-4" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="M9 2a1 1 0 00-.894.553L7.382 4H4a1 1 0 000 2v10a2 2 0 002 2h8a2 2 0 002-2V6a1 1 0 100-2h-3.382l-.724-1.447A1 1 0 0011 2H9zM7 8a1 1 0 012 0v6a1 1 0 11-2 0V8zm5-1a1 1 0 00-1 1v6a1 1 0 102 0V8a1 1 0 00-1-1z" clip-rule="evenodd"></path></svg>
<p>Remove Input</p>
</div>
@endif
</div>
@endforeach
<div wire:click="addInput" class="flex items-center justify-center text-blue-600 text-sm py-4 w-full cursor-pointer">
<svg class="w-4 h-4" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm1-11a1 1 0 10-2 0v2H7a1 1 0 100 2h2v2a1 1 0 102 0v-2h2a1 1 0 100-2h-2V7z" clip-rule="evenodd"></path></svg>
<p class="ml-2">Add New Input</p>
</div>
<div class="w-full flex justify-end mt-12">
<button wire:click="submit" class="px-3 py-1 bg-blue-600 text-white rounded-lg">Submit</button>
</div>
</div>
// dynamic-inputs.blade.php
@foreach($inputs as $key => $input)
// This is a simple foreach loop that we use to iterate
// through the inputs collection. The $key is important!
// dynamic-inputs.blade.php
<label for="input_{{$key}}_email" class="sr-only">Email</label>
<input type="email" id="input_{{$key}}_email" wire:model.defer="inputs.{{$key}}.email" class="shadow-sm border-0 focus:outline-none p-3 block w-full sm:text-sm border-gray-300 rounded-md" placeholder="[email protected]" autocomplete="off">
// When creating dynamic input fields, make sure your for
// attribute and id attribute are dynamic. I accomplish
// this by using the $key value with those attributes.
// Also, for wire:model you want to use inputs.{{$key}}.email
// as your value here. Inputs being the name of the collection
// $key being the dynamic value, and email being the
// collection key.
// dynamic-inputs.blade.php
@if($key > 0)
<div wire:click="removeInput({{$key}})" class="flex items-center justify-end text-red-600 text-sm w-full cursor-pointer">
<svg class="w-4 h-4" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="M9 2a1 1 0 00-.894.553L7.382 4H4a1 1 0 000 2v10a2 2 0 002 2h8a2 2 0 002-2V6a1 1 0 100-2h-3.382l-.724-1.447A1 1 0 0011 2H9zM7 8a1 1 0 012 0v6a1 1 0 11-2 0V8zm5-1a1 1 0 00-1 1v6a1 1 0 102 0V8a1 1 0 00-1-1z" clip-rule="evenodd"></path></svg>
<p>Remove Input</p>
</div>
@endif
// We want to hide the remove input link on the first field.
// To do this, simply add an if statement that checks to see
// if the $key is > 0. If it is, then show it else don't.
// dynamic-inputs.blade.php
<div wire:click="addInput" class="flex items-center justify-center text-blue-600 text-sm py-4 w-full cursor-pointer">
<svg class="w-4 h-4" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm1-11a1 1 0 10-2 0v2H7a1 1 0 100 2h2v2a1 1 0 102 0v-2h2a1 1 0 100-2h-2V7z" clip-rule="evenodd"></path></svg>
<p class="ml-2">Add New Input</p>
</div>
// And lastly we add the link to add the new input. Once
// You've add this you can go ahead and click it and you
// will be creating dynamic input fields.
// DynamicInputs.php
protected $rules = [
'inputs.*.email' => 'required',
];
protected $messages = [
'inputs.*.email.required' => 'This email field is required.',
];
public function submit()
{
$this->validate();
}
// You'll notice we're using . notation to set our validation
// rules.
// dynamic-inputs.blade.php
@error('inputs.'.$key.'.email') <span class="text-xs text-red-600">{{ $message }}</span> @enderror
// Notice the $key variable, you have to set this dynamically
// to make sure you catch the correct error for the correct
// input.