إرسال نموذج مع نوع حقل كيان (صفحات، منتجات...)
في هذا المثال، نوضح كيفية إرسال نموذج يتضمن نوع حقل كيان، مثل الصفحات أو المنتجات، باستخدام واجهة برمجة التطبيقات OneEntry.
✅ هدف السيناريو:
- الحصول على تكوين النموذج من منصة OneEntry
- يقوم المستخدم باختيار أحد عناصر الكيان
- إرسال البيانات المجمعة إلى واجهة برمجة التطبيقات OneEntry.
✅ ما تحتاجه:
- عنوان URL صالح للمشروع (PROJECT_URL) ورمز التطبيق (APP_TOKEN) للمصادقة مع واجهة برمجة التطبيقات OneEntry.
- نموذج مُعد مسبقًا في OneEntry مع علامة (مثل، كيان) وحقول تتضمن واحدة من نوع "كيان".
- حقول نموذج مُعدة مسبقًا تتضمن واحدة من نوع "كيان".
📌 مهم:
- هذه الأمثلة لا تتضمن معالجة الأخطاء.
- يمكنك إدارة الأخطاء باستخدام كتلة try-catch أو من خلال استخدام بناء مثل await Promise.catch((error) => error).
📚 انظر في الوثائق:
📦 مرجع SDK:
جربها مباشرة
قم بتشغيل هذه الطريقة بشكل تفاعلي في صندوق JS SDK — قم بتوصيل عنوان URL لمشروعك ورمز التطبيق في الزيارة الأولى، ثم افتح:
- إرسال نموذج مع نوع حقل كيان (صفحات، منتجات...) — في هذا المثال، نوضح كيفية إرسال نموذج يتضمن نوع حقل كيان، مثل الصفحات أو المنتجات، باستخدام واجهة برمجة التطبيقات OneEntry.
السيناريو
1. استيراد defineOneEntry من SDK وتعريف PROJECT_URL و APP_TOKEN
مثال:
import { defineOneEntry } from 'oneentry';
const PROJECT_URL = 'your-project-url';
const APP_TOKEN = 'your-app-token';
2. إنشاء عميل API باستخدام defineOneEntry()
مثال:
const { Forms, FormData } = defineOneEntry(PROJECT_URL, {
token: APP_TOKEN,
});
3. الحصول على النموذج باستخدام 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. الحصول على إعدادات إضافية لإرسال النموذج
مثال:
const moduleFormConfig = form.moduleFormConfigs?.[0];
if (!moduleFormConfig) {
setErrorMsg('Form has no moduleFormConfigs');
setStatus('error');
return;
}
النتيجة:
{
"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. الحصول على بيانات الحقول من نموذج الواجهة الأمامية — اختر خيار كيان واحد لكل حقل من نوع الكيان (اختيار المستخدم من القائمة المعروضة)
مثال:
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] || ''),
}));
النتيجة:
[
{
"marker": "entity",
"type": "entity",
"value": [
"p-2-7"
]
}
]
6. نشر FormsData باستخدام FormData.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);
النتيجة:
{
"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": ""
}
المثال النهائي
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;