Enviando un formulario con un tipo de campo de entidad (páginas, productos...)
En este ejemplo, demostramos cómo enviar un formulario que incluye un tipo de campo de entidad, como páginas o productos, utilizando la API de OneEntry.
✅ Propósito del escenario:
- Obtener la configuración del formulario desde la Plataforma OneEntry
- El usuario selecciona uno de los elementos de la entidad
- Enviar los datos recopilados a la API de OneEntry.
✅ Lo que necesitas:
- Un PROJECT_URL y APP_TOKEN válidos para la autenticación con la API de OneEntry.
- Un formulario preconfigurado en OneEntry con un marcador (por ejemplo, entidad) y campos que incluyan uno de tipo "entidad".
- Campos de formulario preconfigurados que incluyan uno de tipo "entidad".
📌 Importante:
- Estos ejemplos no incluyen manejo de errores.
- Puedes gestionar errores utilizando un bloque try-catch o empleando una construcción como await Promise.catch((error) => error).
📚 Ver en la documentación:
📦 Referencia del SDK:
Pruébalo en vivo
Ejecuta este método de forma interactiva en el sandbox del JS SDK — conecta tu Project URL y App Token en la primera visita, luego abre:
- Enviando un formulario con un tipo de campo de entidad (páginas, productos...) — En este ejemplo, demostramos cómo enviar un formulario que incluye un tipo de campo de entidad, como páginas o productos, utilizando la API de OneEntry.
Escenario
1. Importar defineOneEntry desde el SDK y definir PROJECT_URL y APP_TOKEN
Ejemplo:
import { defineOneEntry } from 'oneentry';
const PROJECT_URL = 'your-project-url';
const APP_TOKEN = 'your-app-token';
2. Crear un cliente API con defineOneEntry()
Ejemplo:
const { Forms, FormData } = defineOneEntry(PROJECT_URL, {
token: APP_TOKEN,
});
3. Obtener el formulario con Forms.getFormByMarker()
Ejemplo:
useEffect(() => {
Forms.getFormByMarker('entity').then((data: any) => {
setForm(data);
const initial: Record<string, string> = {};
data?.attributes?.forEach((a: any) => { initial[a.marker] = ''; });
setValues(initial);
console.log('Form Entity ', data);
}).catch(console.error);
}, []);
if (!form) return <div>Loading...</div>;
const sortedFields = [...(form.attributes || [])].sort(
(a: any, b: any) => a.position - b.position,
);
const handleSubmit = async (e: any) => {
e.preventDefault();
if (!form) return;
setStatus('loading');
4. Obtener configuraciones adicionales para el envío del formulario
Ejemplo:
const moduleFormConfig = form.moduleFormConfigs?.[0];
if (!moduleFormConfig) {
setErrorMsg('Form has no moduleFormConfigs');
setStatus('error');
return;
}
Resultado:
{
"id": 1,
"moduleIdentifier": "content",
"isGlobal": false,
"isClosed": false,
"viewOnlyUserData": false,
"commentOnlyUserData": false,
"entityIdentifiers": [
{
"id": "services",
"isNested": false
}
],
"ratingCalculation": "average",
"allowHalfRatings": null,
"maxRatingScale": null,
"isAnonymous": null,
"allowRerating": null,
"isRating": null
}
5. Obtener datos de campos del formulario frontend — seleccionar una opción de entidad por cada campo de tipo entidad (la selección del usuario del select renderizado)
Ejemplo:
const fieldsData = sortedFields
.filter((f: any) => values[f.marker])
.map((f: any) => ({
marker: f.marker,
type: f.type,
value: prepareValue(f.type, values[f.marker] || ''),
}));
Resultado:
[
{
"marker": "entity",
"type": "entity",
"value": [
"p-2-7"
]
}
]
6. Publicar FormsData con FormData.postFormsData()
Ejemplo:
const response = await FormData.postFormsData({
formIdentifier: 'entity',
formData: fieldsData,
formModuleConfigId: moduleFormConfig.id,
moduleEntityIdentifier: moduleFormConfig.entityIdentifiers?.[0]?.id || '',
replayTo: null,
status: 'sent',
}).catch((e: any) => e);
Resultado:
{
"formData": {
"formIdentifier": "entity",
"time": "2026-06-06T10:21:42.166Z",
"formData": [
{
"marker": "entity",
"type": "entity",
"value": [
"p-2-7"
]
}
],
"entityIdentifier": "services",
"fingerprint": "UQ_zhfcsr_mpdtr691jq7d",
"isUserAdmin": false,
"formModuleId": 1,
"userIdentifier": null,
"parentId": null,
"id": 174
},
"actionMessage": ""
}
Ejemplo final
import React from 'react';
// Note: React is a sandbox global — in your project use named imports from 'react'
const { useState, useEffect } = React;
// 1. Import defineOneEntry from SDK and define PROJECT_URL and APP_TOKEN
import { defineOneEntry } from 'oneentry';
const PROJECT_URL = 'your-project-url';
const APP_TOKEN = 'your-app-token';
// 2. Creating an API client with [defineOneEntry()](/docs/index/#Installation)
const { Forms, FormData } = defineOneEntry(PROJECT_URL, {
token: APP_TOKEN,
});
// Prepare value for API submission by field type.
function prepareValue(type: string, value: string) {
if (type === 'text') return [{ plainValue: value }];
if (type === 'list' || type === 'radioButton') return [value];
if (type === 'entity') return [/^\d+$/.test(value) ? Number(value) : value];
return value;
}
const EntityForm = () => {
const [form, setForm] = useState<any>(null);
const [values, setValues] = useState<Record<string, string>>({});
const [status, setStatus] = useState<'idle' | 'loading' | 'success' | 'error'>('idle');
const [errorMsg, setErrorMsg] = useState('');
// 3. Get form with [Forms.getFormByMarker()](/docs/forms/getFormByMarker)
useEffect(() => {
Forms.getFormByMarker('entity').then((data: any) => {
setForm(data);
const initial: Record<string, string> = {};
data?.attributes?.forEach((a: any) => { initial[a.marker] = ''; });
setValues(initial);
console.log('Form Entity ', data);
}).catch(console.error);
}, []);
if (!form) return <div>Loading...</div>;
const sortedFields = [...(form.attributes || [])].sort(
(a: any, b: any) => a.position - b.position,
);
const handleSubmit = async (e: any) => {
e.preventDefault();
if (!form) return;
setStatus('loading');
// 4. Get additional settings for the form submission
const moduleFormConfig = form.moduleFormConfigs?.[0];
if (!moduleFormConfig) {
setErrorMsg('Form has no moduleFormConfigs');
setStatus('error');
return;
}
// 5. Get fields data from the frontend form — pick one entity option per entity-typed field (the user's selection from the rendered select)
const fieldsData = sortedFields
.filter((f: any) => values[f.marker])
.map((f: any) => ({
marker: f.marker,
type: f.type,
value: prepareValue(f.type, values[f.marker] || ''),
}));
// 6. post FormsData with [FormData.postFormsData()](/docs/forms-data/postFormsData)
const response = await FormData.postFormsData({
formIdentifier: 'entity',
formData: fieldsData,
formModuleConfigId: moduleFormConfig.id,
moduleEntityIdentifier: moduleFormConfig.entityIdentifiers?.[0]?.id || '',
replayTo: null,
status: 'sent',
}).catch((e: any) => e);
if (response?.statusCode >= 400) {
setErrorMsg(response.message || 'Submission failed');
setStatus('error');
} else {
setStatus('success');
console.log('Submit response: ', response);
}
};
return (
<form onSubmit={handleSubmit}>
<h2>{form.localizeInfos?.title || 'Entity Form'}</h2>
{sortedFields.map((field: any) => {
const label = field.localizeInfos?.title || field.marker;
const value = values[field.marker] || '';
const required = !!field.validators?.requiredValidator?.strict;
const placeholder = field.additionalFields?.placeholder?.value || '';
const onChange = (val: string) =>
setValues((prev) => ({ ...prev, [field.marker]: val }));
if (field.type === 'entity') {
const options = field.listTitles || [];
if (options.length > 0) {
return (
<div key={field.marker}>
<label htmlFor={field.marker}>{label}</label>
<select
id={field.marker}
value={value}
required={required}
onChange={(e: { target: { value: string; }; }) => onChange(e.target.value)}
>
<option value="">— Select —</option>
{options.map((opt: any) => {
// For entity fields, listTitles[].value is an object ({ id, depth, ... }),
// so use its primitive `id` for the key/value (a page id like 25 or product like "p-1-123").
const optValue = opt.value && typeof opt.value === 'object' ? opt.value.id : opt.value;
return (
<option key={optValue} value={optValue}>{opt.title}</option>
);
})}
</select>
</div>
);
}
return (
<div key={field.marker}>
<label htmlFor={field.marker}>{label}</label>
<input
id={field.marker}
type="text"
value={value}
placeholder={placeholder || 'Page id (e.g. 25) or product (e.g. p-1-123)'}
required={required}
onChange={(e: { target: { value: string; }; }) => onChange(e.target.value)}
/>
</div>
);
}
return (
<div key={field.marker}>
<label htmlFor={field.marker}>{label}</label>
<input
id={field.marker}
type="text"
value={value}
placeholder={placeholder}
required={required}
onChange={(e: { target: { value: string; }; }) => onChange(e.target.value)}
/>
</div>
);
})}
{status === 'error' && <p role="alert">{errorMsg}</p>}
{status === 'success' && <p role="status">Form submitted successfully!</p>}
<button type="submit" disabled={status === 'loading'}>
{status === 'loading' ? 'Submitting...' : 'Submit'}
</button>
</form>
);
};
export default EntityForm;