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

Métodos GET y POST en RestFul y JSON

En este post veremos como enviar solicitudes GET y POST a un API RestFul  desde un dispositivo con android. Nuestra apli[...]

Blog MVC – Carga de páginas estáticas [p4]

Cuarta parte de esta pequeña serie de tutoriales sobre [Crea tu blog con el patrón MVC y php] En esta cuarta entrega ver[...]

The Polite Type: La fuente tipográfica políticamente correcta

«Las palabras que elegimos dan forma a nuestra realidad. La Fuente Educada (Polite Type) es una fuente de código abierto[...]

Blog MVC en PHP (Código Fuente)

En este post dejo el código fuente de un blog en PHP desarrollado siguiendo el patrón de diseño MVC (Modelo, Vista y Con[...]

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[...]

10 compiladores online para estudiantes

¿Quieres iniciarte en la programación? ¿Eres un programador impaciente que odia instalar cualquier software en su comput[...]