Laravel 5, parte 6: Vistas y Helpers

Bueno, ahora que ya tenemos el funcionamiento lógico de nuestra aplicación, sólo nos falta agregar la parte visual. Para ello vamos a tener que crear los archivos para ver, modificar o eliminar las tareas.

Helpers

En mi opinión, siempre prefiero evitar este tipo de herramientas, pero visto y considerando que son muy útiles para la mayoría de los desarrolladores, vamos a crear nuestra aplicación con helpers.

Los helpers nos permiten crear contenido html por medio de código propio del framework, una función a la cual podemos pasar parámetros y ésta se encargará de crear el código html correspondiente.

Así que primero vamos a abrir nuestro archivo “composer.js”, y a buscar “require”. En mi caso mi archivo es así:

"require": { "php": ">=5.6.4", "laravel/framework": "5.4.*", "laravel/tinker": "~1.0" }

Dentro de la lista, vamos a agregar un ítem más. En mi caso:

"laravelcollective/html": "5.4.*"

Entonces me quedará de este modo:

"require": {
   "php": ">=5.6.4",
   "laravel/framework": "5.4.*",
   "laravel/tinker": "~1.0",
   "laravelcollective/html": "5.4.*"
}

Pero atención, la versión que yo estoy usando de Laravel es la “5.4”, si estás usando otra, deberías poner la que corresponde. Podés fijarte en el valor de “laravel/framework”, o bien escribir en consola:

php artisan --version

Una vez que terminemos de editar este archivo, vamos a la consola y escribimos lo siguiente:

composer update

Y empezarán a descargarse las dependiencias.

Una vez que termine la descarga desde la consola, editar el archivo “config/app.php”, y buscamos dentro de “providers”, y dentro de la lista agregamos:

Collective\Html\HtmlServiceProvider::class,

Y en el mismo archivo, dentro de “aliases”:

'Form' => 'Collective\Html\FormFacade',
'Html' => 'Collective\Html\HtmlFacade',

 

Vistas

Bueno, ahora vamos a crear las vistas. Tendremos tres vistas, una para mostrar las tareas, otra para visualizar una en particular y otra para guardarlas (crear o modificar)

Así que dentro de resources/views vamos a crear un directorio llamado tareas, y dentro los tres archivos:

  • index.blade.php
  • show.blade.php
  • save.blade.php

(No te olvides de ‘.blade’ antes de ‘.php’)

Antes de editar el código, vamos a detenernos algo. A la hora de crear interfaces visuales, casi siempre hay código html que se repite entre página y página. Por ejemplo cabeceras, pies de página, archivos externos (css, js, imágenes). Laravel nos permite crear una plantilla base, y luego poder reutilizar dicho diseño, incluyendo solamente en cada una el código que cambia entre página y página.

Si nos fijamos bien dentro de resources/views/layouts/app.blade.php, vamos a ver código html. Aquí podemos modificar si por ejemplo necesitamos agregar un css, un js, o simpemente cambiar el diseño de nuestro sitio.

Por ejemplo, podemos encontrar los enlaces del menú que cambian dependiente de si el usuario está logueado o no:

@if (Auth::guest())

Esta línea indica que el usuario no está logueado, así que va a visualizar en este caso los enlaces para iniciar sesión o bien registrarse.

Vamos a aprovechas para agregar el siguiente enlace para acceder con un link a las tareas, siempre y cuando el usuario esté logueado:

<li>
   <a href="/tareas">
      Tareas
   </a>
</li>

Bueno, a continuación vamos a editar los archivos visuales. Dentro de save.blade.php copiamos el siguiente código:

