Premium Widgets
Custom Upload
Custom Upload
AI Defaults
- uniqueId
- Required, `"upload-" + Nr`.
- image.tableId
- Required – target table for new records. Ninox-handler only — core emits semantic file payload.
- image.fieldId
- The text field for Base64 data. Platform-dependent (Web vs. App may differ). Adapter-only.
- Persistence
- Core emits `upload` with `{ name, src, width?, height?, original? }` where `original` is an optional Base64 string (PDF source when `convertSettings.originalFile` is set). Ninox handler builds `update` / `create` / `popup` from `ui.data.image.*` and resolves `originalFile.fieldId` / `recordId` from `convertSettings`. React: `onUpload(payload)`.
- container
- `height: "500px"`, `width: "100%"`.
- multiupload
- Default `false`, set `true` for multiple files at once.
- capture
- Default `false`, set `true` to open camera directly.
- clipboard
- Optional `clipboard: true` — pegar con Ctrl/Cmd+V o al hacer clic, cuando haya archivos en el portapapeles.
- drag
- Default **on** for the empty dropzone (hover + drop). Custom `container.value` stays opt-in via `drag: true` or `{ enabled, label?, target?, targetId? }`. `drag: false` opts out.
- image.format / image.quality
- Optional encode — `format: "jpeg"` | `"webp"` | `"original"`, `quality: 0–1` (default `0.8` when format is set). Offline en el navegador; útil para muchas fotos en informes PDF.
- logs
- Optional `logs: true` — tamaños de codificación + vista previa de la imagen (consola + preview debajo del widget).
- Two Base64 fields
- Some setups need separate fields for Web and App – check your schema.
Custom Upload
Con `arcCustomUpload` puedes subir imágenes y archivos directamente en Ninox — de uno en uno o en selección múltiple. Al hacerlo se crea automáticamente un registro propio por cada archivo, incluyendo el contenido en Base64, el nombre del archivo e información adicional opcional.El widget resuelve una de las mayores limitaciones de Ninox: el incómodo upload múltiple. En lugar de complicados workarounds, ahora se abre con un clic el explorador de archivos o la cámara — y esto en cualquier interfaz: ya sea en un dashboard, mediante un Custom Button o dentro de un layout propio.
Las imágenes subidas se guardan primero como texto Base64 en un campo de tu elección y desde ahí se pueden:
- mostrar directamente con el widget <a href="/documentation/images">Custom Image</a>,
- convertir mediante script en un campo de imagen de Ninox (recomendado),
- o simplemente guardar como archivo.
También en dispositivos móviles el widget es ideal: puedes fotografiar con la cámara o seleccionar y subir varias imágenes de la galería, a tu elección. Esto ahorra al usuario muchos clics y simplifica notablemente el mantenimiento de datos.
⚠️ Nota: En la app de MacOS así como en la app de Android actualmente la función de multi-upload no funciona. Aquí las restricciones vienen dadas por parte de Ninox.
Formatos compatibles
- Imágenes: JPG, PNG, SVG
- Documentos: PDF
- Tablas y datos: CSV, XML, XLS, XLSX
Nota: Los archivos PNG y SVG se convierten actualmente de forma automática a JPG. Para un procesamiento posterior de alta calidad, recomendamos convertir los datos Base64 a archivos reales lo antes posible y guardarlos como campo de archivo en Ninox.
HEIC/HEIF (fotos de iPhone)
Los iPhones modernos guardan las fotos por defecto en formato HEIC. Aquí aplica:
| Método de subida | ¿Funciona? | Explicación |
|---|---|---|
| Directamente desde iPhone/iPad | ✅ Sí | iOS convierte automáticamente a JPEG |
| Escritorio → Safari (macOS) | ✅ Sí | Safari admite HEIC de forma nativa |
| Escritorio → Chrome/Firefox/Edge | ❌ No | Estos navegadores no pueden decodificar HEIC |
💡 Consejo para subidas desde escritorio: Si los usuarios transfieren fotos del iPhone al escritorio con regularidad y quieren subirlas desde ahí, recomendamos el siguiente ajuste en el iPhone:
> Ajustes → Cámara → Formatos → Máxima compatibilidad
Así las fotos se guardan directamente como JPEG y son compatibles con todos los navegadores.
Código de aplicación
Aquí un ejemplo sencillo de cómo puedes usar arcCustomUpload en una función — por ejemplo integrado en una <a href="https://www.arc-rider.de/documentation/custom-table">tabla</a> (embedded:true) o de forma independiente en un formulario de Ninox en un campo de fórmula (embedded:false):
let current := this;
arcCustomUpload({
uniqueId: "my-Files-" + Nr,
embedded: true,
capture: false,
multiupload: true,
container: {
icon: "",
label: "Files Upload",
height: "500px",
width: "100%",
value: ""
},
image: {
tableId: "B",
fieldId: if ninoxApp() = "web" then
fieldId("Bilder", "base64_web")
else
fieldId("Bilder", "base64_app")
end,
width: 1500,
height: 1500,
widthFieldId: "J",
heightFieldId: "K"
},
filename: {
tableId: "B",
fieldId: fieldId("Bilder", "Dateiname")
},
convertSettings: {
type: ""
},
changeFieldValues: [{
fieldId: "B",
value: number(current.Nr)
}, {
fieldId: "E",
value: 12
}],
setNewRecordId: [{
recordId: current.Nr,
fieldId: fieldId(current.Nr, "triggerField_saveForBrowser")
}]
})
Parámetros
uniqueId
Tipo: text Obligatorio: sí
uniqueId lo asignas de forma individual y debería ser único. El sentido es: si creas varios uploads con distintos settings en tu interfaz, evitas que se sobrescriban los estilos.
📌 Atención: Si dos widgets de upload en la misma página usan el mismo uniqueId, esto puede provocar errores (p. ej. los uploads se sobrescriben o no se cargan correctamente).
uniqueId: "my-Image-" + Nr,
embedded
Tipo: boolean Default: false
Con el parámetro embedded determinas si el widget de upload debe mostrarse integrado en un elemento existente (p. ej. un Custom Layout, Custom Button, etc.) — o si aparece como elemento independiente en la interfaz.
true→ El widget se adapta al contenedor circundante (p. ej. en marcos de layout fijos).false→ El widget se representa libremente en la interfaz de Ninox (p. ej. como elemento independiente).
💡 Nota: Si usas embedded: true, asegúrate de que el elemento circundante (p. ej. un bloque de layout) tenga una altura/anchura definida. El campo de upload adopta automáticamente estas medidas.
capture
Tipo: boolean Default: false
Con el parámetro capture controlas si el widget abre directamente la cámara en dispositivos móviles o si el usuario puede seleccionar un archivo manualmente.
true→ En smartphones compatibles, al hacer clic se abre directamente la app de cámara.false→ Se abre como es habitual el explorador de archivos o la galería de fotos.
💡 Nota: Esta función solo funciona en dispositivos móviles (Apple) y en combinación con determinados navegadores. En escritorio el parámetro se ignora.
capture: "", // Default: false
capture: false,
multiupload
Tipo: boolean Default: false
Con multiupload puedes definir si se pueden subir varios archivos a la vez.
true→ El usuario puede seleccionar varios archivos en el diálogo de archivos (p. ej. varias imágenes de la galería).false→ Solo se puede subir un archivo por proceso de upload.
💡 Consejo: Especialmente práctico en formularios donde se deben subir varias fotos o documentos a la vez y guardarse como registros individuales.
logs
Tipo: boolean o { enabled: true } Default: false
Con logs: true el widget escribe estadísticas de codificación/redimensionado en la consola del navegador (DevTools) y muestra debajo del upload una vista previa del resultado — útil para calibrar image.format e image.quality:
- Nombre de archivo y MIME
- Píxeles antes → después
- Tamaño antes → después y ahorro en %
logs: true
Línea de ejemplo:
[arcCustomUpload:…] IMG_1234.JPG image/jpeg → jpeg q=0.7 | 4032×3024→1200×900 | 3.2 MB → 180 KB (−94%)
clipboard
Tipo: boolean Default: false
Con clipboard: true se pueden pegar archivos desde el portapapeles — con Ctrl+V / Cmd+V o haciendo clic en el área de upload, cuando se han copiado archivos en el Finder/Explorador.
- Aparece un aviso tipo badge en cuanto el portapapeles contiene archivos (no solo texto).
- Si el portapapeles solo contiene texto, un clic abre el diálogo de archivos como es habitual.
- Varios widgets de upload en una página: solo reacciona el widget con el foco.
clipboard: true
drag
Tipo: boolean u object Default: activo en la dropzone vacía estándar; desactivado en cuanto se establece container.value
La dropzone vacía (icono + etiqueta, sin container.value) acepta archivos mediante arrastrar y soltar y muestra feedback de hover y drop. Con un container.value propio, drag sigue siendo opt-in.
drag: false desactiva el drop en todas partes. drag: true o un objeto lo activa también para Custom Layouts:
drag: true
// oder mit Optionen: drag: { enabled: true, label: "Datei hier ablegen", target: "area", // "area" | "first-child" | "layout" targetId: "meine-zeile-id" // optional: externe Drop-Zone per DOM-ID }</code></pre>
targetComportamiento "area"Overlay sobre el área de upload "first-child"Estándar con container.value "layout"Primer arcCustomLayout dentro del widget
Con targetId se puede usar como drop zone una fila o área externa (p. ej. una fila de tabla) — el ID se busca primero en la etiqueta de upload, y si no, en todo el documento.
showLoadingPopup
Tipo: boolean Default: false
Con showLoadingPopup puedes mostrar un popup de carga durante el upload. Esto es especialmente útil en:
- archivos de imagen grandes
- conexiones a internet lentas
- multi-uploads con muchos archivos
El popup bloquea la interfaz e informa al usuario de que el upload sigue en curso. Se cierra automáticamente en cuanto se han subido todos los archivos.
showLoadingPopup: true,
💡 Consejo: Combina showLoadingPopup: true con multiupload: true para una mejor UX en uploads masivos.
En la app de Ninox para iOS el popup aparece de forma fiable en cuanto empieza el upload (el widget espera a que se muestre el modal antes de procesar los archivos).
Bloque: container{}
Tipo: object Opcional
El bloque container define el aspecto y comportamiento del campo de upload. Aquí puedes, por ejemplo, definir el tamaño o mostrar un texto propio en el área de upload.
Si no pasas ningún valor, se muestra un layout estándar con icono de upload y el texto «Seleccionar archivo».
container: {
icon: "",
label: "Upload Image",
height: "100%",
value: "wert"
},
Parámetros posibles
<figure><table><tbody><tr><th>Feld
</th><th>Typ
</th><th>Beschreibung
</th></tr><tr><td>label
</td><td>text
</td><td>Etiqueta (texto) en el campo de upload. Se muestra en el centro. Se muestra debajo del icono.
</td></tr><tr><td>value
</td><td>widget text
</td><td>Con value puedes diseñar tu propio diseño completamente personalizado del upload. Todo lo que indiques en value sobrescribe el diseño estándar existente. Aquí puedes usar, por ejemplo, un simple <a href="/documentation/buttons">Custom Button</a> o diseñar un <a href="/documentation/custom-layout">Custom Layout propio</a> que se adapte a tu UI. Este parámetro es opcional y por supuesto no es obligatorio rellenarlo.
</td></tr><tr><td>height
</td><td>text
</td><td>Altura del campo de upload, p. ej. "80px" o "100%".
</td></tr><tr><td>width
</td><td>text
</td><td>Anchura del campo de upload, p. ej. "100%", "300px" o "auto".
</td></tr><tr><td>icon
</td><td>widget
</td><td>Con <a href="https://www.arc-rider.de/documentation/custom-icon">arcCustomIcon</a> se puede definir un icono individual.
</td></tr></tbody></table></figure>💡 Consejo: Evita textos demasiado largos en label, ya que el widget trabaja centrado y de lo contrario la legibilidad se ve afectada. Lo ideal son 1–2 palabras o un símbolo con una explicación corta.
Bloque: image{}
Tipo: object Campo obligatorio
En el bloque image defines dónde debe guardarse la imagen subida. La imagen se escribe automáticamente en un campo de texto Base64 en la tabla indicada. Opcionalmente también puedes registrar por separado el ancho y el alto de la imagen.
<figure><table><tbody><tr><th>Feld
</th><th>Typ
</th><th>Beschreibung
</th></tr><tr><td>tableId
</td><td>text
</td><td>Tabla de destino en la que se guarda la imagen como registro.
</td></tr><tr><td>fieldId
</td><td>text
</td><td>ID del campo de texto en el que se escribe el contenido de la imagen en Base64.
</td></tr><tr><td>widthFieldId
</td><td>text
</td><td>*(opcional)* ID del campo para el ancho de imagen guardado (en píxeles). Crea para ello un campo numérico de Ninox.
</td></tr><tr><td>heightFieldId
</td><td>text
</td><td>*(opcional)* ID del campo para el alto de imagen guardado (en píxeles). Crea para ello un campo numérico de Ninox.
</td></tr><tr><td>width / height
</td><td>text
</td><td>*(opcional)* El width / height dentro del bloque image{} indica el ancho / alto en píxeles de tu imagen en el que quieres guardarla.
</td></tr><tr><td>format
</td><td>text
</td><td>*(opcional)* Formato de salida tras el upload (offline en el navegador). "jpeg" / "jpg", "webp" u "original" (Default: omitir / "original" = comportamiento anterior, MIME de entrada). Con "jpeg"/"webp" la imagen siempre se vuelve a codificar — incluso si ya es más pequeña que width/height. El nombre de archivo recibe la extensión correspondiente (.jpg / .webp).
</td></tr><tr><td>quality
</td><td>number
</td><td>*(opcional)* Calidad de compresión de 0 a 1 (solo con format: "jpeg" o "webp"). Default 0.8 si format está establecido y falta quality. No aplica con "original".
</td></tr></tbody></table></figure>
Los pasos de codificación se ejecutan offline, directamente en el widget (cámara y galería por igual). No se necesita ningún servicio en la nube. Nota: con format: "jpeg" se pierde la transparencia PNG (a propósito, para fotos/informes PDF).
image: {
tableId: "B",
fieldId: if ninoxApp() = "web" then
fieldId("Bilder", "base64_web")
else
fieldId("Bilder", "base64_app")
end,
width: 1500,
height: 1500,
widthFieldId: "J",
heightFieldId: "K"
},
Ejemplo obra / informes PDF (muchas fotos, mantener el PDF por email en unos 5–10 MB): la cámara (capture: true) y el upload múltiple desde galería (multiupload: true) usan la misma ruta de codificación. Para Ninox/importFile es preferible JPEG frente a WebP:
image: {
tableId: "B",
fieldId: if ninoxApp() = "web" then
fieldId("Bilder", "base64_web")
else
fieldId("Bilder", "base64_app")
end,
width: 1200,
height: 1200,
format: "jpeg",
quality: 0.7,
widthFieldId: "J",
heightFieldId: "K"
},
Con muchísimas fotos por informe (60+) prueba width/height a 1000 y/o quality a 0.6. El tamaño final del PDF también depende del generador de informes — calíbralo con un informe real tras la configuración.
Nota importante de rendimiento
💡 Consejo de UI/UX: Los datos Base64 pueden llegar a ser muy grandes — especialmente con imágenes de alta resolución. Por eso recomendamos el siguiente flujo de trabajo:
- Configura un trigger de cambio en el campo Base64.
- Transfiere la imagen Base64 con
importFile() a un campo de imagen real. - Vacía después el campo Base64, para ahorrar espacio de almacenamiento.
Este trigger lo configuras así:
Datei := importFile(Nr, base64, Dateiname);
shareURL := shareFile(Datei);
base64:=null;
Así los tiempos de carga y el tamaño de la base de datos se mantienen razonables — y aun así puedes seguir trabajando directamente con los datos de imagen.
🧠 Importante: Ninox trata los triggers de forma distinta en la app y en el navegador. Para que tu flujo de trabajo funcione de forma fiable en todas las plataformas, usa dos campos base64 separados (cada uno con opciones de almacenamiento distintas) — uno para Web, otro para la app:
- App -> Asignación por registro en el navegador
- Web -> Asignación por registro en el servidor
✅ Así te asegura que el upload se procesa automáticamente en ambos entornos.
filename
Tipo: object Opcional
En el bloque filename puedes indicar en qué campo se debe guardar el nombre del archivo. Esto resulta útil si más adelante quieres filtrar por archivos o mostrarlos en listas.
<figure><table><tbody><tr><th>Feld
</th><th>Typ
</th><th>Beschreibung
</th></tr><tr><td>tableId
</td><td>text
</td><td>Tabla de destino en la que se guarda el registro
</td></tr><tr><td>fieldId
</td><td>text
</td><td>ID del campo en el que se escribe el nombre del archivo
</td></tr></tbody></table></figure>💡 Consejo: Si más adelante sigues trabajando con importFile() o quieres volver a recuperar el archivo (p. ej. en una galería o lista de descargas), el nombre del archivo suele ser necesario — por eso es mejor guardarlo siempre.
changeFieldValues
Tipo: array of objects Opcional
Con changeFieldValues puedes rellenar automáticamente campos adicionales en el registro de upload recién creado — p. ej. con una referencia a la tabla actual, un tipo fijo o un valor de estado. Cada entrada contiene:
<figure><table><tbody><tr><th>Feld
</th><th>Typ
</th><th>Beschreibung
</th></tr><tr><td>fieldId
</td><td>text
</td><td>El campo del nuevo registro que se debe establecer
</td></tr><tr><td>value
</td><td>any
</td><td>El valor que se escribe en el campo
</td></tr></tbody></table></figure> <pre><code class="language-javascript">changeFieldValues: [{ fieldId: "B", value: number(current.Nr) }, { fieldId: "E", value: 10 }]</code></pre>
setNewRecordId
Tipo: array of objects Opcional
Con setNewRecordId puedes, tras el upload, enlazar el registro recién creado (p. ej. la imagen) directamente en un registro existente — por ejemplo en un campo de referencia del formulario actual.
Esto resulta especialmente útil cuando necesitas:
- una vinculación 1:1 con una imagen o documento,
- el elemento de upload no está integrado en la tabla de destino,
- o quieres establecer uploads de forma específica fuera de
changeFieldValues.
<figure><table><tbody><tr><th>Feld
</th><th>Typ
</th><th>Beschreibung
</th></tr><tr><td>recordId
</td><td>text
</td><td>El valor del ID del registro existente en el que se debe enlazar
</td></tr><tr><td>fieldId
</td><td>text
</td><td>El campo de referencia que se rellenará con el nuevo registro de upload
</td></tr></tbody></table></figure>## Servicio adicional de conversión
La conversión de PDF mediante convertSettings no forma parte del upload estándar, sino que es un servicio externo proporcionado por arcRider.
Dado que cada conversión genera costes de servidor, su uso tiene coste. La facturación se realiza por proceso de conversión.
💬 Para el uso de este servicio creamos planes de precios individuales — según el volumen esperado y los requisitos concretos. Ponte en contacto con nosotros si quieres activar el servicio de conversión de PDF o tienes preguntas sobre las condiciones. (<a href="mailto:office@arc-rider.com">office@arc-rider.com</a>)
convertSettings
Tipo: object Opcional – solo relevante en archivos PDF
Si subes archivos PDF, con convertSettings puedes definir que se conviertan automáticamente en archivos JPG / PNG / SVG — p. ej. para planos técnicos o PDFs de formularios que deban poder mostrarse en Ninox.
<figure><table><tbody><tr><th>Feld
</th><th>Typ
</th><th>Beschreibung
</th></tr><tr><td>fileType
</td><td>text
</td><td>Formato de destino de la conversión. Actualmente compatible: "jpg"
</td></tr><tr><td>apiKey
</td><td>text
</td><td>Tu clave API personal para el servicio de conversión de PDF (solicítala a arcRider)
</td></tr><tr><td>width
</td><td>number
</td><td>Ancho de destino en píxeles (si no se establece dpi)
</td></tr><tr><td>height
</td><td>number
</td><td>Alto de destino en píxeles (si no se establece dpi)
</td></tr><tr><td>dpi
</td><td>number
</td><td>Resolución de la conversión en dpi (puntos por pulgada)
</td></tr><tr><td>originalFile
</td><td>object
</td><td>Opcional: campo para guardar el archivo PDF original como Base64
</td></tr></tbody></table></figure>## ✅ Conclusión
Con arcCustomUpload diseñas procesos de upload en Ninox de forma intuitiva, eficiente y flexible — ya sea en escritorio o en móvil. Mediante una parametrización específica controlas la presentación, las tablas de destino, las automatizaciones e incluso la conversión de PDFs.
Si quieres integrar uploads complejos en tu sistema o necesitas ayuda con la configuración, contáctanos sin compromiso — te ayudamos con la configuración óptima.