06. Ver y editar eventos en el calendario - Piptonita/crear-calendario-FullCalendar GitHub Wiki

Ahora vamos a ver como abrir el modal cuando se haga clic en un evento y que se pueda editar.

  • Vamos a añadir un nuevo botón al modal en index.html llamado editar:
<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Calendario a Full</title>
    <link rel="stylesheet" href="vendor/fullcalendar/main.css">
    <link rel="stylesheet" href="src/css/calendar.css">
</head>
<body>
    <div id="calendar"></div>

    <div id="modal">
        <div class="containerModal column">
            <!-- añadimos un id al título: -->
            <h2 id="tituloEntrada">Añadir evento</h2>
            <hr>
            <input type="text" id="titulo" placeholder="Título del evento">
            <div class="row">
                <input type="text" id="fechaInicio">
                <input type="text" id="horaInicio" placeholder="Hora de inicio (opcional)">
            </div>
            <div class="row">
                <input type="text" id="fechaFin" placeholder="Fecha de finalización (opcional)">
                <input type="text" id="horaFin" placeholder="Hora de finalización (opcional)">
            </div>
            <textarea id="descripcion" placeholder="Descripción del evento"></textarea>
            <div class="row">
                <label for="color">Color de la tarjeta:</label>
                <input type="color" id="color" name="color" value="#00C217">
                <label for="textColor">Color del texto:</label>
                <input type="color" id="textColor" name="textColor" value="#0018CC">
            </div>
            <div class="row">
                <!-- añadimos el botón editar aquí: -->
                <button id="editar">Editar</button>
                <button id="crear">Guardar</button>
                <button id="cancelar">Cancelar</button>
            </div>
        </div>
    </div>
    
    <script src="vendor/fullcalendar/main.js"></script>
    <script src="vendor/fullcalendar/locales/es.js"></script>
    <script src="src/js/calendar.js"></script>
</body>
</html>
  • Ahora vamos a editar el archivo calendar.js para añadir la propiedad eventClick que detectará la pulsación de un evento en el calendario y muestre todos sus detalles:
var calendarDiv = document.getElementById('calendar');


var calendar = new FullCalendar.Calendar(calendarDiv, {
    locales: 'es', 
    initialView: 'dayGridMonth', 
    headerToolbar: { 
        left: 'prev', 
        center: 'title', 
        right: 'next',

    },
    footerToolbar: {
        left: 'prevYear',    
        center: 'dayGridMonth,timeGridWeek,timeGridDay,listMonth,today',
        right: 'nextYear'
    }, 
    buttonText: {
        today: 'Hoy',
        month: 'Mes',
        week: 'Semana',
        day: 'Día',
        list: 'Listado'
    }, 
    events: [
        {
            title: 'Evento de prueba 1',
            description: 'Esta es una descripción de prueba', 
            start: '2020-09-20 12:00:00', 
            end: '2020-09-25 12:00:00', 
            color: 'yellow', 
            textColor: 'red', 
        },
        {
            title: 'Evento de prueba 2',
            descripcion: 'Este es otro evento de un solo día',
            start: '2020-09-26',
            color: 'red',
            textColor: 'yellow'
        },
        {
            title: 'Evento de prueba 3',
            description: 'Este evento dura un tiempo determinado',
            start: '2020-09-27 08:00:00', 
            end: '2020-09-27 10:00:00', 
            color: 'blue',
            textColor: 'green'
        }
        
    ], 
    dateClick: (info) => {
        // añadimos el parametro editar para que se active el botón editar: 
        abrirModal('crear');

        var fecha = document.getElementById('fechaInicio');
        fecha.value = info.dateStr; 
        
    },
    eventClick: (info) => { // eventClick funciona exactamente igual que dateClick, solo que se dispara al presionar un evento.
        // cambiamos el título de Añadir entrada por el del evento actual:
        document.getElementById('tituloEntrada').innerHTML = info.event.title;
        // recuperamos todos los campos y les asignamos los datos del evento:
        document.getElementById('titulo').value = info.event.title;
        // llamamos a una función para cortar la fecha y hora y le pasamos la fecha:
        fechaInicio = cortarFecha(info.event.startStr);
        
        document.getElementById('fechaInicio').value = fechaInicio[0];
        // comprobamos que el array devuelto es mayor de 1, si lo es significa que existe la hora:
        if(fechaInicio.length > 1){
            document.getElementById('horaInicio').value = fechaInicio[1];
        }
        // hacemos lo mismo para la fecha fin: 
        fechaFin = cortarFecha(info.event.endStr);
        document.getElementById('fechaFin').value = fechaFin[0];
        if(fechaFin.length > 1){
            document.getElementById('horaFin').value = fechaFin[1];
        }
        // la descripción hay que recuperarla de extendedProps, validamos si existe primero:
        if(info.event.extendedProps.description){
            document.getElementById('descripcion').value = info.event.extendedProps.description;
        }
        // en color tenemos que seleccionar la propiedad backgroundColor de info:
        document.getElementById('color').value = info.event.backgroundColor;
        document.getElementById('textColor').value = info.event.textColor;
        // vamos a abrir el modal pero con permisos de edicion:
        abrirModal('editar');
    },
    editable: true, // esta propiedad tenemos que añadirla para permitir editar eventos.
});

