Aprende Java Aprende Php Aprende C++ Aprende HTML 5 Aprende JavaScript Aprende JSON Aprende MySQL Aprende SQLServer Aprende Visual Basic 6 Aprende PostgreSQL Aprende SQLite Aprende Redis Aprende Kotlin Aprende XML Aprende Linux VSC Aprende Wordpress Aprende Laravel Aprende VueJS Aprende JQuery Aprende Bootstrap Aprende Netbeans Aprende Android
Sigueme en Facebook Sigueme en Twitter Sigueme en Instagram Sigueme en Youtube Sigueme en TikTok Sigueme en Whatsapp
Home / Laravel / CRUD con FullCalendar y Laravel 11

CRUD con FullCalendar y Laravel 11

Por jc mouse lunes, agosto 12, 2024

En esta ocasión se crea un proyecto en Laravel 11 para implementar el CRUD (Crear, Leer, Actualizar y Borrar) necesario para trabajar con el plugins javascript de FullCalendar.

¿Que necesitamos?

  • Conocimientos intermedios de Laravel
  • Conocimientos básicos de JavaScript
  • Un proyecto limpio de Laravel 11

Una vez que ya tengas tu proyecto laravel 11 creado y abierto en tu editor de codigo favorito. Pongamos manos a la obra

Paso 1. Migration

Creamos una nueva migración donde se declara la tabla «events», en la misma se registraran todos los eventos del fullcalendar.

<?php

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

return new class extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::create('events', function (Blueprint $table) {
            $table->id();
            $table->string('title');
            $table->date('start');
            $table->date('end');
            $table->timestamps();
        });
    }

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

Se realiza la migración con el comando:

php artisan migrate:refresh

Paso 2. Model

A continuación se crea el modelo «Event»

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Event extends Model
{
    use HasFactory;    

    protected $fillable = [
        'title', 
        'start',
        'end'
    ];

}

Paso 3. Services

Se crea una clase Service con el nombre «FullCalendarService.php», en el mismo se declaran las funciones necesarias para el CRUD.

<?php

namespace App\Services;

use Illuminate\Http\Request;
use App\Models\Event;

class FullCalendarService
{
    public function events(Request $request)
    {
        $data = Event::whereDate('start', '>=', $request->start)
            ->whereDate('end', '<=', $request->end)
            ->get(['id', 'title', 'start', 'end']);
        return response()->json($data);
    }

    public function add(Request $request){
        $event = Event::create([
            'title' => $request->title,
            'start' => $request->start,
            'end' => $request->end,
        ]);
        return response()->json($event);
    }

    public function update(Request $request){
        $event = Event::find($request->id)->update([
            'title' => $request->title,
            'start' => $request->start,
            'end' => $request->end,
        ]);        
        return response()->json($event);
    }

    public function destroy($id){
        $event = Event::find($id)->delete();  
        return response()->json($event);
    }
    
}

Paso 4. Controller

Se requiere una clase controller bajo el nombre de «FullCalendarController.php», en el mismo se inyectara el Service creado en el paso 3 y se declaran las funciones respectivas para el CRUD.

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Services\FullCalendarService;
use Illuminate\Http\JsonResponse;

class FullCalendarController extends Controller
{
    protected $fullCalendarService;

    public function __construct(FullCalendarService $fullCalendarService)
    {
        $this->fullCalendarService = $fullCalendarService;
    }

    public function index()
    {
        return view('fullcalendar.index');
    }

    public function events(Request $request)
    {    
        return $this->fullCalendarService->events($request);    
    }

    public function add(Request $request): JsonResponse
    {        
        return $this->fullCalendarService->add($request);        
    }

    public function update(Request $request): JsonResponse
    {        
        return $this->fullCalendarService->update($request);        
    }

    public function destroy(Request $request)
    {
        return $this->fullCalendarService->destroy($request->id);                    
    }

}

Paso 5. View

Ya finalizando se crea una vista index.blade.php en la ruta «views/fullcalendar/».

