Premium Widgets
Custom Calendar (Week)
Custom Calendar (Week)
AI Defaults
- uniqueId
- Required, `"calendar-" + Nr`.
- height
- Use `"100%"` when embedded in a layout.
- timeZoneBalance
- Set `-1` for German timezone in `dateSettings`.
- dateFrom/dateTo
- Must be actual date field values, not strings.
- dragAction
- Requires `recordId: Nr` and field IDs via `fieldId(Nr, "Feldname")`. Optional `changeFieldValues` for extra field updates after a successful drag (cache/trigger fields).
- createNew
- Needs `tableId` and field IDs via `fieldId(Nr, "Feldname")`. Optional `changeFieldValues` for extra fields on create. Optional `dataBag` after a successful create (same as Button create; `##newRecordId##`). Optional `item` for click-to-place (duration, clock, `offset: { days, time }`, `splits`, `linked`). `linked: false` + clock = satellite (does not pin the duration chain). Shift moves the whole ghost; release snaps satellites back. Create writes the same four date/time fields — overall span of the chain. Toggle with `item.active`. Empty selection: omit `item` (never `else ""`). Same-title pause: `splits`. Named leftover pieces (Teil 1 / Teil 2): three `segments`, not `splits`.
- Persistence
- Drag/create go through the **Action Performer** (`type: "update"` / `type: "create"`). Ninox config (`dragAction` / `createNew`) is unchanged. React hosts: handle these via `onAction` — **no** global `database` stub.
- timeSettings
- Omit for full 0–24h range. Set `from`/`to` in hours (integers) to restrict.
- lang
- Set `lang: clientLang()` for localized weekdays/months.
Custom Calendar (Week)
Con el widget **Custom Calendar Week** llevas una potente vista de calendario directamente a tu base de datos Ninox. Puedes integrarlo sin problemas en cualquier tabla, diseñarlo con flexibilidad y rellenarlo dinámicamente con tus propios datos. Ya sea planificación de proyectos, gestión de recursos o vista de citas: el widget se adapta a tus necesidades.💡 Lo que puedes hacer con Custom Calendar:
- Diseño individual: Adapta colores, iconos y layout a tu estilo o tu marca.
- Entradas flexibles: Diseña la representación de tus citas, tareas o eventos exactamente como las necesites, con los campos, iconos o etiquetas que quieras.
- Eventos de varios días y de todo el día: Planifica con claridad y detecta de un vistazo los periodos más largos.
- Arrastrar y soltar: Mueve citas directamente en el calendario, de forma intuitiva y sin rodeos.
- Filtrado dinámico: Muestra solo las entradas relevantes, controlable mediante script de Ninox.
- Resaltado de días especiales: Marca festivos, vacaciones, ausencias o eventos individuales.
- Eje de tiempo personalizable: Muestra solo las horas importantes para tu caso de uso, p. ej. de 8 a 18 h en lugar de 0 a 24 h.
- Integración de varias tablas: Vincula datos de distintas fuentes, ideal para equipos o proyectos distribuidos.
- Funciona sin conexión: Tu calendario sigue siendo utilizable incluso sin internet.
📅 Custom Calendar Week hace que tu planificación de citas en Ninox sea más clara, interactiva y notablemente más eficiente, perfecto para quienes quieren sacar más partido a su base de datos.
Código de aplicación
let current := this;
arcCustomCalendarWeek({
uniqueId: "cal-39",
embedded: false,
weekdaySettings: {
week: 12,
year:2024
},
weekStart: "",
dateSettings: {
startDate: date(2025, 2, 2),
endDate: "",
duration: 7,
highlights: [{
date: date(2025, 2, 7),
color: "#F1B6CE"
}, {
weekday: 6,
color: "rgba(255,0,0,0.1)"
}, {
weekday: 7,
color: "rgba(255,0,0,0.1)"
}]
},
timeZoneBalance: "",
timeSettings: {
timeStart: time(6, 30),
duration: time(15, 0)
},
currentTime: "rgba(0,0,255,0.5)",
lang: clientLang(),
timeSlotWidth: "250px",
timeSlotHeight: "80px",
allDayHeight: "",
styles: {
backgroundColor: "rgba(0,0,255,0.01)"
},
createNew: {
tableId: "B",
dateFrom: "A",
timeFrom: "B",
dateTo: "C",
timeTo: "D",
changeFieldValues: [{
fieldId: fieldId(Nr, "CacheTrigger"),
value: now()
}]
},
timeEntries: (select 'Time Entries').[{
title: Kalendertitel,
subtitle: Description,
value: "",
customLayout: "",
dateFrom: 'Date From',
dateTo: 'Date To',
timeFrom: 'Time From',
timeTo: 'Time To',
styles: {
backgroundColor: color(Person),
color: "#fff",
borderRadius: "8px",
padding: "5px"
},
insetBorder: {
enabled: true,
stroke: "dotted"
},
dragAction: {
recordId: Nr,
dateFrom: "A",
timeFrom: "B",
dateTo: "C",
timeTo: "D",
changeFieldValues: [{
fieldId: fieldId(Nr, "CacheTrigger"),
value: now()
}]
},
clickAction: {
type: "popup",
recordId: Nr
},
segments: [{
title: "Anfahrt",
timeFrom: SegVon,
timeTo: SegBis,
dateFrom: 'Seg Date From',
dateTo: 'Seg Date To',
linked: false,
dragAction: {
recordId: Nr,
dateFrom: "E",
timeFrom: "F",
dateTo: "G",
timeTo: "H"
}
}]
}]
})
Ajustes generales
weekdaySettings – control específico de la semana calendario
Con el parámetro weekdaySettings puedes definir exactamente qué semana calendario de qué año se muestra en el calendario.
En este ejemplo se muestra la semana calendario 12 del año 2025.
En lugar de valores fijos, también puedes referenciar campos de Ninox para dinamizar los datos.
⚠️ Importante: Si están configurados tanto dateSettings como weekdaySettings, dateSettings tiene prioridad y sobrescribe los valores de weekdaySettings.
dateSettings – inicio, duración y resaltado en la vista semanal
Con el grupo de parámetros dateSettings controlas cuándo empieza tu calendario, cuánto tiempo se muestra y qué días deben resaltarse especialmente.
Parámetros individuales en dateSettings:
startDate*(obligatorio)*endDate*(opcional)*duration*(opcional)*
Lógica de la duración de visualización:
- Solo
startDateconfigurado → muestra 7 días a partir de la fecha de inicio startDate+duration→ muestra el número de días definidostartDate+endDate→durationse ignorahighlights*(opcional)*header*(opcional)*
header: {
backgroundColor: "#F8FAFC",
title: {
label: "##weekDayShort##. ##day##.",
fontSize: "15px",
fontColor: "#000",
alignX: "center"
},
subtitle: {
label: "##weekdayName##",
fontSize: "12px",
fontColor: "#666"
}
}
Marcadores para label: ##date##, ##weekdayName##, ##weekDayLong##, ##weekDayShort##, ##day##, ##month##, ##monthLong##, ##monthShort##, ##year##
📌 Nota: subtitle es opcional. Si solo indicas title (sin subtitle), la segunda línea no se muestra – el título recibe todo el espacio. - day *(opcional)* Controla las acciones al hacer clic en un día (p. ej. seleccionar fecha, cambiar de vista).
day: {
actions: [{
type: "update",
recordId: Nr,
field: fieldId(Nr, "helper_selectedDate"),
value: "##clickedDate##"
}]
}
Marcador: ##clickedDate## se sustituye por la marca de tiempo en milisegundos de la fecha clicada (p. ej. 1731369600000).
dateSettings: {
startDate: "",
endDate: "",
duration: 14,
highlights: [{
date: date(2024, 10, 31),
color: 'Color Highlights'
}, {
weekday: 6,
color: "rgba(255,0,0,0.1)"
}, {
weekday: 7,
color: "rgba(255,0,0,0.1)"
}]
}
weekStart – definir el día de inicio de la semana calendario
Con el parámetro weekStart determinas en qué día de la semana debe empezar tu calendario.
📌 Tipo: Número (0–6) 📅 Valores:
0= Domingo *(habitual, p. ej., en EE. UU.)*1= Lunes *(estándar en Europa Central)*2= Martes- ...
6= Sábado
💡 Consejo: Para la mayoría de los usuarios en el ámbito hispanohablante, 1 (lunes) es la opción adecuada.
weekStart: 1,
timeZoneBalance – corrección manual de zona horaria para una visualización precisa
Tipo: Número (en horas)
El parámetro timeZoneBalance te ayuda a compensar diferencias de zona horaria que pueden surgir por la forma en que Ninox representa los datos.
Contexto: Ninox usa internamente otra lógica de zona horaria, lo que puede provocar un desplazamiento de las horas en el calendario.
Recomendación para Alemania: Ajusta el valor a -1 para adaptar la visualización a la hora centroeuropea (CET/CEST).
timeZoneBalance: -1,
timeZoneBalance: "" // default: Zeiten werden wie in Ninox gespeichert angezeigt, die Nutzer-Zeitzone wird nicht beachtet.</code></pre>
timeSettings – control individual del eje horario
Con el grupo de parámetros timeSettings puedes definir qué franja horaria del día se muestra en el calendario. Así puedes adaptar mejor la vista del calendario a tu caso de uso, p. ej., para horarios de oficina típicos o modelos de turnos.
timeSettings: {
timeStart: time(6, 30), // Zeitfeld oder Milisekunden
duration: time(6, 30), // Duration in Milisekunden angeben. hier: 8 Stunden
},
En este ejemplo el día del calendario empieza a las 06:00 y termina a las 22:00.
🧠 Importante saber:
- Solo se admiten horas completas.
- Si se indica, p. ej.,
6.5 (para las 06:30), el sistema redondea a las 06:00. - El rango estándar sin configuración propia es de 0 a 24 h (es decir, un día completo).
💡 Consejo: Menos horas visibles = representación más compacta = mejor visión de conjunto con muchas entradas.
currentTime – marcado en color de la hora actual
El parámetro currentTime controla la representación de una barra estrecha que te muestra la hora actual en el calendario – de forma similar a las apps de calendario conocidas.
🎨 Función: Con este parámetro fijas el color de la barra que marca la posición actual dentro del día.
currentTime: "rgba(0,0,255,0.5)", // RGB Codes
currentTime: "#f95757" // HEX Codes
lang
Esta función se configura por defecto y no necesita ajustarse.
lang: clientLang(),
timeSlotWidth – ancho de cada día de la semana
Con el parámetro timeSlotWidth fijas qué ancho tienen las columnas de cada día en el calendario semanal.
`timeSlotWidth: "250px" ,`
→ Cada día de la semana se muestra con **250 píxeles de ancho**.
📌 Nota:
- El valor por defecto es de aproximadamente 100 px, pero puede ajustarse según los requisitos del layout.
- Un número más alto ofrece más espacio por día, especialmente útil con muchas entradas.
timeSlotHeight – fijar la altura de las filas horarias
Con el parámetro timeSlotHeight determinas qué altura tiene cada hora en el calendario.
`timeSlotHeight: "80px",`
→ Cada hora recibe una **altura de 50 píxeles** en el eje de tiempo vertical.
📌 Nota:
- El valor por defecto es de aproximadamente 40 px.
- Un valor más alto ofrece más espacio por hora.
allDayHeight – altura de la fila para entradas de todo el día
Con el parámetro allDayHeight fijas qué altura tiene la fila superior para las entradas de todo el día.
→ La fila para entradas de todo el día se muestra con una altura de 60 píxeles.
📌 Nota:
- Por defecto la altura es de aprox. 40 px.
- Un valor más alto crea más espacio para varias entradas de todo el día o representaciones de texto más grandes.
styles – estilo individual para tu calendario
Con styles puedes adaptar el aspecto de tu calendario – aquí puedes personalizar actualmente el color de fondo de tu calendario.
styles: {
backgroundColor: "rgba(0,0,255,0.01)"
},
### createNew – crear nuevas citas arrastrando
Con el parámetro createNew activas la posibilidad de crear nuevas citas directamente arrastrando un rango de tiempo en el calendario.
🖱️ Así funciona:
- Haces clic en una zona libre del calendario, arrastras con el botón del ratón pulsado y sueltas.
- Con esto se crea automáticamente una nueva cita, incluyendo hora de inicio y duración.
📌 Nota:
- Todas las referencias de campo (
dateFrom, dateTo, timeFrom, timeTo) deben coincidir con los Field IDs de los campos correspondientes de tu tabla de citas del calendario (tableId). - Puedes averiguar fácilmente los Field IDs con la función de Ninox
fieldId() e incorporarlos directamente en la configuración.
💡 Consejo: Ideal para una planificación de citas rápida e intuitiva, p. ej., en turnos, reservas o asignación de salas.
Opcionalmente puedes usar changeFieldValues para establecer campos adicionales en el nuevo registro – p. ej., campos de caché o de trigger:
createNew: {
tableId: "B",
dateFrom: fieldId(Nr, "Datum von"),
timeFrom: fieldId(Nr, "Von"),
dateTo: fieldId(Nr, "Datum bis"),
timeTo: fieldId(Nr, "Bis"),
changeFieldValues: [{
fieldId: fieldId(Nr, "CacheTrigger"),
value: now()
}]
}
Opcional dataBag: tras crear correctamente, se actualiza el mismo bote de estado JSON que en Button-Create. Solo se ejecuta si el registro se creó realmente. ##newRecordId## se sustituye por el ID de la nueva cita. Típico: vaciar la selección para que desaparezca el ghost.
createNew: {
tableId: "B",
dateFrom: fieldId(Nr, "Datum von"),
timeFrom: fieldId(Nr, "Von"),
dateTo: fieldId(Nr, "Datum bis"),
timeTo: fieldId(Nr, "Bis"),
item: if Auswahl then {
/* Ghost */
},
dataBag: {
recordId: Nr,
fieldId: fieldId(Nr, "helper_uiState"),
base: helper_uiState,
patch: { auswahlId: null }
}
}
null en el patch elimina la key. Guardar también el nuevo ID de cita: patch: { auswahlId: null, lastTerminId: "##newRecordId##" }. Sintaxis: <a href="../patterns/data-bag-actions.md"><code>data-bag-actions</code></a>.
📌 Persistencia / React: Create se ejecuta mediante { type: "create", tableId, changeFieldValues, setNewRecordId?, dataBag?, popup?, fullscreen? }. React: procesar la misma acción mediante onAction.
createNew.item – colocar una cita preconfigurada con un clic
Con createNew.item colocas una cita ya preparada en el calendario, en lugar de arrastrar un intervalo de tiempo. Caso típico: una selección en una barra lateral (tipo, duración, fases) escribe en el campo de fórmula — el calendario muestra un ghost que sigue al ratón. Un clic lo coloca.
Sin item se mantiene el arrastre habitual. Con item (y con duration o duraciones de segmento definidas) el arrastre queda desactivado — excepto si active es false.
El modo de colocación se activa fuera del calendario: un campo sí/no, una casilla en la barra lateral o la propia selección.
createNew: {
tableId: "B",
dateFrom: fieldId(first(Termine), "Datum von"),
timeFrom: fieldId(first(Termine), "Von"),
dateTo: fieldId(first(Termine), "Datum bis"),
timeTo: fieldId(first(Termine), "Bis"),
changeFieldValues: if Auswahl then [{
fieldId: fieldId(first(Termine), "Typ"),
value: number(Auswahl)
}] else [{
fieldId: fieldId(first(Termine), "CacheTrigger"),
value: now()
}],
item: if Auswahl then {
active: Platzieren,
title: Auswahl.Name,
styles: {
backgroundColor: color(Auswahl),
color: "#fff",
borderRadius: "8px"
},
segments: [{
title: "Anfahrt",
linked: false,
offset: { days: -1 },
timeFrom: time(16, 0),
timeTo: time(17, 0)
}, {
title: "Kernarbeit",
timeFrom: time(11, 0),
timeTo: time(14, 0),
splits: [{
title: "Pause",
timeFrom: time(12, 30),
timeTo: time(13, 0)
}]
}, {
title: "Abfahrt",
linked: false,
offset: { days: 1 },
timeFrom: time(8, 0),
timeTo: time(9, 0)
}]
}
}
Campos en item:
- active — opcional. true u omitido: ghost activado, el clic coloca. false / vacío: ghost desactivado, el arrastre vuelve a estar activo. Se vincula a un campo fuera del widget (p. ej. Platzieren). - duration — longitud relativa. Las fases de solo duración se enganchan a la fase de seguimiento anterior (la primera: al ratón). - timeFrom / timeTo — hora fija en el día de anclaje (día bajo el ratón). Fija esta fase. Con linked: false permanece como satélite — la cadena de seguimiento sigue siguiendo al ratón. Sin linked: false la cadena queda enganchada a esta hora. - linked — igual que en los segmentos guardados. false = satélite (ida/vuelta). Por defecto true. - offset — { days, time }, ambos opcionales y con signo. days: -1 día anterior, days: 1 día siguiente. time: -time(1, 0) una hora antes (ratón / fase anterior). Combinable: { days: -1, time: -time(1, 0) }. Con hora fija, days elige el día del calendario; time desplaza la hora junto con él. days: 0 mantiene la fase en el día de anclaje si la fase anterior estaba en otro día. No confundir con el offset: time(…) plano en splits. - dateFrom / dateTo — valores de fecha reales (como en timeEntries), cuando la fase está fija en un día concreto del calendario. - splits — un nivel de interrupciones en esta fase (típicamente una pausa). Ambos trozos principales conservan el título de la fase. Ver más abajo. - title / subtitle / value / customLayout / styles / insetBorder — como un timeEntry.
Resolución por fase, primera regla que aplica: fecha fija + hora → hora (timeFrom/timeTo, opcional offset.days / offset.time) → offset + duration → solo duration. linked: false + hora no actualiza el cursor de seguimiento.
Tecla Mayús en el ghost: mover toda la cadena, incluidos los satélites. Al soltar: los satélites vuelven a su hora fija. El clic guarda lo que se ve.
Núcleo bajo el ratón, satélite con hora fija:
segments: [{
title: "Anfahrt",
linked: false,
offset: { days: -1 },
timeFrom: time(16, 0),
timeTo: time(17, 0)
}, {
title: "Vorarbeit",
offset: { days: 0 },
duration: time(0, 30)
}, {
title: "Kern",
duration: time(3, 0)
}, {
title: "Abfahrt",
offset: { days: 1 },
duration: time(1, 0)
}]
Sin horas fijas (sigue al ratón):
segments: [{
title: "Anfahrt",
offset: { days: -1, time: -time(1, 0) },
duration: time(1, 0)
}, {
title: "Kernarbeit",
offset: { days: 0 },
duration: time(3, 0),
splits: [{
title: "Pause",
offset: time(1, 30),
duration: time(0, 30)
}]
}, {
title: "Abfahrt",
offset: { days: 1 },
duration: time(1, 0)
}]
Si las partes deben tener nombres distintos (Parte 1 / Pausa / Parte 2): tres segments con duration, sin splits.
El ghost puede abarcar varios días. Por fase la hora avanza en tiempo real (##entrytime##).
El ghost ocupa un carril propio — las citas existentes en el mismo horario se desplazan hacia un lado, igual que con dos entradas reales. Al retirar el ratón, las demás vuelven a su ancho completo.
Ocultar: ojo en la toolbar o Esc. Volver a mostrar solo mediante el ojo. La selección de la barra lateral se mantiene.
Se guarda un nuevo registro en los mismos cuatro campos de createNew: desde la primera fase hasta el final de la última. changeFieldValues y dataBag igual que al arrastrar.
Selección vacía: omitir item (nunca else ""). Entonces se aplica de nuevo el arrastre.
timeEntries – tus entradas de calendario en detalle
El bloque timeEntries define qué entradas de tiempo concretas se muestran en el calendario.
Aquí determinas cómo se representa cada entrada individual: desde el título hasta el color, e incluso layouts propios. Así puedes diseñar tus tarjetas de calendario de forma totalmente individual y adaptarlas a tu caso de uso. Con esto se crea automáticamente una nueva cita, incluyendo hora de inicio y duración.
📌 Nota:
Para mostrar el cambio en tiempo real de los datos de la cita (al crear o también al mover una cita), el marcador "##entrytime##" se puede usar en cualquier parte de timeEntries donde se deba mostrar la hora de la cita, es decir, en title, subtitle, value, pero también en todos los widgets que se usen aquí. Por ejemplo, cuando se usa un customLayout para el diseño del timeEntry o en botones, inputs, etc.
Por ejemplo dentro de un bloque de layout en el widget Text:
...
value: arcCustomText({
alignY: "top",
fontSize: typo.paragraph3.fontSize,
fontWeight: "400",
fontColor: appointmentType.colorShade,
value: "##entrytime##"
}),
...
➡️ Todos los parámetros para las timeEntries los encuentras en la siguiente sección.
title – título de la entrada del calendario
Con el parámetro title fijas qué se muestra en la primera línea de la entrada del calendario.
🔧 Dos opciones:
- Título propio:
- Sin indicación (
"):
title: Kalendertitel, // Ninox Feld
title: "", // Default: Gibt die Uhrzeit des Kalendereintrages an
📌 Nota:
- Si no asignas un título y en su lugar se muestra la hora, esta se actualiza en vivo con los cambios, p. ej., al arrastrar o alargar una entrada.
- Valor vacío: Si
title está vacío o solo contiene espacios, la línea del título se oculta – el espacio pasa a subtitle o ##entrytime##.
subtitle – descripción bajo el título
Con el parámetro subtitle puedes mostrar una línea adicional bajo el título en la entrada del calendario.
Normalmente aquí se coloca una breve descripción o una indicación complementaria, como el motivo de la cita o un estado.
subtitle: Description, // Ninox Feld
subtitle: "" // Textfeld
→ Muestra, p. ej., el contenido del campo *„Description“* bajo el título en la entrada del calendario.
📌 Nota:
- El
subtitle es opcional y solo se muestra si existe un valor de campo correspondiente. - Valor vacío: Si
subtitle está vacío o solo contiene espacios, la línea de subtitle se oculta – el espacio pasa al título. Título y subtitle se tratan de forma simétrica: si ambos están vacíos, solo se muestra ##entrytime##.
value – información adicional o campos interactivos
El parámetro value representa la tercera línea de tu entrada de calendario. Aquí puedes mostrar más información o incluso integrar elementos interactivos como campos de entrada o listas de selección.
🔧 Posibilidades de uso:
- Información adicional como, p. ej., lugar, estado, responsable
- Widgets interactivos directamente en la entrada del calendario – p. ej.:</p><ul><li data-preset-tag="p"><p>Un campo de selección para elegir al empleado responsable
- Un campo de entrada para notas breves o respuestas
</li></ul><pre data-language="JavaScript"><code>value: "", value: Kommentar, </code></pre>→ Muestra el contenido del campo *„Kommentar“* en la tercera línea.
📌 Nota:
value es opcional, pero amplía la representación de tus entradas con un nivel adicional.- En combinación con widgets integrados surge una experiencia de calendario interactiva directamente en la entrada.
💡 Consejo: Usa value para mostrar información adicional importante de inmediato – o para que tus usuarios trabajen directamente en el calendario.
customLayout – layout individual completo para entradas de calendario
Con el parámetro customLayout puedes definir un layout completamente propio para tus entradas de calendario.
Si usas este parámetro, los campos estándar title, subtitle y value ya no se muestran. En su lugar puedes diseñar libremente el aspecto de tu entrada de calendario, con los widgets que quieras.
`customLayout: "",`
💡 Consejo: Usa `customLayout` cuando necesites una representación completamente individual, p. ej., con colores propios, iconos, estructura o condiciones lógicas.
dateFrom, dateTo, timeFrom, timeTo – hora de inicio y fin por entrada
Con estos cuatro parámetros indicas qué campos de tu registro de entrada de tiempo deben usarse para la fecha y la hora.
dateFrom: 'Date From',
dateTo: 'Date To',
timeFrom: 'Time From',
timeTo: 'Time To',
📌 Nota:
- Deben indicarse campos de fecha y hora reales de Ninox.
- La combinación de fecha + hora determina la posición y la duración de la entrada del calendario.
⚠️ Importante saber:
- Si falta
dateTo, se usa automáticamente el día de dateFrom (y viceversa). - Si faltan ambos campos de fecha, la entrada no se muestra.
- Si falta
timeTo, se usa automáticamente timeFrom + 5 minutos. - Si falta
timeFrom, se asume timeTo - 5 minutos.
💡 Consejo: Si solo quieres mostrar entradas de día sin horas exactas, también puedes trabajar solo con campos de fecha – el calendario mostrará entonces la entrada como cita de todo el día.
styles – estilo individual para entradas de calendario
Con el parámetro styles puedes adaptar el aspecto de entradas de calendario individuales – p. ej., colores, espaciado interno (padding) o esquinas redondeadas (border-radius).
styles: {
backgroundColor: color(Person),
color: "#fff",
borderRadius: "8px",
padding: ""
},
📌 **Propiedades admitidas:**
backgroundColor: Color de fondo de la tarjetacolor: Color de fuentepadding: Espaciado interno (p. ej. "6px")borderRadius: Redondeo de esquinas (p. ej. "8px")
💡 Consejo: Con styles puedes diferenciar visualmente tus entradas entre sí, p. ej., por estado, tipo o prioridad – también de forma dinámica, si usas campos de tu fuente de datos como valor.
dragAction – definir campos para mover entradas
Con el parámetro dragAction defines qué campos de fecha y hora deben actualizarse al arrastrar o mover una entrada.
Así se garantiza que la nueva hora quede guardada en el registro cuando se mueve una entrada en el calendario.
dragAction: {
recordId: Nr,
dateFrom: fieldId(Nr, "Datum von"),
timeFrom: fieldId(Nr, "Von"),
dateTo: fieldId(Nr, "Datum bis"),
timeTo: fieldId(Nr, "Bis"),
changeFieldValues: [{
fieldId: fieldId(Nr, "CacheTrigger"),
value: now()
}]
}
📌 Nota:
- Indica aquí los Field IDs correctos de cada campo en la tabla de entradas de tiempo.
- Aquí puedes usar la función de Ninox
fieldId(). - changeFieldValues: Opcional. Array de
{ fieldId, value } – se escribe después de un arrastre exitoso (la fecha/hora ha cambiado). Uso típico: actualizar campos de caché o de trigger. Estructura igual que en createNew.changeFieldValues y como en la Timeline.
⚠️ Importante: recordId y los campos de fecha/hora son obligatorios si quieres que las entradas se puedan mover mediante arrastrar y soltar o cambiar de duración.
📌 Persistencia / React: Al guardar tras el arrastre, el widget envía acciones del Action Performer { type: "update", recordId, field, value } (una acción por campo modificado). En Ninox, el adaptador lo mapea a database.update. En el adaptador React esto llega a onAction — sin database global.
clickAction – abrir entradas con un clic en Ninox
Con el parámetro clickAction permites que el usuario, al hacer clic en una entrada de calendario, pueda abrir directamente el registro correspondiente en Ninox.
clickAction: {
type: "popup",
recordId: Nr
}
📌 Significado de los parámetros:
type: "popup" – Abre el registro en una ventana popup (podrían seguir otros tipos).recordId: El campo en la entrada del calendario que contiene la clave primaria (Record ID) – normalmente "Nr".
⚠️ Importante:
- El campo indicado en
recordId debe contener el ID real del registro de Ninox. - Si no se encuentra un valor válido, no ocurre nada al hacer clic.
insetBorder – línea inset vertical en la entrada del calendario
Con insetBorder puedes mostrar una línea vertical discreta en el borde izquierdo (o derecho) de cada entrada del calendario – similar al estilo del calendario de Apple. La función está activa por defecto y solo hay que desactivarla si no la quieres.
insetBorder: {
enabled: true, // Standard: true – false blendet die Linie aus
position: "left", // "left" (Standard) oder "right"
width: "2px", // Breite der Linie
stroke: "dotted", // "solid", "dashed" oder "dotted"
color: "#ffffff" // Farbe (Standard: Schriftfarbe des Eintrags)
}
📌 Nota:
- La línea reacciona automáticamente al
borderRadius de la entrada y se acorta a medida que aumenta el radio. - En segmentos conectados (cadena) se continúa sin cortes en las transiciones.
- Puedes definir
insetBorder tanto a nivel del timeEntry como por segmento – el nivel de segmento sobrescribe el nivel de entrada.
segments – dividir citas en fases
Con el parámetro segments puedes dividir una cita en varias fases de tiempo relacionadas entre sí – p. ej., desplazamiento de ida, trabajo previo, trabajo principal, pausa, trabajo posterior y desplazamiento de vuelta.
Cada segmento es una entrada independiente con su propio horario y diseño, pero puede vincularse con otros segmentos para que se muevan juntos al desplazarlos.
timeEntries: (select Termine).[{
title: Bezeichnung,
dateFrom: 'Datum von',
dateTo: 'Datum bis',
timeFrom: Von,
timeTo: Bis,
styles: {
backgroundColor: "#5b6af0",
color: "#fff",
borderRadius: "8px"
},
dragAction: {
recordId: Nr,
dateFrom: fieldId(Nr, "Datum von"),
timeFrom: fieldId(Nr, "Von"),
dateTo: fieldId(Nr, "Datum bis"),
timeTo: fieldId(Nr, "Bis")
},
segmentSettings: {
dayJump: {
threshold: time(22, 0),
startTime: time(7, 0)
}
},
segments: [{
title: "Anfahrt",
dateFrom: 'Seg Datum von',
dateTo: 'Seg Datum bis',
timeFrom: SegVon,
timeTo: SegBis,
styles: {
backgroundColor: "#3b4fd0",
color: "#fff"
},
linked: false,
segmentType: "travel",
dragAction: {
recordId: Nr,
dateFrom: fieldId(Nr, "Seg Datum von"),
timeFrom: fieldId(Nr, "SegVon"),
dateTo: fieldId(Nr, "Seg Datum bis"),
timeTo: fieldId(Nr, "SegBis")
}
}, {
title: "Kernarbeit",
dateFrom: 'Kern Datum von',
dateTo: 'Kern Datum bis',
timeFrom: KernVon,
timeTo: KernBis,
styles: {
backgroundColor: "#5b6af0",
color: "#fff"
},
linked: true
}]
}]
Campos por segmento
Parameter Typ Beschreibung titleText Titel des Segments subtitleText Untertitel (optional) valueText/Widget Zusatzzeile oder eingebettetes Widget dateFrom, dateToDatum Start- und Enddatum timeFrom, timeToZeit Start- und Endzeit stylesObjekt Wie beim timeEntry – überschreibt Parent-Styles linkedBoolean true = Segment wird mit anderen linked-Segmenten gemeinsam verschoben (Standard: true)segmentTypeText Frei wählbarer Typ-Bezeichner (z. B. "travel", "core") insetBorderObjekt Inset-Linie für dieses Segment (überschreibt Entry-Level) dragActionObjekt Felder für Drag & Drop – Aufbau identisch mit timeEntry.dragAction segmentSettingsObjekt Segment-Einstellungen für dieses einzelne Segment (z. B. dayJump) splitsArray Eine Ebene Unterbrechungen in dieser Phase (z. B. Pause). Das Widget macht daraus: Teil 1 → Pause → Teil 2.
💡 Consejo: Los campos que no se definan en el segmento heredan el valor del timeEntry superior. Así basta con definir solo las diferencias por segmento.
splits – pausa dentro de una fase
splits divide una fase (normalmente el trabajo principal), sin que tengas que crear en Ninox „Kern Teil 1 / Kern Teil 2“. Sin más anidación — solo este único nivel.
{
title: "Kernarbeit",
dateFrom: 'Datum von',
dateTo: 'Datum bis',
timeFrom: time(11, 0),
timeTo: time(14, 0),
splits: [{
title: "Pause",
timeFrom: time(12, 30),
timeTo: time(13, 0),
styles: {
backgroundColor: "#94a3b8"
}
}]
}
O relativo al inicio de la fase: offset: time(1, 30), duration: time(0, 30).
Se permiten varios splits; se ordenan por hora de inicio y se limitan al rango de tiempo de la fase. Los trozos principales conservan el look y el título de la fase, la pausa el suyo propio.
Títulos distintos para los trozos principales (Parte 1 / Parte 2): tres segments, sin splits — p. ej., duration: time(1, 30), pausa, duration: time(1, 30).
linked – vincular o desacoplar segmentos
Con linked: true (por defecto) un segmento pasa a formar parte de la cadena conectada. Al mover en el calendario, todos los segmentos vinculados se mueven juntos.
Con linked: false un segmento queda desacoplado – p. ej., ida y vuelta, que pueden estar en otro día y deben moverse de forma independiente. En el placement-ghost (createNew.item) rige lo mismo: una hora fija en un satélite linked: false no fija el núcleo.
Toolbar
Abajo a la derecha hay una pequeña toolbar. Es siempre visible, salvo que segmentSettings.toolbar sea false.
Candado — mover segmentos en conjunto o por separado:
- Bloqueado (candado cerrado): Todos los segmentos del
timeEntry se mueven juntos - Individual (candado abierto): Los segmentos
linked forman un grupo, los segmentos linked: false se pueden mover de forma independiente
Sin segmentos, el candado está inactivo. Al pasar el ratón por encima aparece una breve indicación.
Ojo — solo con createNew.item: mostrar y ocultar el ghost. Esc lo oculta. Volver a mostrarlo solo mediante el ojo. Al ocultarlo, se aplica de nuevo el arrastre, sin cambiar la selección en la barra lateral.
💡 Tecla Mayús: Durante un arrastre o en el placement-ghost mantén pulsada Mayús para invertir el lock: los satélites guardados o los satélites del ghost se mueven junto con el conjunto. Al soltar, los satélites del ghost vuelven a su hora fija. El icono del candado muestra el estado en tiempo real.
💡 Mayús + redimensionar: Si mantienes pulsada la tecla Mayús y arrastras desde el borde de un segmento (arriba/abajo), todos los segmentos adyacentes se desplazan junto con él – el bloque completo se hace más grande, en lugar de quitar tiempo al segmento siguiente.
segmentSettings – ajustes globales para segmentos
El parámetro opcional segmentSettings a nivel de todo el widget controla el comportamiento por defecto de todos los segmentos – p. ej., si los grupos están bloqueados por defecto o si se muestra la toolbar.
arcCustomCalendarWeek({
// ...
segmentSettings: {
lockGroups: true,
edgeMagnetism: true,
toolbar: true,
dayJump: {
threshold: time(22, 0),
startTime: time(7, 0)
}
},
timeEntries: [...]
})
📌 Vista general de los parámetros:
Parameter Typ Beschreibung lockGroupsBoolean true = Segmente werden standardmäßig gemeinsam verschoben (Standard: true)edgeMagnetismBoolean true = Beim Resize bleibt die gemeinsame Grenze angrenzender Segmente synchron (Standard: true)toolbarBoolean false = Toolbar ausblenden. Sonst immer sichtbar (Schloss + Auge bei createNew.item)dayJump.thresholdZeit Ab dieser Uhrzeit springt ein Segment beim Drag auf den nächsten Tag dayJump.startTimeZeit Startzeit am neuen Tag nach dem Sprung
⚠️ Prioridad: Los ajustes a nivel de timeEntry (segmentSettings dentro de una entrada) sobrescriben los segmentSettings globales. Los ajustes a nivel de segmento sobrescriben a su vez el nivel de entrada.
---
Con Custom Calendar Week llevas planificación estructurada y total flexibilidad a tu base de datos Ninox – adaptable de forma individual, intuitivo de usar y listo para tu día a día.
Happy Widgeting 🥳