Herramientas de usuario

Herramientas del sitio


informatica:programacion:php:frameworks:laravel:formularios

¡Esta es una revisión vieja del documento!


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"

Enviando y mostrando información en vistas

Sabemos cómo crear una vista, cómo mostrar información en esa vista, pero ahora queremos añadir en la vista información que recuperamos de la base de datos a través de un controlador.

Partimos de un método de nuestro ProductController:

    // code
    public function show($product) 
    {
        $product = Product::findOrFail($product);
 
        return view("products.show");
 
    }

Para enviar información a la vista usamos with y definimos qué nos llevaremos a la vista.

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

A la vista estaremos enviando la variable product con el valor $product.

Si vamos a la vista (resources/views/products/show.blade.php:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <title>Product</title>
  </head>
 
  <body>
    <h1>{{ $product->title }} ({{ $product->id }})</h1>
    <p>{{ $product->description }}</p>
    <p>{{ $product->price }}</p>
    <p>{{ $product->stock }}</p>
    <p>{{ $product->status }}</p>            
  </body>
</html>

Usando Blade, el motor de plantillas que incluye Laravel, interpretará las variables. Las encerramos entre llaves dobles ({{ }}).

Blade: motor de plantillas

Blade es el motor de plantillas que incluye Laravel

Variables

Para mostrar el contenido de una variable en Blade:

{{ $variable }}

Comentar para que no las procese ni las muestre:

{{-- $variable --}}

Si queremos que aparezca el texto tal cual (llaves incluidas), es decir, que Blade no evalúe nada:

@{{ $variable }}

Esto es útil si estamos trabajando con un framework para el frontend como Vuejs, React o Angular ya que también utilizan la sintaxis de las dobles llaves para las variables.

Estructuras de control

Por ejemplo, si tenemos en nuestro controlador:

    public function index()
    {
        $products = Product::all();
 
        return view("products.index")->with([
            "products" => $products,
        ]);
    }

En la vista (resources/views/products.blade.php):

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <title>Product</title>
  </head>
 
  <body>
    <h1>List of Products</h1>
 
    @if (empty($products))
        <div class="alert alert-warning">
            This list of products is empty
        </div>
    @else
        <div class="table-responsive">
            <table class="table table-striped">
                <thead class="thead-light">
                    <tr>
                        <th>ID</th>
                        <th>Title</th>
                        <th>Description</th>
                        <th>Price</th>
                        <th>Stock</th>
                        <th>Status</th>
                    </tr>
                </thead>
                <tbody>
                    @foreach ($products as $product)
                    <tr>
                        <td>{{ $product->id }}</td>
                        <td>{{ $product->title }}</td>
                        <td>{{ $product->description }}</td>
                        <td>{{ $product->price }}</td>
                        <td>{{ $product->stock }}</td>
                        <td>{{ $product->status }}</td>                        
                    </tr>      
                    @endforeach                  
                </tbody>
            </table>
        </div>
    @endif
  </body>
</html>

Para el caso de comprobar vacíos, existe otra estructura dedicada::

    <h1>List of Products</h1>
 
    @empty ($products)
        <div class="alert alert-warning">
            This list of products is empty
        </div>
    @else
    ...
    @endempty

Crear plantillas para las vistas

Para cuando tengamos componentes que se repitan.

Creamos, por ejemplo, reseources/views/layouts/master.blade.php:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <title>Laravel Shop</title>
  </head>
 
  <body>
    @yield('content')
  </body>
</html>

Con yield() marcamos una sección a la que podremos hacer luego referencia.

Las vistas que quieran utilizar esta plantilla tendrían que…

@extends("layouts.master")
 
@section("content")
 
    <h1>List of Products</h1>
 
    @if (empty($products))
        <div class="alert alert-warning">
            This list of products is empty
        </div>
    @else
        <div class="table-responsive">
            <table class="table table-striped">
                <thead class="thead-light">
                    <tr>
                        <th>ID</th>
                        <th>Title</th>
                        <th>Description</th>
                        <th>Price</th>
                        <th>Stock</th>
                        <th>Status</th>
                    </tr>
                </thead>
                <tbody>
                    @foreach ($products as $product)
                    <tr>
                        <td>{{ $product->id }}</td>
                        <td>{{ $product->title }}</td>
                        <td>{{ $product->description }}</td>
                        <td>{{ $product->price }}</td>
                        <td>{{ $product->stock }}</td>
                        <td>{{ $product->status }}</td>                        
                    </tr>      
                    @endforeach                  
                </tbody>
            </table>
        </div>
    @endif
 
@endsection
informatica/programacion/php/frameworks/laravel/formularios.1686400642.txt.gz · Última modificación: por tempwin