Ana içeriğe geç

Submitting a form with an entity field type (pages, products...)

In this example, we demonstrate how to submit a form that includes an entity field type, such as pages or products, using the OneEntry API.

✅ Purpose of the scenario:

  • Get form configuration from OneEntry Platform
  • User select one of the elements of the entity
  • Submit the collected data to an OneEntry API.

✅ What you need:

  • A valid PROJECT_URL and APP_TOKEN for authentication with the OneEntry API.
  • A pre-configured form in OneEntry with a marker (e.g., entity) and fields including one of type "entity".
  • A pre-configured form fields including one of type "entity".

📌 Important:

  • These examples do not include error handling.
  • You can manage errors using a try-catch block or by employing a construction like await Promise.catch((error) => error).

📚 See in documentation:

📦 SDK reference:

Try it live

Run this method interactively in the JS SDK sandbox — connect your Project URL and App Token on first visit, then open:

Scenario

1. Import defineOneEntry from SDK and define PROJECT_URL and APP_TOKEN

Example:

import { defineOneEntry } from 'oneentry';

const PROJECT_URL = 'your-project-url';
const APP_TOKEN = 'your-app-token';

2. Creating an API client with defineOneEntry()

Example:

const { Forms, FormData } = defineOneEntry(PROJECT_URL, {
token: APP_TOKEN,
});

3. Get form with Forms.getFormByMarker()

Example:

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

Example:

const moduleFormConfig = form.moduleFormConfigs?.[0];
if (!moduleFormConfig) {
setErrorMsg('Form has no moduleFormConfigs');
setStatus('error');
return;
}
Result:
{
"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. Get fields data from the frontend form — pick one entity option per entity-typed field (the user's selection from the rendered select)

Example:

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] || ''),
}));
Result:
[
{
"marker": "entity",
"type": "entity",
"value": [
"p-2-7"
]
}
]

6. post FormsData with FormData.postFormsData()

Example:

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);
Result:
{
"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": ""
}

Final example

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;