# CustomSchedule

<style>
    img {
        max-width: 100%;
    }
    pre {
        background-color: #F5F5F5;
        padding: .5rem;
    }
    table {
        min-width: 100%;
        width: auto;
        margin-bottom: 1rem;
        font-size: 1rem;
        border-collapse: collapse;
        border-spacing: 1px;
    }
    tr th {
        padding: 4px 8px;
        outline: 1px solid #DDD;
        font-size: .9rem;
        font-weight: 500;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
        -o-text-overflow: ellipsis;
    }
    tr td {
        padding: 4px;
        outline: 1px solid #EDEDED;
        font-size: .8rem;
        height: 1.4rem;
    }

    @media (max-width: 575px)
    {
        thead {
            display: none;
        }
        tr {
            display: block;
            margin-bottom: 10px;
        }
        td {
            display: block;
            text-align: left;
            position: relative;
            padding-left: 50%;
        }
        td:nth-child(1) {
            font-weight: 500;
        }
        /*td::before {
            content: attr(textContent);
            position: absolute;
            left: 0;
            width: 50%;
            padding-left: 10px;
            font-weight: bold;
            text-align: left;
        }*/
    }
</style>

## Definición

Archivo: `induxsoft.controls.schedule.js`

Produce una interfaz de tabla el cual representa una agenda visual tipo calendario.

<img src="/es/api/web-components/img/schedule-demo-01.png">



## Ejemplos

Maquetación HTML con todos los atributos que pueden establecerse.

```html
<custom-schedule
    id="agenda"
    view="week"
    day="2025-06-14"
    breaks="14:00-14:30"
    weekend="sunday"
    holidays=""
    start-weekday="monday"
    start-lab-hour="9"
    end-lab-hour="18"
    interval="30"
    increment="15"
    min-duration="15"
    max-duration="60"
    events='[]'>
</custom-schedule>
```

El atributo `events` permite establecer las tareas/eventos mediante una cadena que representa un objeto JSON tal como en el siguiente ejemplo:

```html
<custom-schedule
    id="agenda"
    ...
    events='[
        {
            "id": "E01",
            "start": "2025-06-14 12:00",
            "duration": 15,
            "caption": "Ir por unas papitas",
            "backcolor": "#FFFFE1",
            "color": "#000000",
            "data": {}
        },
        ...
    ]'>
</custom-schedule>
```

Las propiedades que pueden establecerse para cada objeto que representa a los eventos se listan a continuación:

- `string` *id -* Identificador del evento. **Requerido**
- `string` *start -* Fecha y hora de inicio. **Requerido**
- `integer` *duration -* Duración en minutos del evento. **Requerido**
- `string` *caption -* Texto a mostrar en el contenedor del evento. **Requerido**
- `string` *backcolor -* Color de fondo para el contenedor del evento. **Opcional**
- `string` *color -* Color para el texto del contenedor del evento. **Opcional**
- `object` *data -* Array de propósito general. **Opcional**

**Ejemplos de uso con JavaScript**

Agregar un nuevo evento a la agenda.

```js
const schedule = document.getElementById('agenda');

const event = {
    id: "E02",
    start: "2025-06-11 17:00",
    duration: 60,
    caption: "Dolor sint laboris in nisi."
};
schedule.save(event);
```

Actualizar un evento existente.

```js
const schedule = document.getElementById('agenda');

const event = {
    id: "E02",
    start: "2025-06-13 17:00",
    duration: 60,
    caption: "Aute et irure labore mollit est qui duis laborum ad."
};
schedule.save(event);
```

Eliminar un evento existente.

```js
const schedule = document.getElementById('agenda');
schedule.delete('E02');
```

## Comentarios

También puede establecer sus propios estilos css para la agenda, para ello agregue la etiqueta `control-styles` como un nodo hijo del componente y comience a personalizar colores, tamaños, etc. Tal como en el siguiente ejemplo:

```html
<custom-schedule id="agenda" ...>
    <control-styles>
        tr th {
            background-color: cadetblue;
        }
        .event-task.selected {
            box-shadow: 1px 1px 4px cadetblue;
        }
    </control-styles>
</custom-schedule>
```

## Atributos

#### view (opcional)

Establece la interfaz del componente, si no se establece por defecto es *week*. Las opciones disponibles para el atributo son:

- Un dia (day)
- Una semana (week)
- Dos semanas (2week)
- Cuatro semanas (4week)
- Seis semanas (6week)