@extends('layouts.app')
@section('content')
 <div class="container">
    <h1> Guardar tarea </h1>
    {!! Form::open(array('url' => 'tareas/' . $tarea->id, 'method' => $method)) !!}
       <div class="form-group">
          {!! Form::label('titulo', 'Título') !!}
          {!! Form::text('titulo', $tarea->titulo, ['class' => 'form-control']) !!}
       </div>
       <div class="form-group">
          {!! Form::label('descripcion', 'Descripción') !!}
          {!! Form::textarea('descripcion', $tarea->descripcion, ['class'=>'form-control', 'rows' => 2, 'cols' => 40]) !!}
       </div>
       <div class="form-group">
          {!! Form::label('estado', 'Estado') !!}
          <select name="estado_id" id="estado_id" class="form-control"> 
             <option value=""> --- </option>
             @foreach ($estados as $item)
                @if($tarea->id != null && $item->id == $tarea->estado->id)
                   <option selected="selected" value="{{ $item->id }}"> {{ $item->nombre }} </option>
                @else
                   <option value="{{ $item->id }}"> {{ $item->nombre }} </option>
                @endif
             @endforeach
          </select>
       </div>
       {!! Form::submit('Guardar', ['class' => 'btn btn-primary']) !!} 
       {!! link_to('tareas', 'Cancelar', ['class' => 'btn btn-danger']) !!}
    {!! Form::close() !!}
 </div>
@endsection

Bueno, sé que es mucho código, pero vamos a ir viéndolo de a poco.

En primer lugar extendemos de otra vista, la cual tiene una suerte de plantilla para el resto de nuestras interfaces gráficas:

@extends('layouts.app')

Esto dibujará la cabecera y el pie sin necesidad de repetirlo en cada vista.

Comenzando con los helper, primero usamos:

{!! Form::open(array('url' => 'tareas/' . $tarea->id, 'method' => $method)) !!}

Este es un helper para abrir un formulario. La url es ‘tareas’ + barra (/) + id, en caso de que haya un id. Osea este formulario nos va a servir cuando tengamos una tarea nueva o una que vamos a editar. Por eso en la publicación pasado escribimos :

$tarea = new Tarea();

Para una tarea que aún no se ha creado

$tarea = Tarea::find($id);

Con una tarea que ya existe, y que recuperamos por id.

Otra cosa que hay que aclarar es que:

'method' => $method

Será una variable que le pasamos el método. Cuando sea el método create(), le vamos a pasar ‘POST’, que es para crear un nuevo registro; cuando sea el edit(), entonces será ‘PUT’, para modificar.

Y cerramos con:

{!! Form::close() !!}

El resto de los helpers son simplemente elementos de formulario, por ejemplo:

{!! Form::label(‘titulo’, ‘Título’) !!}
{!! Form::text(‘titulo’, $tarea->titulo, [‘class’ => ‘form-control’]) !!}

En el caso de label(), el primer parámetro es el for, y el segundo el texto de la etiqueta.

Mientras que text() es el name, el value por defecto y el tercer parámetro es un array con datos adicionales como la clase que usamos.

Y un select para mostrar los estados:

<select name="estado_id" id="estado_id" class="form-control"> 
   <option value=""> --- </option>
   @foreach ($estados as $item)
      @if($tarea->id != null && $item->id == $tarea->estado->id)
         <option selected="selected" value="{{ $item->id }}"> {{ $item->nombre }} </option>
      @else
         <option value="{{ $item->id }}"> {{ $item->nombre }} </option>
      @endif
   @endforeach
</select>

Verificamos si la tarea ya existe con:

$tarea->id != null

Y luego si coincide con el estado que estamos recorriendo, para ponerla en selected o no:

$item->id == $tarea->estado->id

Finalmente vamos a modificar los métodos create() y edit() que creamos la última vez, permitiendo que se cargue esta vista.

public function create()
{
   $tarea = new Tarea();
   $estados = Estado::all();
   return View('tareas.save')
      ->with('tarea', $tarea)
      ->with('estados', $estados)
      ->with('method', 'POST');
}
public function edit($id)
{
   $tarea = Tarea::where(array(
      'id' => $id,
      'user_id' => Auth::id()
   ))->first();
   $estados = Estado::all();
   return View('tareas.save')
      ->with('tarea', $tarea)
      ->with('estados', $estados)
      ->with('method', 'PUT');
}

