Herramientas de usuario

Herramientas del sitio


informatica:programacion:php:frameworks:laravel:formularios

Trabajando con formularios en Laravel

Crear formulario

Si queremos crear un formulario que nos permita añadir un producto, vamos al controlador y nos centramos en el método create:

public function create() 
{
    return view("products.create");
}

Crearemos una vista resources/views/products/create.blade.php:

@extends("layout.master")
 
@section("content")
    <h1>Create a product</h1>
 
    <form method="post" action="{{ route("products.store" }}">
        <div class="form-row">
            <label>Title</label>
            <input class="form-control" type="text" name="title" required>
        </div>
        <div class="form-row">
            <label>Description</label>
            <input class="form-control" type="text" name="description" required>
        </div>
        <div class="form-row">
            <label>Price</label>
            <input class="form-control" type="number" min="1.00" step="0.01" name="price" required>
        </div>                
        <div class="form-row">
            <label>Stock</label>
            <input class="form-control" type="number" min="0" name="stock" required>
        </div>                  
        <div class="form-row">
            <label>Status</label>      
            <select class="custom-select" name="status" required>
                <option value="" selected>Select...</option>
                <option value="available">Available</option>                
                <option value="unavailable">Unavailable</option>                                
            </select>
        </div>
        <div class="form-row">
            <button type="submit" class="btn btn-primary btn-lg">Create product</button>
        </div>
    </form>

Recordemos que tenemos estas rutas en routes/web.php para este caso:

Route::get("products/create", "ProductController@create")->name("products.create");
 
Route::post("products", "ProductController@store")->name("products.store");

Por tanto, cuando se envíe el formulario, se llamará al método store del ProductController mediante POST:

public function store() 
{
    dd("Estamos en store");
}

Esto no nos funcionará porque, por defecto, Laravel tiene protección contra CSRF (Cross-site request forgery). Se asegura que las peticiones que se hagan a nuestra web, vengan realmente de nuestra web.

Para solucionarlo, en nuestros formularios debemos añadir un token CSRF:

@extends("layout.master")
 
@section("content")
    <h1>Create a product</h1>
 
    <form method="post" action="{{ route("products.store" }}">
    @csrf
 

Esa instrucción de Blade incluye un campo HTML oculto en el formulario:

<form method="post" action="">
    <input type="hidden" name="_token" value="123h4jkl123khxvbnasd12"

Datos provenientes de formularios

Vamos a crear (almacenar) un producto a partir de la información recibida desde un formulario:

public function store() 
{
    $product = Product::create([
        'title' => request()->title,
        'description' => request()->description,
        'price' => request()->price,
        'stock' => request()->stock,
        'status' => request()->status,
    ]);
 
    return $product;
}

Veremos un string JSON con el producto creado a través del formulario.

Versión abreviada cogiendo todo lo que llegue de un formulario:

public function store() 
{
    $product = Product::create(request()->all());
 
    return $product;
}

Los atributos que se asignarán a nuestro modelo a partir del formulario serán los que hayamos indicado en el array de $fillable.

Editando desde un formulario

Los métodos que modificaremos en nuestro ProductController serán edit y update. Uno mostrará el formulario de edición del producto y el otro hará efectiva la actualización.

public function edit($product) 
{
    return view("products.edit")->with([
        "product" => Product::findOrFail($product),
    ]);
}
 
public function update($product) 
{
}

Recordemos las rutas:

Route::get("products/{$product}/edit", "ProductController@edit")->name("products.edit");
 
Route::match(["put", "patch"], "products/{$product}", "ProductController@update")->name("products.update");

Para el formulario de edición, creamos la vista resources/views/products/edit.blade.php:

@extends("layout.master")
 
@section("content")
    <h1>Edit a product</h1>
 
    <form method="post" action="{{ route("products.update", ["product" => $product->id]) }}">
        @csrf
        @method("PUT")
        <div class="form-row">
            <label>Title</label>
            <input class="form-control" type="text" name="title" value="{{ $product->title }}" required>
        </div>
        <div class="form-row">
            <label>Description</label>
            <input class="form-control" type="text" name="description" value="{{ $product->description }} required>
        </div>
        <div class="form-row">
            <label>Price</label>
            <input class="form-control" type="number" min="1.00" step="0.01" name="price" value="{{ $product->price }} required>
        </div>                
        <div class="form-row">
            <label>Stock</label>
            <input class="form-control" type="number" min="0" name="stock" value="{{ $product->stock }} required>
        </div>                  
        <div class="form-row">
            <label>Status</label>      
            <select class="custom-select" name="status" required>
                <option {{ $product->status == "available" ? "selected" : "" }} value="available">Available</option>                
                <option {{ $product->status == "unavailable" ? "selected" : "" }} value="unavailable">Unavailable</option>                                
            </select>
        </div>
        <div class="form-row">
            <button type="submit" class="btn btn-primary btn-lg">Edit product</button>
        </div>
    </form>

Los navegadores solo procesan GET y POST, así que para forzar un tipo de petición, usamos @method que añadirá una etiqueta input oculta con el valor que le pasemos.

Para realizar la actualización del producto, en el controlador:

public function update($product) 
{
    $product = Product::findOrFail($product);
 
    $product->update(request()->all());
 
    return $product;
}

Eliminar de la base de datos

En Laravel tenemos que usar un formulario también para eliminar productos. En nuestro controlador, modificaremos el método destroy:

public function destroy($product) 
{
    $product = Product::findOrFail($product);
 
    $product->delete();
}

Recordemos que debe existir una ruta:

Route::delete("products/{product}", "ProductController@destroy")->name("products.destroy");

Finalmente, para dar la opción de eliminar un producto, basta con crear un enlace, pero debe ser usando el método DELETE:

<form method="post" action="{{ route("products.destroy", ["product" => product->id]) }}">
    @csrf
    @method("DELETE")
    <button type="submit" class="btn btn-link">Delete</button>
</form>
informatica/programacion/php/frameworks/laravel/formularios.txt · Última modificación: por tempwin