Diferencia entre revisiones de «PHP Livewire»
Ir a la navegación
Ir a la búsqueda
| Línea 133: | Línea 133: | ||
::<syntaxhighlight lang="java" enclose="div" highlight="" > | ::<syntaxhighlight lang="java" enclose="div" highlight="" > | ||
<div> | <div> | ||
| − | Descripción:<input type="text" maxlength="45" required size="45 | + | Descripción:<input type="text" maxlength="45" required size="45" name="descripcion" /> |
</div> | </div> | ||
| Línea 266: | Línea 266: | ||
protected $rules = [ | protected $rules = [ | ||
| − | 'descripcion' => 'required|min:5|max:45', | + | 'descripcion' => 'required|string|min:5|max:45', |
]; | ]; | ||
| Línea 282: | Línea 282: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
| − | : Para depurar o funcionamento dos compoñente livewire | + | : Para depurar o funcionamento dos compoñente livewire podemos empregar o facade Log::info e ver as mensaxes no arquivo /storage/logs/laravel.log (podedes borrar o contido antes de executar para ter todo limpo ao principio). |
| Línea 313: | Línea 313: | ||
@error('descripcion') <span class="error">{{ $message }}</span> @enderror | @error('descripcion') <span class="error">{{ $message }}</span> @enderror | ||
</div> | </div> | ||
| + | |||
| + | </syntaxhighlight> | ||
| + | |||
| + | |||
| + | * Se queremos personalizar as mensaxes de erro: | ||
| + | :'''Arquivo: app/Livewire/Marca.php''' | ||
| + | ::<syntaxhighlight lang="java" enclose="div" highlight="`13-15,22-26" > | ||
| + | <?php | ||
| + | ........... | ||
| + | |||
| + | protected $messages = [ | ||
| + | 'descripcion.required' => 'La descripción es obligatoria.', | ||
| + | 'descripcion.string' => 'La descripción debe ser una cadena de texto.', | ||
| + | 'descripcion.min' => 'La descripción debe tener al menos 5 caracteres.', | ||
| + | 'descripcion.max' => 'La descripción no puede tener más de 45 caracteres.', | ||
| + | ]; | ||
| + | .............. | ||
</syntaxhighlight> | </syntaxhighlight> | ||
| Línea 320: | Línea 337: | ||
* Fixerase que neste caso a validación faise cando o usuario preme o botón de submit. | * Fixerase que neste caso a validación faise cando o usuario preme o botón de submit. | ||
| − | : Se queremos que se faga a validación cando o usuario cambio o contido da caixa de texto | + | : Se queremos que se faga a validación cando o usuario cambio o contido da caixa de texto temos que: |
| + | :* Empregar o método update($propiedade) que será chamado de forma automáticamente cando o campo teña unha modificación. Dito método fará a validación da propiedade. Temos que chamar ao método '''validatyOnly'''. | ||
| + | :* Cambiar a propiedade wire:model da caixa de texto por '''wire:model.live''' | ||
: Lembrar que estas chamadas fanse ao servidor polo que pode ser que non nos interese para aforrar recursos e comunicacións entre cliente e o servidor. | : Lembrar que estas chamadas fanse ao servidor polo que pode ser que non nos interese para aforrar recursos e comunicacións entre cliente e o servidor. | ||
| + | |||
| + | |||
| + | :'''Arquivo: app/views/campos_marca.blade.php''' | ||
| + | : '''MOI IMPORTANTE:''' Tedes que cambiar a propiedade wire:model por wire:model'''.live''' | ||
| + | ::<syntaxhighlight lang="java" enclose="div" highlight="3" > | ||
| + | <div> | ||
| + | Descripción:<input type="text" maxlength="45" size="45" required | ||
| + | wire:model.live="descripcion" name="descripcion" /> | ||
| + | @error('descripcion') <span class="error">{{ $message }}</span> @enderror | ||
| + | </div> | ||
| + | </syntaxhighlight> | ||
| + | |||
:'''Arquivo: app/Livewire/Marca.php''' | :'''Arquivo: app/Livewire/Marca.php''' | ||
| − | ::<syntaxhighlight lang="java" enclose="div" highlight=" | + | ::<syntaxhighlight lang="java" enclose="div" highlight="3-5" > |
| + | |||
| + | .............. | ||
| + | public function updated($propiedade){ | ||
| + | $this->validateOnly($propiedade); | ||
| + | } | ||
| + | ............. | ||
| + | </syntaxhighlight> | ||
| + | |||
| + | : Ao facer isto, cada vez que se preme no imput fará a validación. | ||
| + | : Lembrar que poñer isto non quita que teñades a chamada $this->validate() cando se vaia a dar de alta/modificar os datos | ||
| − | |||
| + | * Mirade a documentación xa que a validación tamén se pode definir en cada un dos campos en vez de empregar a propiedade $rules: https://livewire.laravel.com/docs/validation (escoller versión 3 na parte esquerda da páxina) | ||
<br /> | <br /> | ||
Revisión del 09:52 10 abr 2025
Sumario
Introducción
- Livewire permite o uso de compoñentes integrados en Laravel nos que se establece unha comunicación bidireccional (podemos enviar información desde o cliente (HTML) ao servidor (controlador) e viceversa sen necesidade de recargar completamente a páxina).
- É o mesmo concepto que se empregaba en AJAX e que agora se usa con FETCH, pero integrado no framework de Laravel.
- IMPORTANTE: Cando vexades a documentación mirade que version estades a consultar xa que dende a versión 2 á versión 3 houbo cambios.
- Unha vez instalado en Laravel podedes consultar a versión instalada buscando a entrada livewire/livewire no arquivo composor.json no raíz do proxecto.
- Polo de agora (versión 10-12) estamos a traballar coa versión 3.x de Livewire.
Instalación
- No directorio raíz do proxecto Laravel escribe: composer require livewire/livewire
- Unha vez instalado en Laravel podedes consultar a versión instalada buscando a entrada livewire/livewire no arquivo composor.json no raíz do proxecto.
- Polo de agora (versión 10-12) estamos a traballar coa versión 3.x de Livewire.
Validación de campos
- Imos crear a táboa marcas e imos crear unha relación entre perfumes e marcas.
- A nivel de mysql:
CREATE TABLE perfumes.marcas ( `id` int NOT NULL, `descripcion` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_spanish2_ci NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_spanish2_ci; INSERT INTO `marcas` (`id`, `descripcion`) VALUES (1, 'Descripción actualizada da marca con id=1'), (2, 'ADIDAS'), (3, 'ARAMIS');
- Táboa perfumes
CREATE TABLE perfumes.perfumes ( `id` int NOT NULL, `descripcion` varchar(45) CHARACTER SET utf8mb4 COLLATE utf8mb4_spanish2_ci NOT NULL, `prezo` decimal(8,2) NOT NULL, `data_compra` date DEFAULT NULL, `marca_id` int DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_spanish2_ci; ALTER TABLE perfumes.perfumes ADD PRIMARY KEY (`id`), ADD KEY `fk_PERFUMES_1_idx` (`id`), ADD KEY `fk_PERFUMES_MARCA_idx` (`marca_id`); INSERT INTO perfumes.perfumes (`id`, `descripcion`, `prezo`, `data_compra`, `marca_id`) VALUES (18, 'Best Aramis', '54.32', '2024-01-18', 2), (19, 'Novo perfume da marca con id 1', '100.22', '2024-01-22', 1);
- Creamos o modelo, ruta, controlador e polo de agora imos facer a vista para crear unha nova marca.
- Dende o terminal escribimos: php artisan make:model Marca --resource
- Arquivo: routes/web.php
<?php use Illuminate\Support\Facades\Route; use App\Http\Controllers\PerfumeController; use App\Http\Controllers\MarcaController; Route::resource('perfumes', PerfumeController::class); Route::resource('marcas', MarcaController::class);
- O arquivo de MarcaController xa se crearia con todo o código necesario para a xestión.
- Arquivo resources/views/marcas/form_alta_marcas.blade.php (creado o cartafol marcas dentro de view)
@extends('plantilla'); @section('pageTitle', 'Alta de marcas') @section('content') <h2>Alta de novos perfumes</h2> @if (session()->has('idPerfume')) <h4>Creado un novo rexistro co id: {{session('idPerfume')}}</h4> @endif @if(count($errors) > 0) <div class="errors"> <ul> @foreach($errors->all() as $error) <li>{{ $error }}</li> @endforeach </ul> </div> @endif @include('mensaxes.alertas_javascript') @endsection
- Como fixemos con perfume, os campos que conforman o formulario en Alta e Modificar son os mesmos, polo que imos crear un arquivo para facer un include nas dúas vistas:
- Arquivo: resources/views/marcas/campos_marca.blade.php
<div> Descripción:<input type="text" maxlength="45" required size="45" name="descripcion" /> </div>
- Como vemos o contido é parecido ao que tiñammos con perfumes, pero agora o contido (form e campos) os imos xestionar dende un compoñente Livewire.
- Creamos o compoñente con esta orde: php artisan make:livewire marca
- Isto creará dous arquivos en Laravel:
- CLASS: app/Livewire/Marca.php => Ven a ser o controlador que vimos ata o de agora en Laravel.
- VIEW: resources/views/livewire/marca.blade.php => Ven a ser a vista que vai visualizar Laravel no cliente.
- Arquivo: app/Livewire/Marca.php
<?php namespace App\Livewire; use Livewire\Component; class Marca extends Component { public function render() { return view('livewire.marca'); } }
- Básicamente indicamos en render a vista que vai enviar ao cliente.
- Arquivo resource/views/Livewire/marca.blade.php
<form method="post" action="{{route('marcas.store')}}" name="formulario_marcas"> @csrf @include('marcas.campos_marca') <div> <input type="submit" name="btnAlta" value="Alta" onClick="return confirm('Estás seguro de dar de alta a nova marca ');"/> <input type="reset" name="btnBorrar" value="Limpar" /> </div> </form>
- Agora para incluir o compoñente Livewire nunha view de Laravel temos que poñer:
- Arquivo resouces/views/marcas/form_alta_marca.blade.php
@extends('plantilla'); @section('pageTitle', 'Alta de marcas') @section('content') <h2>Alta de novos perfumes</h2> <livewire:marca /> ................
- Se agora poñemosm na url: http://localhost:8080/marcas/create veremos que aparecerá unha vista tal cual aparecía cando fixemos o de perfume, pero a diferenza de perfumes, esta vista (os campos e form) se xestionan cun compoñente Livewire.
- Agora imos ver os cambios que temos que facer para xestionar os campos do formulario.
- Primero imos definir no controlador do compoñente livewire os campos que imos xestionar. No noso caso está a descripcion.
<?php namespace App\Livewire; use Livewire\Component; class Marca extends Component { public $descripcion = "Valor inicial"; // O valor inicial non é necesasrio. Soamente para que vexades como dito valor se carga na vista. public function render() { return view('livewire.marca'); } }
- Arquivo: resources/views/marcas/campos_marca.blade.php
<div> Descripción:<input type="text" maxlength="45" required size="45" wire:model="descripcion" name="descripcion" /> </div>
- wire:model="descripcion": O que estamos a dicir con isto é que este input está vinculado á propiedade $descripcion definida no compoñente Livewire. Calquera modificación realizada polo usuario no cliente (na páxina web) actualizará automaticamente o valor da propiedade no servidor grazas á reactividade proporcionada por Livewire. Ademais, se a propiedade no servidor cambia, ese cambio tamén se reflectirá no cliente.
- Se vos dades conta non temos a propiedade value como tiñamos en perfumes.
- Se agora cargades a páxina veredes como o valor inicial se carga no input.
- Agora imos a facer a validación no servidor. Para iso temos que definir unha propiedade $rules coas regras de validación que xa empregamos en Laravel.
- Ademáis imos crear un método ao que vai chamar o formulario cando faga submit e que fará a validación dos campos. No exemplo imos chamar ao método gardarMarca.
- Arquivo: app/Livewire/Marca.php
<?php namespace App\Livewire; use Illuminate\Support\Facades\Log; use Livewire\Component; class Marca extends Component { public $descripcion = "Valor inicial"; protected $rules = [ 'descripcion' => 'required|string|min:5|max:45', ]; public function render() { return view('livewire.marca'); } public function gardarMarca(){ $this->validate(); Log::info('Pasa a validación'); } }
- Para depurar o funcionamento dos compoñente livewire podemos empregar o facade Log::info e ver as mensaxes no arquivo /storage/logs/laravel.log (podedes borrar o contido antes de executar para ter todo limpo ao principio).
- Para chamar a ese método temos que modificar a vista do compoñente livewire.
<form wire:submit.prevent="gardarMarca"> @csrf @include('marcas.campos_marca') <div> <input type="submit" name="btnAlta" value="Alta" onClick="return confirm('Estás seguro de dar de alta a nova marca ');"/> <input type="reset" name="btnBorrar" value="Limpar" /> </div> </form>
- Con isto wire:submit.prevent="gardarMarca" estamos a decir que cando faga o submit chame de forma asíncrona ao controlador do compoñente livewire ao método gardarMarca.
- Nota: Podemos asociar calquera click de botón directamente ao un método no controlador do livewire, da forma: <button wire:click="gardarMarca">+</button>
- Tamén imos visualizar os erros de validación que poida enviar o controlador Livewire se non pasa a validación. Para iso temos que empregar a directiva @error sobre cada un dos campos que teñen validación. No exemplo se coloca ao lado do input, pero poderían ir en calquera parte.
- Arquivo: resources/views/marcas/campos_marca.blade.php
<div> Descripción:<input type="text" maxlength="45" required size="45" wire:model="descripcion" name="descripcion" /> @error('descripcion') <span class="error">{{ $message }}</span> @enderror </div>
- Se queremos personalizar as mensaxes de erro:
- Arquivo: app/Livewire/Marca.php
<?php ........... protected $messages = [ 'descripcion.required' => 'La descripción es obligatoria.', 'descripcion.string' => 'La descripción debe ser una cadena de texto.', 'descripcion.min' => 'La descripción debe tener al menos 5 caracteres.', 'descripcion.max' => 'La descripción no puede tener más de 45 caracteres.', ]; ..............
- Fixerase que neste caso a validación faise cando o usuario preme o botón de submit.
- Se queremos que se faga a validación cando o usuario cambio o contido da caixa de texto temos que:
- Empregar o método update($propiedade) que será chamado de forma automáticamente cando o campo teña unha modificación. Dito método fará a validación da propiedade. Temos que chamar ao método validatyOnly.
- Cambiar a propiedade wire:model da caixa de texto por wire:model.live
- Lembrar que estas chamadas fanse ao servidor polo que pode ser que non nos interese para aforrar recursos e comunicacións entre cliente e o servidor.
- Arquivo: app/views/campos_marca.blade.php
- MOI IMPORTANTE: Tedes que cambiar a propiedade wire:model por wire:model.live
<div> Descripción:<input type="text" maxlength="45" size="45" required wire:model.live="descripcion" name="descripcion" /> @error('descripcion') <span class="error">{{ $message }}</span> @enderror </div>
- Arquivo: app/Livewire/Marca.php
.............. public function updated($propiedade){ $this->validateOnly($propiedade); } .............
- Ao facer isto, cada vez que se preme no imput fará a validación.
- Lembrar que poñer isto non quita que teñades a chamada $this->validate() cando se vaia a dar de alta/modificar os datos
- Mirade a documentación xa que a validación tamén se pode definir en cada un dos campos en vez de empregar a propiedade $rules: https://livewire.laravel.com/docs/validation (escoller versión 3 na parte esquerda da páxina)
Operacións de alta-baixa-modificación
Alta
* A alta faise como sempre pero agora está no controlador do compoñente livewire.
- Arquivo: app/Livewire/Marca.php
............. public function gardarMarca(){ $this->validate(); Log::info('Pasa a validación'); $marcaCreada = Marca::create([ 'descripcion' => $this->descripcion ]); session()->flash('message', "Marca creada correctamente con id $marcaCreada->id"); $this->reset(['descripcion']); } : Fixarse que para enviar unha información á vista empregamos session()->flash que vai gardar nunha variable de sesión (message) o texto a amosar. : Dita variable non pode ser empregada pola páxina, soamente polo compoñente livewire xa que non se recarga a páxina enteira. : A chamada a reset vai poñer en branco os valor da variable $descripcion do compoñente.
Funcionamento
-- Ángel D. Fernández González -- (2025).