Saltar al contenido principal

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:

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;