Create a TODOs app

Table des matières

1. Create the migration class

php artisan make:migration create_todos_table

2. Update the migration class

Edit /database/migrations/2018_08_01_000000_create_todos_table.php and add our fields.

The list of column’s type can be retrieved here

<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateTodosTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('todos', function (Blueprint $table) {
            $table->increments('id');
            $table->timestamps();
            $table->string('title', 100);
            $table->boolean('completed')->default(0);
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('todos');
    }
}

3. Execute and create the table

php artisan migrate

4. Create a model

php artisan make:model Todo

5. Add code to the model

Edit /app/Todo.php.

We don’t need to specify our table’s fields

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Todo extends Model
{
  protected $table = 'todos';

  // Only if $table->timestamps() was mentioned in the
  // CreateTodosTable class; set to False if not mentioned
  public $timestamps = true;
}

6. Create validation rules

php artisan make:request TodoRequest

7. Add rules

Edit /app/Http/Requests/TodoRequest.php and add somes rules:

<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class TodoRequest extends FormRequest
{
  /**
   * Determine if the user is authorized to make this request.
   *
   * @return bool
   */
  public function authorize()
  {
    return true;  // allow anyone to submit Todos
  }

  /**
   * Get the validation rules that apply to the request.
   *
   * @return array
   */
  public function rules()
  {
    return [
      'title' => 'required|string|max:100',
      'completed' => 'boolean'
      ];
  }
}

8. Add routes

Edit /routes/web.php, add a GET and a POST route and, for the exercise, give a name to the POST one.

Add also a route for showing all todos.

Route::get('form', 'TodoController@getForm');
Route::post('todo', [
  'uses' => 'TodoController@postForm',
  'as' => 'storeTodo'
]);

Route::get('todos', [
  'uses' => 'TodoController@index',
  'as' => 'showTodos'
]);

9. Create a controller

php artisan make:controller TodoController

10. Add code to the controller

Edit /app/Http/Controllers/TodoController.php and add this code:

<?php

namespace App\Http\Controllers;

use App\Todo;
use App\Http\Requests\TodoRequest;

class TodoController extends Controller
{
  public function index()
  {
    return Todo::all(); // Return JSON output
  }

  public function getForm()
  {
    return view('todo'); // Show the form
  }

  public function postForm(TodoRequest $request)
  {
    $todo = new Todo();

    $todo->title = $request->input('title');
    $todo->completed = $request->input('completed');

    $todo->save(); // Save the submitted data

    return view('todo_ok'); // And show a "successful" page
  }
}

11. Create the view

Manually create the file /resources/views/form.blade.php (there is no artisan command for this)

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>Some stupid Todos application</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
    <h1>Some stupid Todos application</h1>

    <div class="col-sm-offset-4 col-sm-4">
    <div class="panel panel-info">
      <div class="panel-heading">Todos</div>
      <div class="panel-body">
        {!! Form::open(['route' => 'storeTodo']) !!}
          <div class="form-group {!! $errors->has('todo') ? 'has-error' : '' !!}">
            {!! Form::text('title', null, array('size' => '100', 'class' => 'form-control', 'placeholder' => 'Enter Todo\'s title')) !!}
            {!! $errors->first('title', '<div class="alert alert-danger">:message</div>') !!}
          </div>
          <div class="form-group ">
            {!! Form::checkbox('completed', 1, 0)  !!}
            {!! Form::label('completed', 'Completed'); !!}
          </div>
          {!! Form::submit('Submit !') !!}
        {!! Form::close() !!}
      </div>
    </div>
  </div>
</body>
</html>

12. Test the view

The route, the controller and the view are now in place, we can therefore access to http://127.0.0.1:8000/todo and check if our form is well displayed.

Showing the Todo form

13. Create a successful view

Create /resources/views/todo_ok.blade.php

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>Some stupid Todos application</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
    <h1>Some stupid Todos application</h1>
    <div class="panel-body">
        Successfully stored in the database
    </div>
</body>
</html>

14. Use the form

Go to http://127.0.0.1:8000/todo and add a few items. If everything goes fine, each of them will be now immediately stored in your database.

You can open it with, f.i. phpMyAdmin to check how they’re saved.

But remember: we’ve created a route called /todos so open http://127.0.0.1:8000/todos and you should see this:

Show index

That output is made by the controller, function index():

public function index()
{
  return Todo::all(); // Return JSON output
}

(The JSON formatting as displayed on the screen capture has been automatically made thanks the JSON Formatter Chrome extension)