Tipo: `string`; Predeterminado: `week`

```html
<custom-schedule view="week"></custom-schedule>
```

#### day (opcional)

Cadena de fecha con el formato `yyyy-MM-dd` que establece el dia o semana a mostrar, si no se establece por defecto es *now*.

Tipo: `string`; Predeterminado: `now`

```html
<custom-schedule day="2025-06-04"></custom-schedule>
```

#### breaks (opcional)

Lista de recesos (descansos en el día laboral).

Permite definir rangos de horas bloqueadas para todos los días o para un día específico de la semana.

Sintaxis soportada:

- `HH:mm-HH:mm`
- `[WEEKDAY] HH:mm-HH:mm`

Donde `WEEKDAY` es opcional y puede ser el nombre del día de la semana en inglés o español (sin distinguir mayúsculas/minúsculas).

Los valores deben separarse por coma.

Tipo: `string`; Predeterminado: `""`

Ejemplos:

```html
<!-- Receso para todos los días -->
<custom-schedule breaks="14:00-14:30"></custom-schedule>

<!-- Receso solo los viernes -->
<custom-schedule breaks="viernes 17:00-18:00"></custom-schedule>

<!-- Múltiples recesos -->
<custom-schedule breaks="14:00-14:30, viernes 17:00-18:00, saturday 14:00-18:00"></custom-schedule>
```

#### weekend (opcional)

Establece los dias no laborales separadas por comas, si no se establece por defecto es *saturday,sunday*.

Tipo: `string`; Predeterminado: `saturday,sunday`

```html
<custom-schedule weekend="sunday"></custom-schedule>
```

#### holidays (opcional)

Establece los dias de descanso como una cadena de fechas con el formato `yyyy-MM-dd` separadas por comas.

Tipo: `string`; Predeterminado: `""`

```html
<custom-schedule holidays="2025-01-01,2025-12-25"></custom-schedule>
```

#### start-weekday (opcional)

Indica el dia en que inicia la semana, si no se establece por defecto es *sunday*.

Tipo: `string`; Predeterminado: `sunday`

```html
<custom-schedule start-weekday="monday"></custom-schedule>
```

#### start-lab-hour (opcional)

Establece la hora de inicio laboral, si no se establece por defecto es *0*.

Tipo: `integer`; Predeterminado: `0`

```html
<custom-schedule start-lab-hour="9"></custom-schedule>
```

#### end-lab-hour (opcional)

Establece la hora de finalización laboral, si no se establece por defecto es *24*.

Tipo: `integer`; Predeterminado: `24`

```html
<custom-schedule end-lab-hour="18"></custom-schedule>
```

#### interval (opcional)

Indica los intervalos en minutos de tiempo visual para la agenda en los que el horario laboral es segmentado, si no se establece por defecto es *30*.

Valores aceptados: [15, 30, 60, 120]

Tipo: `integer`; Predeterminado: `30`

```html
<custom-schedule interval="30"></custom-schedule>
```

#### increment (opcional)

Incremento estándar en minutos de un evento, si no se indica o es cero el evento se puede extender libremente entre `min-duration` y `max-duration`. si no se establece por defecto es *0*.

Tipo: `integer`; Predeterminado: `0`

```html
<custom-schedule increment="15"></custom-schedule>
```

#### min-duration (opcional)

Establece la duración minima en minutos para los eventos, si no se establece por defecto es *15*.

Tipo: `integer`; Predeterminado: `15`

```html
<custom-schedule min-duration="15"></custom-schedule>
```

#### max-duration (opcional)

Establece la duración maxima en minutos para los eventos, si no se establece por defecto es *60*.

Tipo: `integer`; Predeterminado: `60`

```html
<custom-schedule max-duration="60"></custom-schedule>
```

#### events (opcional)

Establece los eventos mediante una cadena que representa un objeto JSON.

Tipo: `json`: Predeterminado: `[]`

```html
<custom-schedule events='[]'></custom-schedule>
```

## Propiedades