Como podemos observar le pasamos por parámetro un dato llamado ‘method’, el cual va a cambiar dependiendo de si lo enviamos por ‘POST’ o  ‘PUT’.

Luego vamos a editar el archivo index.blade.php con el siguiente código:

@extends('layouts.app')
 @section('content')
 <div class="container">
    @if(Session::has('notice'))
       <div class="alert alert-success">
          {{ Session::get('notice') }}
       </div>
    @endif
    <h1> Lista de tareas </h1>
    <div class="row">
       <div class="col-lg-12">
          {!! link_to('tareas/create', 'Crear', ['class' => 'btn btn-primary']) !!}
       </div>
    </div>
    <table class="table">
       <thead>
       <tr>
             <th style="width: 35%"> Título </th>
             <th style="width: 35%"> Estado </th>
             <th style="width: 10%"> </th>
             <th style="width: 10%"> </th>
             <th style="width: 10%"> </th>
          </tr>
       </thead>
       <tbody>
          @foreach ($tareas as $tarea)
             <tr>
                <td> {{ $tarea->titulo }} </td>
                <td> {{ $tarea->estado->nombre }} </td>
                <td>
                   {!! link_to('tareas/'.$tarea->id, 'Ver', ['class' => 'btn btn-primary']) !!}
                </td>
                <td>
                   {!! link_to('tareas/'.$tarea->id.'/edit', 'Editar', ['class' => 'btn btn-primary']) !!}
                </td>
                <td>
                   {!! Form::open(array('url' => 'tareas/' . $tarea->id, 'method' => 'DELETE')) !!}
                      {!! Form::submit('Eliminar', ['class' => 'btn btn-danger']) !!}
                   {!! Form::close() !!}
                </td>
             </tr>
          @endforeach
       </tbody>
    </table>
 </div>
 @endsection

Usamos el helper link_to para crear un enlace al formulario de creación de tareas:

{!! link_to('tareas/create', 'Crear', ['class' => 'btn btn-primary']) !!}

Recorremos las tareas creadas actualmente por el usuario, podremos verlas:

{!! link_to('tareas/'.$tarea->id, 'Ver', ['class' => 'btn btn-primary']) !!}

Editarlas:

{!! link_to('tareas/'.$tarea->id.'/edit', 'Editar', ['class' => 'btn btn-primary']) !!}

O bien, eliminarlas:

{!! Form::open(array('url' => 'tareas/' . $tarea->id, 'method' => 'DELETE')) !!}
   {!! Form::submit('Eliminar', ['class' => 'btn btn-danger']) !!}
{!! Form::close() !!}

Es importante observar que en este último, debemos crear un formulario para hacer un envío con el método ‘DELETE’, al igual que lo hacíamos en el formulario para guardar con ‘POST’ o ‘PUT’.

Y debemos modificar el método index también con el siguiente código:

public function index()
{
   $tareas = User::find(Auth::id())->tareas;
   return View('tareas.index')->with('tareas', $tareas);
}

Por último y para termina vamos a reemplazar show.blade.php con el siguiente código:

@extends('layouts.app')
@section('content')
 <div class="container">
    <h1> {{ $tarea->titulo }} ({{ $tarea->estado->nombre }}) </h1>
    <div class="row">
       <div class="col-lg-12">
          {{ $tarea->descripcion }}
       </div>
       <hr />
       <div class="col-lg-12">
          {!! link_to('tareas', 'Volver', ['class' => 'btn btn-danger']) !!}
       </div>
    </div>
 </div>
@endsection

Solamente para ver la tarea con su descripción.

Y reemplazamos el método por lo siguiente:

public function show($id)
{
   $tarea = Tarea::where(array(
      'id' => $id,
      'user_id' => Auth::id()
   ))->first();
   return View('tareas.show')
      ->with('tarea', $tarea);
}

Anterior: Laravel 5, parte 5: Controladores y Rutas

Siguiente: Laravel 5, parte 7: Validaciones

 

Descargar ejemplo completo

 

Redes sociables

    Deja un comentario

    Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

    *