botonCrear = document.getElementById('crear');
botonCrear.addEventListener('click', ()=> {
    recuperarCampos();
    calendar.addEvent(recuperarCampos());
    cerrarModal();
    vaciarCampos();

});

var modal = document.getElementById('modal');

// le pasamos los permisos:
function abrirModal(permisos){
    // con los permisos determinamos que botones se verán según si añadimos evento o editamos:
    if(permisos == 'crear'){
        document.getElementById('editar').style.cssText = "display: none";
        document.getElementById('crear').style.cssText = "display: block";
    }else{
        document.getElementById('editar').style.cssText = "display: block";
        document.getElementById('crear').style.cssText = "display: none";
    }
    modal.style.cssText = "display: flex;";
    window.setTimeout(()=>{
        modal.style.cssText += "opacity: 1; transition: 0.5s";
    }, 10);
}

function recuperarCampos(){
    var nuevoEvento = [];
    nuevoEvento.title = document.getElementById('titulo').value;
    if(document.getElementById('horaInicio').value != ''){
        nuevoEvento.start = document.getElementById('fechaInicio').value + " " + document.getElementById('horaInicio').value;
    }else{
        nuevoEvento.start = document.getElementById('fechaInicio').value;
    }
    nuevoEvento.end = document.getElementById('fechaFin').value + " " + document.getElementById('horaFin').value;
    nuevoEvento.description = document.getElementById('descripcion').value;
    nuevoEvento.color = document.getElementById('color').value;
    nuevoEvento.textColor = document.getElementById('textColor').value;
    return nuevoEvento;
}

var botonCerrar = document.getElementById('cancelar');
botonCerrar.addEventListener('click', ()=>{
    cerrarModal();
    // añadimos aquí vaciarCampos ya que sino al ver un evento y añadir otro se verá:
    vaciarCampos();
});

function cerrarModal(){
    modal.style.cssText += 'opacity: 0; transition: 0.5s';
    window.setTimeout(()=>{
        modal.style.cssText = 'display: none';
    }, 500);
}

function vaciarCampos(){
    document.getElementById('titulo').value = '';
    document.getElementById('horaInicio').value = '';
    document.getElementById('fechaFin').value = '';
    document.getElementById('horaFin').value = '';
    document.getElementById('descripcion').value = '';
    document.getElementById('color').value = '#00C217';
    document.getElementById('textColor').value = '#0018CC';
}

// creamos el metodo que nos ayudara a arreglar la fecha y hora:
function cortarFecha(fecha){
    // cortamos a partir de la T que separa la fecha de la hora:
    fecha = fecha.split("T");
    // si existía hora le vamos a quitar la zona horaria para que no se muestre:
    if(fecha[1]){
        fecha[1] = fecha[1].substr(0,8);
    }
    // retornamos la fecha:
    return fecha;
}

calendar.render();

Con esto ya podemos ver los eventos y todos sus campos excepto los de color que salen en negro debido a que no los establecimos con notación hexadecimal. Pero si creamos un nuevo evento y lo abrimos se mostrarán correctamente.

  • Ahora vamos a volver a editar el archivo calendar.js para habilitar el botón de editar:
var calendarDiv = document.getElementById('calendar');