| Propiedad  | Tipo  | Predeterminado  | Descripción  |
| :------------ | :------------ | :------------ | :------------ |
| view  | `string`  | *week*  | Establece la interfaz visual del componente  |
| day  | `string`  | *now*  | Fecha en que se empieza a mostrar la semana  |
| breaks  | `string`  | *''*  | Recesos en el día laboral  |
| weekend  | `string`  | *saturday,sunday*  | Días no laborales  |
| holidays  | `string`  | *''*  | Días de descanso  |
| start_weekday  | `string`  | *sunday*  | Día en que inicia la semana  |
| start_lab_hour  | `integer`  | *0*  | Hora de inicio laboral  |
| end_lab_hour  | `integer`  | *24*  | Hora de fin del día laboral  |
| interval  | `integer`  | *30*  | Intervalo de tiempo visual de la agenda  |
| increment  | `integer`  | *0*  | Incremento estándar en minutos de un evento  |
| min_duration  | `integer`  | *15*  | Mínimo de duración en minutos de un evento  |
| max_duration  | `integer`  | *60*  | Máximo de duración en minutos de un evento  |
| events  | `object`  | []  | Array con los eventos a renderizar en la agenda  |

## Métodos

#### save

Agrega o edita un evento.

```js
save(event): boolean
```

**Parámetros**

- `array` **event** Array con la información necesaria para agregar o actualizar un evento.

**Devoluciones**

- `boolean`

Retorna `true` si se completo la tarea, en caso contrario `false`.

#### delete

Elimina un evento.

```js
delete(id): boolean
```

**Parámetros**

- `string` **id** Identificador del evento.

**Devoluciones**

- `boolean`

Retorna `true` si se completo la tarea, en caso contrario `false`.

#### renderEvent

Renderiza un nuevo evento.

```js
renderEvent(event): void
```

**Parámetros**

- `array` **event** Array del evento a renderizar.

#### renderEvents

Renderiza todos los eventos de la propiedad `events`.

```js
renderEvents(): void
```

## Eventos

#### CellClick

`cellclick`

Se dispara cuando se hace click sobre una celda del componente.

**Ejemplo:**

```js
const schedule = document.getElementById('agenda');

schedule.addEventListener('cellclick', (e) => {
    /**
     * Argumentos del evento (e)
     * 
     * cancelable: false
     * detail: {
            cell: <td> //Referencia a la celda.
            datetime: "yyyy-MM-dd HH:mm" //Fecha y hora de la celda seleccionada.
            date: "yyyy-MM-dd" //Fecha de la celda seleccionada.
            time: "HH:mm" //Hora de la celda seleccionada.
      }
    */
});
```

#### CellDoubleClick

`celldblclick`

Se dispara cuando se hace doble click sobre una celda del componente.

**Ejemplo:**

```js
const schedule = document.getElementById('agenda');

schedule.addEventListener('celldblclick', (e) => {
    /**
     * Argumentos del evento (e)
     * 
     * cancelable: false
     * detail: {
            cell: <td> //Referencia a la celda.
            datetime: "yyyy-MM-dd HH:mm" //Fecha y hora de la celda seleccionada.
            date: "yyyy-MM-dd" //Fecha de la celda seleccionada.
            time: "HH:mm" //Hora de la celda seleccionada.
      }
    */
});
```

#### ItemClick

`itemclick`

Se dispara cuando se hace click sobre un evento.

**Ejemplo:**

```js
const schedule = document.getElementById('agenda');

schedule.addEventListener('itemclick', (e) => {
    /**
     * Argumentos del evento (e)
     * 
     * cancelable: false
     * detail: { id:"", start:"", ... } // Propiedades del evento
    */
});
```

#### ItemDoubleClick

`itemdblclick`

Se dispara cuando se hace doble click sobre un evento.

**Ejemplo:**

```js
const schedule = document.getElementById('agenda');

schedule.addEventListener('itemdblclick', (e) => {
    /**
     * Argumentos del evento (e)
     * 
     * cancelable: false
     * detail: { id:"", start:"", ... } // Propiedades del evento
    */
});
```

#### ItemMoving

`itemmoving`

Se dispara durante el desplazamiento de un evento.

**Ejemplo:**

```js
const schedule = document.getElementById('agenda');

schedule.addEventListener('itemmoving', (e) => {
    /**
     * Argumentos del evento (e)
     * 
     * cancelable: true
     * detail: {
            cell: <td> //Referencia a la celda actual del desplazamiento.
            item: {} //Propiedades del evento antes de actualizar.
            from: "" //Fecha de origen
            to: "" //Fecha de destino
      }
    */
});
```

#### ItemMoved

`itemmoved`

Ocurre al soltar un evento, después de desplazarlo cambiando su fecha de inicio.