<!DOCTYPE html>
<html>
<head>
    <title>CRUD Fullcalendar - Laravel 11 (https://www.jc-mouse.net/)</title>
    <meta name="csrf-token" content="{{ csrf_token() }}">
    <link href='https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css' rel='stylesheet'>
    <link href='https://cdn.jsdelivr.net/npm/bootstrap-icons@1.8.1/font/bootstrap-icons.css' rel='stylesheet'>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/fullcalendar@6.1.15/index.global.min.js"></script>
    <script src='https://cdn.jsdelivr.net/npm/@fullcalendar/core@6.1.15/locales-all.global.min.js'></script>
</head>
<body>
    <div class="container">
        <div class="card">
            <div class="card-body">
                <div id='calendar'></div>
            </div>
        </div>
    </div>
    <script type="text/javascript">
        document.addEventListener('DOMContentLoaded', function() {
            var calendarEl = document.getElementById('calendar');
            var calendar = new FullCalendar.Calendar(calendarEl, {
                headerToolbar: {
                    left: 'prevYear,prev,next,nextYear today'
                    , center: 'title'
                    , right: 'dayGridMonth,dayGridWeek,dayGridDay'                    
                }                
                , navLinks: true
                , editable: true
                , displayEventTime: false
                , selectable: true
                , locale: 'es'
                , events: "{{ route('fullcalendar.events') }}",
                /** -------------------------------------------------------------
                 * creacion de eventos
                 */
                dateClick: function(info) {
                    var title = prompt('Nuevo evento:');
                    if (title) {                        
                        var start = moment(info.dateStr).format('Y-MM-DD');
                        var end = moment(info.dateStr).format('Y-MM-DD');

                        $.ajax({
                            url: "{{ route('fullcalendar.events.add') }}"
                            , data: {
                                _token: $('meta[name="csrf-token"]').attr('content')
                                , title: title
                                , start: start
                                , end: end
                            }
                            , type: "POST"
                            , success: function(data) {
                                calendar.addEvent({
                                    id: data.id
                                    , title: title
                                    , start: end
                                    , allDay: false
                                });
                                calendar.render();
                            }
                        });
                    }
                },
                /** -------------------------------------------------------------
                 * Eliminación de eventos
                 */
                eventClick: function(info) {
                    var deleteMsg = confirm("¿Realmente quieres eliminar este evento?");
                    if (deleteMsg) {
                        $.ajax({
                            type: "DELETE"
                            , url: "{{ route('fullcalendar.events.destroy') }}"
                            , data: {
                                _token: $('meta[name="csrf-token"]').attr('content')
                                , id: info.event.id
                            , }
                            , success: function(response) {
                                info.event.remove();
                            }
                        });
                    }
                },
                /** -------------------------------------------------------------
                 * Actualización de eventos
                 */
                eventDrop: function(info) {
                    var start = moment(info.event.start).format('Y-MM-DD');
                    var end = moment(info.event.start).format('Y-MM-DD');
                    $.ajax({
                        url: "{{ route('fullcalendar.events.update') }}"
                        , data: {
                            _token: $('meta[name="csrf-token"]').attr('content')
                            , title: info.event.title
                            , start: start
                            , end: end
                            , id: info.event.id
                        }
                        , type: "PUT"
                        , success: function(response) {
                            console.log(response);                            
                        }
                    });
                },

            });
            calendar.render();
        });
    </script>
</body>

</html>

Paso 6. Routes

Finalmente declaramos rutas necesarias para el CRUD en el archivo routes.php.

<?php

use Illuminate\Support\Facades\Route;
use App\Http\Controllers\FullCalendarController;

Route::controller(FullCalendarController::class)->group(function(){
    Route::get('fullcalendar', 'index');    
    Route::get('events', 'events')->name('fullcalendar.events');
    Route::post('events/add', 'add')->name('fullcalendar.events.add');
    Route::put('events/update', 'update')->name('fullcalendar.events.update');
    Route::delete('events/destroy', 'destroy')->name('fullcalendar.events.destroy');    
});

Y ya solo nos queda abrir el proyecto desde el navegador: http://laravel-fullcalendar.test/fullcalendar y tenemos:

Videito en TikTok 🙂

Enjoy!!!

Tags

Artículos similares

Crear web multi-lenguaje con php

En este tutorial realizaremos un proyecto web de un «sitio multi lenguaje» o «web multi idiomas» como prefieran llamarlo[...]

MVC: Modelo, Vista y Controlador en PHP

EL patrón MVC (Model, View, Controller) o Modelo, Vista Controlador, es un tipo de diseño que separa en capas bien defin[...]

Hola Mundo con Slim Framework

Slim es un micro framework para PHP que nos ayuda a escribir rápidamente aplicaciones Web y APIs sencillas pero poderosa[...]

Conexión a MySQL con PDO

¿Que es PDO? PHP Data Objects (o PDO) es una extensión que provee una capa de abstracción de acceso a datos para PHP 5,[...]

Pruebas Unitarias con PHPUnit

PHPUnit es un framework que se utiliza para escribir tests en PHP, Netbeans nos permite configurarlo y usarlo fácilmente[...]

Manejo de excepciones: Uso de Throw Exception en Laravel 11

El manejo correcto de excepciones permite que nuestras aplicaciones sean robustas, tolerante a fallos y amigable con el[...]