var calendar = new FullCalendar.Calendar(calendarDiv, {
    locales: 'es', 
    initialView: 'dayGridMonth', 
    headerToolbar: { 
        left: 'prev', 
        center: 'title', 
        right: 'next',

    },
    footerToolbar: {
        left: 'prevYear',    
        center: 'dayGridMonth,timeGridWeek,timeGridDay,listMonth,today',
        right: 'nextYear'
    }, 
    buttonText: {
        today: 'Hoy',
        month: 'Mes',
        week: 'Semana',
        day: 'Día',
        list: 'Listado'
    }, 
    events: [
        {
            title: 'Evento de prueba 1',
            description: 'Esta es una descripción de prueba', 
            start: '2020-09-20 12:00:00', 
            end: '2020-09-25 12:00:00', 
            color: 'yellow', 
            textColor: 'red', 
        },
        {
            title: 'Evento de prueba 2',
            descripcion: 'Este es otro evento de un solo día',
            start: '2020-09-26',
            color: 'red',
            textColor: 'yellow'
        },
        {
            title: 'Evento de prueba 3',
            description: 'Este evento dura un tiempo determinado',
            start: '2020-09-27 08:00:00', 
            end: '2020-09-27 10:00:00', 
            color: 'blue',
            textColor: 'green'
        }        
    ], 
    dateClick: (info) => {
        abrirModal('crear');

        var fecha = document.getElementById('fechaInicio');
        fecha.value = info.dateStr; 
        
    },
    eventClick: (info) => {
        document.getElementById('tituloEntrada').innerHTML = info.event.title;
        document.getElementById('titulo').value = info.event.title;
        fechaInicio = cortarFecha(info.event.startStr);
        document.getElementById('fechaInicio').value = fechaInicio[0];

        if(fechaInicio.length > 1){
            document.getElementById('horaInicio').value = fechaInicio[1];
        }

        fechaFin = cortarFecha(info.event.endStr);
        document.getElementById('fechaFin').value = fechaFin[0];

        if(fechaFin.length > 1){
            document.getElementById('horaFin').value = fechaFin[1];
        }

        if(info.event.extendedProps.description){
            document.getElementById('descripcion').value = info.event.extendedProps.description;
        }
        
        document.getElementById('color').value = info.event.backgroundColor;
        document.getElementById('textColor').value = info.event.textColor;

        abrirModal('editar');
    },
    editable: true, 
});

botonCrear = document.getElementById('crear');
botonCrear.addEventListener('click', ()=> {
    recuperarCampos();
    calendar.addEvent(recuperarCampos());
    cerrarModal();
    vaciarCampos();

});

// capturamos el botón de editar:
botonEditar = document.getElementById('editar');
botonEditar.addEventListener('click', ()=>{
    // cerramos el modal:
    cerrarModal();
    // ahora utilizamos este metodo para actualizar el calendario:
    calendar.refetchEvents();
    // vaciamos los campos:
    vaciarCampos();
});

var modal = document.getElementById('modal');

function abrirModal(permisos){

    if(permisos == 'crear'){
        document.getElementById('editar').style.cssText = "display: none";
        document.getElementById('crear').style.cssText = "display: block";
    }else{
        document.getElementById('editar').style.cssText = "display: block";
        document.getElementById('crear').style.cssText = "display: none";
    }

    modal.style.cssText = "display: flex;";
    window.setTimeout(()=>{
        modal.style.cssText += "opacity: 1; transition: 0.5s";
    }, 10);
}

function recuperarCampos(){
    var nuevoEvento = [];
    nuevoEvento.title = document.getElementById('titulo').value;
    if(document.getElementById('horaInicio').value != ''){
        nuevoEvento.start = document.getElementById('fechaInicio').value + " " + document.getElementById('horaInicio').value;
    }else{
        nuevoEvento.start = document.getElementById('fechaInicio').value;
    }
    nuevoEvento.end = document.getElementById('fechaFin').value + " " + document.getElementById('horaFin').value;
    nuevoEvento.description = document.getElementById('descripcion').value;
    nuevoEvento.color = document.getElementById('color').value;
    nuevoEvento.textColor = document.getElementById('textColor').value;

    return nuevoEvento;
}

var botonCerrar = document.getElementById('cancelar');
botonCerrar.addEventListener('click', ()=>{
    cerrarModal();
    // añadimos aquí vaciarCampos ya que sino al ver un evento y añadir otro se verá:
    vaciarCampos();
});

function cerrarModal(){
    modal.style.cssText += 'opacity: 0; transition: 0.5s';
    window.setTimeout(()=>{
        modal.style.cssText = 'display: none';
    }, 500);
}

function vaciarCampos(){
    document.getElementById('titulo').value = '';
    document.getElementById('horaInicio').value = '';
    document.getElementById('fechaFin').value = '';
    document.getElementById('horaFin').value = '';
    document.getElementById('descripcion').value = '';
    document.getElementById('color').value = '#00C217';
    document.getElementById('textColor').value = '#0018CC';
}

// creamos el metodo que nos ayudara a arreglar la fecha y hora:
function cortarFecha(fecha){
    // cortamos a partir de la T que separa la fecha de la hora:
    fecha = fecha.split("T");
    // si existía hora le vamos a quitar la zona horaria para que no se muestre:
    if(fecha[1]){
        fecha[1] = fecha[1].substr(0,8);
    }
    // retornamos la fecha:
    return fecha;
}

calendar.render();

En terminos técnicos esto debería de funcionar. Pero la propiedad refetchEvents() lo que hace es repasar la lista de eventos y volver a reimprimirlos.

más adelante veremos como otorgar persistencia y entonces se actualizarán los eventos en el calendario.

⚠️ **GitHub.com Fallback** ⚠️