**Ejemplo:**

```js
const schedule = document.getElementById('agenda');

schedule.addEventListener('itemmoved', (e) => {
    /**
     * Argumentos del evento (e)
     * 
     * cancelable: false
     * detail: {
            cell: <td> //Referencia a la celda actual del desplazamiento.
            item: {} //Propiedades del evento después de actualizar.
            from: "" //Fecha de origen
            to: "" //Fecha de destino
      }
    */
});
```

#### ItemResizing

`itemresizing`

Se dispara durante el redimensionamiento de un evento.

**Ejemplo:**

```js
const schedule = document.getElementById('agenda');

schedule.addEventListener('itemresizing', (e) => {
    /**
     * Argumentos del evento (e)
     * 
     * cancelable: false
     * detail: {
            item: {} //Propiedades del evento antes de actualizar.
            oldDuration: 0 //Duración inicial del evento.
            newDuration: 0 //Nueva duración a establecer.
      }
    */
});
```

#### ItemResized

`itemresized`

Ocurre al finalizar el redimensionamiento del evento.

**Ejemplo:**

```js
const schedule = document.getElementById('agenda');

schedule.addEventListener('itemresizing', (e) => {
    /**
     * Argumentos del evento (e)
     * 
     * cancelable: false
     * detail: {
            item: {} //Propiedades del evento después de actualizar.
            oldDuration: 0 //Duración inicial del evento.
            newDuration: 0 //Nueva duración del evento.
      }
    */
});
```

#### BeforeCreateItem

`beforecreateitem`

Ocurre antes de crear un nuevo evento.

**Ejemplo:**

```js
const schedule = document.getElementById('agenda');

schedule.addEventListener('beforecreateitem', (e) => {
    /**
     * Argumentos del evento (e)
     * 
     * cancelable: true
     * detail: {
            item: {} //Propiedades del evento a crear.
      }
    */
});
```

#### ItemCreated

`itemcreated`

Ocurre después de crear un nuevo evento.

**Ejemplo:**

```js
const schedule = document.getElementById('agenda');

schedule.addEventListener('itemcreated', (e) => {
    /**
     * Argumentos del evento (e)
     * 
     * cancelable: false
     * detail: {
            item: {} //Propiedades del evento creado.
            element: <div> //Referencia al elemento creado.
      }
    */
});
```

#### BeforeUpdateItem

`beforeupdateitem`

Ocurre antes de actualizar un evento.

**Ejemplo:**

```js
const schedule = document.getElementById('agenda');

schedule.addEventListener('beforeupdateitem', (e) => {
    /**
     * Argumentos del evento (e)
     * 
     * cancelable: true
     * detail: {
            oldItem: {} //Propiedades del evento antes de actualizar.
            oldElement: <div> //Copia del elemento antes de actualizar.
            newItem: {} //Propiedades del evento con los nuevos valores.
      }
    */
});
```

#### ItemUpdated

`itemupdated`

Ocurre después de actualizar un evento.

**Ejemplo:**

```js
const schedule = document.getElementById('agenda');

schedule.addEventListener('itemupdated', (e) => {
    /**
     * Argumentos del evento (e)
     * 
     * cancelable: false
     * detail: {
            oldItem: {} //Propiedades del evento antes de actualizar.
            oldElement: <div> //Copia del elemento antes de actualizar.
            newItem: {} //Propiedades del evento después de actualizar.
            newElement: <div> //Referencia al elemento actualizado.
      }
    */
});
```

#### BeforeDeleteItem

`beforedeleteitem`

Ocurre antes de eliminar un evento.

**Ejemplo:**

```js
const schedule = document.getElementById('agenda');

schedule.addEventListener('beforedeleteitem', (e) => {
    /**
     * Argumentos del evento (e)
     * 
     * cancelable: true
     * detail: {
            index: 0 //Indice del evento a eliminar.
            item: {} //Propiedades del evento a eliminar.
      }
    */
});
```

#### ItemDeleted

`itemdeleted`

Ocurre después de eliminar un evento.

**Ejemplo:**

```js
const schedule = document.getElementById('agenda');

schedule.addEventListener('itemdeleted', (e) => {
    /**
     * Argumentos del evento (e)
     * 
     * cancelable: false
     * detail: {
            index: 0 //Indice del evento eliminado.
            item: {} //Propiedades del evento eliminado.
      }
    */
});
```
