חוקי טופס
חוק טופס הוא התנהגות בצד הלקוח, שרצה בדפדפן בזמן שמשתמש צופה או עורך רשומה בדף כרטיס. כל חוק הוא זוג: conditions[] — מתי, ו‑actions[] — מה קורה ולאיזה שדה.
מה חוקי טופס אינם
Section titled “מה חוקי טופס אינם”| התכונה | חוקי טופס | טריגרים |
|---|---|---|
| איפה רצים | בדפדפן, בזמן שהמשתמש עורך | בשרת, בשמירה או בתזמון |
| היקף | טופס אחד בדף אחד | הטבלה כולה |
| אכיפה | UX בלבד — כתיבה ב‑API עוקפת אותם לגמרי | צד שרת |
| שימוש טיפוסי | הצגה מותנית, חובה מותנית, מילוי אוטומטי, נעילה אחרי סגירה | התראות, יצירת רשומות, סנכרון בין טבלאות |
Get-Form-Rules
Section titled “Get-Form-Rules”| הפרמטר | טיפוס | חובה | המשמעות |
|---|---|---|---|
pageId |
String | ✔ | הדף |
formId |
String | הטופס. ברירת מחדל — הטופס הראשון בדף | |
siteId |
String | האתר |
מחזיר { rules: [ { name, conditions[], actions[] } ] }.
זו תמיד הקריאה הראשונה — כדי לדעת מה יש ולשמור עותק. החוקים יושבים ב‑HTML של הדף, ב‑attribute data-rules של הטופס, ולכן כל כתיבה שלהם יוצרת גרסת דף — זו דרך השחזור האמיתית. בגרסת השרת של 25.08.2026 כל מה ש‑Get-Form-Rules מחזיר היה ניתן לשלוח חזרה כמות שהוא (round‑trip מלא, אומת 2026-08-25), אבל זה תלוי ב‑enum האופרטורים שהשרת מגדיר באותו רגע. ראו את פירוט האופרטורים למטה ואת הערת ההיסטוריה הבאה.
מבנה החוק
Section titled “מבנה החוק”{ "name": "סיבת ביטול (חובה)", "conditions": [ { "field": "StatusId", "equesition": "equalTo", "value": "zrP1MSVBoq", "visibleVal": "בוטל", "condOr": false } ], "actions": [ { "field": "CancelReason", "action": "required", "value": "" } ]}| המפתח | חובה | המשמעות |
|---|---|---|
name |
✔ | הזהות של החוק. edit ו‑delete מאתרים לפיו |
conditions |
✔ | מערך תנאים. מותר שיהיה ריק — אבל הוא חייב להישלח |
actions |
✔ | מערך פעולות |
name הוא המזהה — לא מספר סידורי
Section titled “name הוא המזהה — לא מספר סידורי”אין ruleId. הכלי אוכף ייחודיות: add עם שם קיים מחזיר Error: Rule name already exists, ו‑edit/delete עם שם שלא קיים — Error: Rule not found. השתמשו בשמות עבריים ייחודיים ותיאוריים — הם גם מה שהמיישם הבא יקרא.
| המפתח | טיפוס | חובה | המשמעות |
|---|---|---|---|
field |
String | ✔ | השדה שמשווים |
equesition |
Enum | ✔ | האופרטור. השם משובש בשרת — כך כותבים אותו |
value |
String | Number | Boolean | ✔ | ערך ההשוואה. מותר מחרוזת ריקה, אבל המפתח חייב להישלח |
visibleVal |
String | תיאור לתצוגה בלבד | |
condOr |
Boolean | true מכניס את התנאי לקבוצת ה‑OR |
האופרטורים — שמונת הערכים הקנוניים:
equalTo · notEqualTo · greaterThan · lessThan · greaterThanOrEqualTo · lessThanOrEqualTo · containedIn · notContainedIn. לצידם קיימים בנתונים שמורים שני ערכי legacy: equealTo (איות ישן של equalTo) ו‑empty (בזמן ריצה — לשדות תאריך בלבד).
ערכי התנאי לפי סוג השדה:
| סוג השדה | value |
|---|---|
| Pointer | ה‑objectId (10 תווים). ל‑Pointer של _User מותר גם "currentUser" |
| Boolean | "checked" / "unchecked" |
| Date | "today", "year ago", YYYY-MM-DD, מספר ימים, וגם "beginning of this month", "30 days period", "end of this year", "year ahead" |
| String / Number | הערך עצמו |
AND ו‑OR
Section titled “AND ו‑OR”- תנאים בלי
condOr— כולם חייבים להתקיים. - תנאים עם
condOr: true— מרכיבים קבוצת OR אחת: מספיק שאחד מהם מתקיים. - תנאי OR בודד מתנהג כמו AND — הוא נבדק ככל תנאי אחר (תיאור הכלי אומר “no effect”; בפועל, בדפדפן, חוק עם תנאי
condOr: trueיחיד רץ רק כשהתנאי מתקיים). קבוצת OR אמיתית דורשת לפחות שניים. - שילוב: כל תנאי ה‑AND חייבים להתקיים, וגם לפחות אחד מתנאי ה‑OR.
שמונה הפעולות
Section titled “שמונה הפעולות”action |
value |
מה קורה |
|---|---|---|
hidden |
"" |
השדה נעלם מהטופס |
required |
"" |
חובה למלא לפני שמירה |
readonly |
"" |
נעול לעריכה |
fixed-value |
ערך קבוע | מציב ערך: literal · objectId ל‑Pointer · "currentUser" · מילת מפתח של תאריך · "checked"/"unchecked" לתיבת סימון |
dynamic-value |
מסלול שדה | מעתיק חי משדה אחר, כולל קפיצה אחת דרך Pointer: "AccountId.Email" |
formula-value |
— | ערך מחושב — לא ניתן לכתיבה דרך הכלים (ראו בהמשך) |
show-message |
טקסט ההודעה | מציג הודעה למשתמש (חלון קופץ; פעם אחת לכל טקסט בטעינת הדף) |
value-from-url |
(לא בשימוש) | ממלא את השדה מפרמטר ב‑query string ששמו הוא שם השדה — ?Website=… ממלא את Website; ה‑value לא נקרא |
בסכימה החיה, רק action הוא חובה בתוך אובייקט הפעולה; field ו‑value אופציונליים. פעולה שאין לה שדה — show-message — מקבלת אותו בכל זאת ברוב הדוגמאות, וזה לא מזיק. שם שדה שלא קיים בטופס מתקבל בשקט ולא עושה דבר.
dynamic-value — קפיצה אחת בלבד
Section titled “dynamic-value — קפיצה אחת בלבד”המסלול הוא דו‑חלקי: Pointer.Field — למשל AccountId.Email או BrandId.Name.
שימו לב שזה שונה מהמסלול התלת‑חלקי של טבלאות תצוגה ודוחות (AccountId.Accounts.Name). אותו רעיון, שתי דקדוקים.
יותר מקפיצה אחת אינו נתמך (מאומת): הריצה קוראת רק את שני החלקים הראשונים, כך ש‑AccountId.OwnerId.name מעתיק את ה‑objectId של AccountId.OwnerId — לא את השם.
formula-value — לא ניתן לכתיבה דרך הכלים
Section titled “formula-value — לא ניתן לכתיבה דרך הכלים”fixed-value על תיבת סימון
Section titled “fixed-value על תיבת סימון”הריצה מבצעת checked = (value === "checked"): "checked" מסמן, כל ערך אחר — כולל "checkbox" שמופיע בהוראות השרת — מבטל את הסימון. ובתנאי: "checked" / "unchecked".
חוק בלי תנאים רץ תמיד
Section titled “חוק בלי תנאים רץ תמיד”"conditions": [] הוא הניב המקובל לשיקוף קבוע — “תמיד תעתיק את המייל של הלקוח לשדה הזה”.
Edit-Form-Rules — הדרך המועדפת
Section titled “Edit-Form-Rules — הדרך המועדפת”מוסיף, עורך או מוחק חוק בודד.
| הפרמטר | טיפוס | חובה | המשמעות |
|---|---|---|---|
pageId |
String | ✔ | הדף |
action |
Enum | ✔ | add · edit · delete |
rule |
Object | ✔ | החוק. name, conditions ו‑actions — כולם נדרשים |
formId |
String | הטופס. ברירת מחדל — הראשון | |
siteId |
String | האתר |
// הוספה{ "pageId": "<pageId>", "action": "add", "rule": { "name": "סיבת ביטול (חובה)", "conditions": [ { "field": "StatusId", "equesition": "equalTo", "value": "zrP1MSVBoq", "visibleVal": "בוטל" } ], "actions": [ { "field": "CancelReason", "action": "required", "value": "" } ] } }
// עריכה — התנאים והפעולות מחליפים לגמרי את של החוק הקיים באותו שם{ "pageId": "<pageId>", "action": "edit", "rule": { "name": "סיבת ביטול (חובה)", "conditions": [ … ], "actions": [ … ] } }
// מחיקה — רק השם משנה, אבל המערכים חייבים להישלח{ "pageId": "<pageId>", "action": "delete", "rule": { "name": "סיבת ביטול (חובה)", "conditions": [], "actions": [] } }Set-Form-Rules — דורס את הכול
Section titled “Set-Form-Rules — דורס את הכול”| הפרמטר | טיפוס | חובה | המשמעות |
|---|---|---|---|
pageId |
String | ✔ | הדף |
rules |
Array<Object> | ✔ | מערכת החוקים המלאה |
formId |
String | הטופס | |
siteId |
String | האתר |
מתי בכל זאת: בניית מערכת חוקים מאפס בדף חדש, או שכתוב יזום ומלא. בכל מצב אחר — Edit-Form-Rules.
הזרימה הבטוחה היחידה:
1. backup = Get-Form-Rules(pageId) שומרים את ה-JSON בצד2. newRules = backup.rules ± השינויים ממזגים, לא מחברים מהזיכרון3. Set-Form-Rules(pageId, rules: newRules)4. Get-Form-Rules(pageId) סופרים: הכמות = הבסיס ± השינוי| המצב | הכלי |
|---|---|
| הוספת חוק אחד | Edit-Form-Rules (add) |
| שינוי חוק אחד | Edit-Form-Rules (edit) |
| מחיקת חוק אחד | Edit-Form-Rules (delete) |
| מערכת חוקים מאפס בדף חדש | Set-Form-Rules |
| שכתוב מלא ומכוון | Set-Form-Rules — אחרי גיבוי |
דפוסים
Section titled “דפוסים”הזוג הסתרה + חובה
Section titled “הזוג הסתרה + חובה”הקומפוזיציה הנפוצה ביותר, ותמיד שני חוקים על אותו שדה:
[ { "name": "סיבת ביטול (הסתרה)", "conditions": [ { "field": "StatusId", "equesition": "notEqualTo", "value": "zrP1MSVBoq", "visibleVal": "בוטל" } ], "actions": [ { "field": "CancelReason", "action": "hidden", "value": "" } ] },
{ "name": "סיבת ביטול (חובה)", "conditions": [ { "field": "StatusId", "equesition": "equalTo", "value": "zrP1MSVBoq", "visibleVal": "בוטל" } ], "actions": [ { "field": "CancelReason", "action": "required", "value": "" } ] }]השדה מוסתר כל עוד הסטטוס אינו “בוטל”, וברגע שהוא הופך לבוטל — הוא מופיע וגם נדרש.
שיקוף פרטים מהלקוח
Section titled “שיקוף פרטים מהלקוח”{ "name": "שיקוף פרטי לקוח", "conditions": [], "actions": [ { "field": "Email", "action": "dynamic-value", "value": "AccountId.Email" }, { "field": "Phone", "action": "dynamic-value", "value": "AccountId.PhoneNumber" }, { "field": "Address", "action": "dynamic-value", "value": "AccountId.Address" } ] }נעילה בסטטוסים סופיים
Section titled “נעילה בסטטוסים סופיים”{ "name": "סטטוסים סופיים - קריאה בלבד", "conditions": [ { "field": "StatusId", "equesition": "equalTo", "value": "<completedId>", "visibleVal": "הושלם", "condOr": true }, { "field": "StatusId", "equesition": "equalTo", "value": "<cancelledId>", "visibleVal": "בוטל", "condOr": true } ], "actions": [ { "field": "Name", "action": "readonly", "value": "" }, { "field": "TypeId", "action": "readonly", "value": "" }, { "field": "Total", "action": "readonly", "value": "" } ] }חובה לקבוצת ערכים
Section titled “חובה לקבוצת ערכים”{ "name": "מיקום פגישה - פגישות חיצוניות", "conditions": [ { "field": "MeetingType", "equesition": "containedIn", "value": ["<externalId>", "<clientOfficeId>", "<restaurantId>"], "visibleVal": "פגישות חיצוניות" } ], "actions": [ { "field": "Location", "action": "required", "value": "" } ] }אחראי ברירת מחדל
Section titled “אחראי ברירת מחדל”{ "name": "אחראי ברירת מחדל", "conditions": [], "actions": [ { "field": "OwnerId", "action": "fixed-value", "value": "currentUser" } ] }זה גם התנאי המקדים לסינון ברמת שורה: מנגנון שמסנן רשומות לפי OwnerId שובר כשהשדה ריק.
קישור שממלא שדות מראש
Section titled “קישור שממלא שדות מראש”{ "name": "מקור הליד מה-URL", "conditions": [], "actions": [ { "field": "LeadSourceId", "action": "value-from-url", "value": "" } ] }הפרמטר נקרא בשם השדה: …/Lead?status=new&LeadSourceId=<objectId>. ה‑value אינו נקרא.
מה חוקי טופס לא יודעים לעשות
Section titled “מה חוקי טופס לא יודעים לעשות”| הבקשה | למה לא / מה במקום |
|---|---|
| לסנן את האפשרויות ברשימה נפתחת לפי שדה אחר | אין פעולה כזו. המנגנון הוא subclassDepend ב‑Edit-Page |
| לאכוף שלמות נתונים מול כתיבה ב‑API | צד לקוח בלבד. טריגרים או CLP |
| ליצור או לעדכן רשומה אחרת, לשלוח הודעה | טריגרים |
| התנהגות שונה לפי תפקיד המשתמש | אין תנאי תפקיד — התנאים קוראים רק ערכי שדות בטופס (מאומת בקוד הריצה). הפתרון המעשי: allowedRoles ברמת הדף, או דף נפרד לכל קהל |
- קריאה חוזרת:
Get-Form-Rules(pageId)— החוק קיים, התנאים והפעולות תואמים, וכמות החוקים = הבסיס ± השינוי שלכם. הספירה היא מה שתופס דריסה בשוגג. - בדיקת התנהגות בדפדפן. החוקים רצים רק שם, ואין להם יומן צד שרת. פותחים את הדף, רענון קשיח (Ctrl+F5) — הגדרות החוקים נטענות עם הדף — ואז משנים את שדה התנאי ורואים את הפעולה נכנסת ויוצאת.
Get-Form-Rulesמוכיח אחסון, לא התנהגות. בלי בדיקה בדפדפן החוק אינו מאומת.
כשהחוק לא עובד — סדר הבדיקות
Section titled “כשהחוק לא עובד — סדר הבדיקות”| הבדיקה | מה מחפשים |
|---|---|
| הדף הנכון? | שולחן עבודה מול Mobile-* — לכל אחד חוקים משלו |
ה‑formId הנכון? |
בדף עם יותר מטופס אחד, ברירת המחדל היא הראשון |
| רענון קשיח? | Ctrl+F5. הגדרות החוקים נטענות עם הדף |
| ערך התנאי | objectId ולא תווית |
condOr בודד |
תנאי OR יחיד נבדק כמו AND — הוא לא “מתבטל” |
| חוק אחר על אותו שדה | החוקים רצים לפי סדר המערך: קודם מבוטלות הפעולות של החוקים שתנאיהם לא מתקיימים, ואז מופעלים החוקים שמתקיימים — החוק המאוחר גובר (מאומת: שני fixed-value ללא תנאי על אותו שדה → הערך של האחרון). עדיף תנאים שסותרים זה את זה מלכתחילה |
| ציפייה שהחוק ירוץ על כתיבת API | הוא לא. לעולם |
- עריכת דפים ואלמנטים — השדות שהחוקים פועלים עליהם, ו‑
subclassDepend - כלי טריגרים ואוטומציות — כשהדרישה היא אכיפה בשרת
- תפקידים, הרשאות טבלה וחבילות — כשהדרישה היא הרשאה
- אתרים ודפים — קריאה — למצוא את
pageIdהנכון - כלי נתונים — להוציא את ה‑
objectIdשל ערכי ה‑lookup - אינדקס הכלים המלא