panel_table (api/core/libraries/panel_table.php, בפריסה system/libraries/panel_table.php) היא טבלת הניהול הסטנדרטית: רכיב Vue שמצויר מהשרת, עם עימוד, חיפוש, סינון לפי עמודה, עריכה בתוך השורה, מיון בגרירה, פעולות לשורה ולקבוצה וייצוא ל-Excel. הדף הזה הוא הרפרנס לכל אפשרות. מדריך בנייה של פאנל שלם נמצא במדריך panel_table ובבניית פאנל ניהול.
השימוש: יוצרים אובייקט, מגדירים מאפיינים, וקוראים ל-get_html(). כל פעולה בטבלה (עימוד, חיפוש, מחיקה, עריכה, מיון, ייצוא) היא POST JSON לאותה כתובת של הדף, ש-get_html() מזהה לפי tbl_action.
$lstListManager = new panel_table("pgs");
$lstListManager->title = "עמודי תוכן";
$lstListManager->titles = [
["title" => "id", "field" => "id", "type" => "number"],
["title" => "noDelete", "field" => "noDelete", "editable" => true, "type" => "boolean"],
["title" => "כותרת", "field" => "title", "editable" => true, "editable_table" => "content"],
["title" => "URL", "func" => function($row){
$url = ROUTER::get_by_url("pages/" . $row["id"]);
return "<a target=\"_blank\" href=\"$url\">$url</a>";
}],
];
$lstListManager->query = DB::query("pages", null, "id DESC");
$lstListManager->btn_add_url = CONFIG::$admin_url . "/Pages/insert";
$lstListManager->order_manager = false;
$lstListManager->delete = function ($id) {
DB::delete("pages", ["id" => $id]);
ROUTER::remove_by_url("pages/" . $id);
};
$lstListManager->actions = function ($rows) {
return [
["title" => LANGS::get_word('EDIT'), "link" => "EDIT", "perms" => "edit", "target" => "inner",
"icon" => '<i class="fas fa-edit"></i>'],
];
};
return $lstListManager->get_html();
הארגומנט של הבנאי (tblID) חייב להיות ייחודי בדף ויציב בין ה-GET ל-POST, כי השרת מזהה בו את הבקשה (data["tblID"] == tblID). בלי ארגומנט משתמשים במונה סטטי, שתלוי בסדר יצירת הטבלאות בדף.
הבנאי#
| חתימה | הערה |
|---|---|
__construct($tblID = false) | tblID ריק מקבל ערך מהמונה הסטטי panel_table::$index. קורא את php://input ומפענח אותו ל-$this->data. קובע txt_add מהמילה _ADD_, direction מהפלטפורמה, ו-actions ל-closure שמחזיר [] |
הבנאי גם מחליט מראש על כמה דגלים:
- בנייד (
PAGE::is_mobile())actions_sideהופך ל-"right". realtime_trackingדולק כששירות השוקwizzonowפעיל.radar_trackingדולק כשהשירותkamaפעיל, ואזradar_api_keyנלקח מהשירות.ai_insert_enabledדולק אם הוגדרai_insert_default_promptוהשירותwizzoaiפעיל.
מאפיינים#
נתונים ושאילתה#
| מאפיין | ברירת מחדל | משמעות |
|---|---|---|
title | "" | כותרת הטבלה |
titles | [] | הגדרות העמודות. ראו "עמודות" |
query | false | אובייקט DB::query(...) או מחרוזת SQL. עם מחרוזת: אין מיון בגרירה, ו-DELETE ועריכה דורשים id בתוצאה |
rows_func | false | fn($qu, $results). הערך המוחזר נקבע ב-$this->rows ושורות אלה מוצגות לפני תוצאות ה-DB |
rows | false | השורות שנוספו על ידי rows_func |
searchFunc | null | fn($escapedQ): string. מקבל את מחרוזת החיפוש אחרי DB::escape ומחזיר תנאי SQL. בלעדיו החיפוש הוא LIKE על כל עמודות השאילתה |
limit | 50 | שורות בעמוד |
pgnm | 1 | מספר העמוד הנוכחי, נקרא מ-data.pgnm |
default_order | "" | ORDER BY ברירת מחדל, אחרי כל שאר המקורות (ראו "מיון") |
name | "report" | חלק משם קובץ ה-Excel |
more_data | [] | מידע נוסף שמוחזר ללקוח (בשימוש פנימי לתשובות פעולה) |
data | [] | גוף הבקשה (JSON מפוענח) |
כפתור הוספה ואלמנטים בראש הטבלה#
| מאפיין | ברירת מחדל | משמעות |
|---|---|---|
txt_add | המילה _ADD_ | טקסט כפתור ההוספה |
btn_add_url | "" | כתובת הוספה. כשהוגדרה, השרת שולח גם את הכותרת add_action: <btn_add_url> ומציב $_SERVER["HTTP_ADD_ACTION"] |
btn_add_url_target | "inner" | יעד הפתיחה (inner לפאנל פנימי, popup) |
head_html | [] | מערך מחרוזות HTML שמוצגות בסרגל העליון (כפתורים נוספים) |
intro | "" | HTML גולמי מעל הטבלה |
intro_card | true | האם intro עטוף בכרטיס .pt_intro. עם false הוא מוצג כמו שהוא |
additional_content | false | fn($tbl). התוצאה חוזרת בשדה additional_content של תשובת השורות ומפעילה את אירוע jQuery additionalcontent |
ai_insert_enabled | false | כפתור "צור עם AI" |
ai_insert_default_prompt | "" | הנחיית ברירת מחדל ליצירה עם AI |
excel_import_enabled | true | כפתור ייבוא מ-Excel |
בתוך intro עם intro_card אפשר להשתמש במחלקות העזר .pt_intro__head, .pt_intro__icon, .pt_intro__title, .pt_intro__text, .pt_intro__code, .pt_intro__chips, .pt_intro__actions.
הלקוח מציג ערכי תאים עם v-html. הפלט של func (ושל intro, head_html) חייב להיות מוצא באחריות המפתח (MISC::special_chars), אחרת זו פרצת XSS.
פעולות, הרשאות ומחיקה#
| מאפיין | ברירת מחדל | משמעות |
|---|---|---|
actions | closure שמחזיר [] | fn($row): array מחזיר את פעולות השורה. ראו "פעולות" |
group_actions | [] | פעולות לשורות מסומנות. ראו "פעולות קבוצה" |
actions_side | "left" | "left", "right", או מספר: אינדקס עמודה שמתחתיה מוצגות הפעולות (ב-Pages.php: 2) |
delete | NULL | fn($id, $row). מפעיל מחיקה: כפתור מחיקה בשורה ופעולת קבוצה, מותנים בהרשאה delete |
dblclick_url | NULL | כתובת שנפתחת בלחיצה כפולה על שורה (מתווספת פעולה "כניסה") |
line_class | NULL | fn($row). מחלקת CSS על שורה |
ignore_perms | false | מתעלם משדה perms של עמודות ופעולות. שבור, ראו אזהרה |
argtogetDelete | "" | לא בשימוש |
עם ignore_perms = true, get_actions לא מציב את המשתנה $ret, ו-array_map מקבל null וזורק TypeError (ממצא ADMIN-30). עד שיתוקן, אל תפעילו אותו על טבלה שיש לה actions או delete.
מיון בגרירה#
| מאפיין | ברירת מחדל | משמעות |
|---|---|---|
order_manager | true | מיון בגרירה. מכובה אוטומטית אם query אינו אובייקט DB::query, ואם המשתמש בחר מיון לפי עמודה |
order_manager_external_tbl | false | להחזיק את הסדר בטבלה חיצונית panel_table_order ולא בעמודת ord |
order_manager_external_key | "" | המפתח (type) של הטבלה בטבלת הסדר החיצונית |
order_success | false | callable שרץ אחרי שמירת סדר |
כשהוא דולק וללא טבלה חיצונית, init() מריץ DESCRIBE על הטבלה, ואם אין עמודה ord מריץ ALTER TABLE ... ADD ord INT NOT NULL (בשקט). כבו אותו (order_manager = false) בכל טבלה שלא מתכוונים לסדר, ובמיוחד בטבלאות גדולות.
מעקב בזמן אמת ורדאר#
| מאפיין | ברירת מחדל | משמעות |
|---|---|---|
realtime_tracking | לפי שירות wizzonow | מעקב עריכה בזמן אמת |
realtime_tracking_urls | [] | כתובות לעקוב אחריהן. מוסיפים עם realtime_tracking_add_url() |
realtime_key | false | מפתח מעקב |
radar_tracking | לפי שירות kama | חיבור לרדאר |
radar_url_func | null | fn($row): כתובת האתר של השורה, שמוצגת ברדאר (מחזיר נתיב, והטבלה מוסיפה / בתחילתו) |
radar_api_key | null | מפתח השירות |
direction | כיוון הפלטפורמה | rtl או ltr |
queryType, lines | לא בשימוש |
עמודות#
titles הוא מערך של מערכים. לכל עמודה:
| מפתח | משמעות |
|---|---|
title | כותרת העמודה (HTML) |
field | שם העמודה בשאילתה. בלעדיו העמודה מחושבת על ידי func |
type | סוג העמודה. ברירת מחדל "text". עמודה עם field == "id" מקבלת "id" |
func | fn($row, $title): מחזיר את הערך המוצג (HTML) |
link | מחרוזת או fn($row, $title): הופך את התא לקישור |
editable | true או fn($row, $title) שמחזיר true: עריכה בתוך הטבלה |
editable_table | "conf" או "content": איזו טבלה מעדכנים כשעורכים |
editable_field_table | שם טבלה אחרת (בלי CRM_) לעדכון לפי id |
editable_field_func | fn($row, $value, $title): שמירה מותאמת |
editable_success | fn($row, $value, $title) שרץ אחרי שמירה מוצלחת |
confirm | כותרת חלון אישור לפני שמירה בעריכה |
select_options | אפשרויות לעמודות select, multiselect, list: מערך [id => טקסט] |
filter_func | fn($fieldObj, $GetVal): string: תנאי SQL מותאם לסינון העמודה |
perms | הרשאה נדרשת לראות את העמודה (נבדקת ב-ADMIN::has_perms, אלא אם ignore_perms) |
classname | מחלקת CSS על תא העמודה |
style | style על תא העמודה |
עמודה שאינה מערך נזרקת. העמודות עוברות json_encode ללקוח, ולכן closures שבתוכן לא מגיעים אליו.
סוגי עמודה#
type | תצוגה | סינון | עריכה בתוך הטבלה |
|---|---|---|---|
id | המספר | שוויון (= (int)) | לא |
text (ברירת מחדל) | הערך | LIKE '%q%' | תיבת טקסט (Ctrl+Enter שומר) |
number | הערך | טווח from ו-to | שדה מספר |
boolean | הערך | בחירה | מתג |
select | התווית מתוך select_options | שוויון | רשימה |
multiselect | כמו select | IN (...) | לא |
list | ערכים מופרדים ב-", " | LIKE '%|id|%' | רשימה |
date | Y-m-d | טווח תאריכים | תאריך |
datetime | Y-m-d H:i | טווח תאריכים | datetime-local |
image | תמונה ממוזערת 70 על 70 | לא |
פרטים לפי סוג:
image: אם הערך מספרי וגדול מ-0 הוא id בטבלת storage והתמונה נבנית ב-STORAGE::get_url; אחרת הערך נחשב כתובת. מוצגת כ-<img class="big_pic">ב-70 על 70 פיקסלים עםobject-fit: cover.list: הערך נשמר בפורמט הרשימה של הליבה (|1||2|) ומפורק עםMISC::bgl_explode, ואז ממופה דרךselect_options. הערך המקורי (original_value) הוא מערך.dateו-datetime: ערך ריק או0000-...מוצג כריק.select: ערך שאין לו מפתח ב-select_optionsמוצג כמו שהוא.
עמודת select, multiselect או list בלי select_options מקבלת אפשרויות מ-SELECT * FROM (<query>) tbl GROUP BY tbl.<field>, והתווית היא תוצאת func אם קיימת. זה שאילתה על כל הטבלה בכל הצגה. בטבלה גדולה, או כשיש רק rows_func ואין query, הגדירו select_options בעצמכם.
רק classname ו-style של העמודה מוחלים על התא בלקוח. מפתח class של העמודה, וגם class ברמת התא שהשרת מחזיר, לא נצרכים.
ערכי תא שהשרת מחזיר#
כל תא בתשובה הוא אובייקט {value, original_value, editable, link, select_options, class, style, field}. בכל שורה נוספים __actions_arr (הפעולות), __id, __class (מ-line_class) ו-__radar_url (כש-radar_tracking ו-radar_url_func). תווי בקרה מוסרים מערכי התאים, ונשארים רק התווים U+0020-U+007E ו-U+00A0-U+FFFF, כלומר ירידות שורה, טאבים ואימוג'י מחוץ ל-BMP נמחקים.
סינון וחיפוש#
הסינון מגיע ב-data.filters[field]. השדה חייב להתאים לעמודה בהגדרות, והערכים --all-- ו-"" מדלגים. הערך --none-- מסנן שורות ריקות: `field` IN ('', '0', NULL) (שים לב ש-NULL לעולם לא מתאים בתוך IN, כך שרק '' ו-'0' נמצאים בפועל).
| סוג עמודה | תנאי |
|---|---|
עם filter_func | התנאי שחוזר מ-filter_func($fieldObj, $GetVal) |
id | = (int) |
text | LIKE '%q%', ועוד ORDER BY IF(field = 'q', 1, 0) DESC שמקדים התאמה מדויקת |
date, datetime | מערך של שני ערכים לא ריקים: >= ראשון AND < שני + יום |
number | אובייקט {from, to} עם (float): >= ו-<= |
select | = 'ערך מוצא' |
multiselect | IN (...). ערכים לא-מספריים מוקפים במרכאות בלי escape |
list | LIKE '%|(int)|%' |
| ערך מספרי בסוג אחר | = |
| אחר | LIKE |
חיפוש חופשי (data.q): אם הוגדר searchFunc, התנאי הוא searchFunc(DB::escape(q)). אחרת LIKE על כל עמודה שבשורה הראשונה של התוצאה (SELECT * FROM (...) LIMIT 0,1).
$lstListManager->searchFunc = function ($q) {
// $q כבר עבר DB::escape
return "(name LIKE '%" . $q . "%' OR email LIKE '%" . $q . "%')";
};
ערכי סינון multiselect שאינם מספרים נכנסים ל-SQL במרכאות אך ללא DB::escape. כל עוד לא תוקן, הימנעו מעמודות multiselect בטבלה שנגישה למי שאינם מנהלים מהימנים, והעדיפו select או filter_func שמבצע escape.
השאילתה הסופית שנבנית:
SELECT * [, ordtbl.item_ord AS tbl_ord]
FROM (<sql>) AS tbl
[LEFT JOIN CRM_panel_table_order ordtbl ON ordtbl.type = '<key>' AND ordtbl.item_id = tbl.id]
WHERE true <search> AND (<filters>)
ORDER BY ...
LIMIT (pgnm-1)*limit, limit
מיון#
סדר המקורות לקביעת ORDER BY, מהחזק לחלש:
data.ordByו-data.ordDir(המשתמש לחץ על כותרת עמודה). מכבה אתorder_managerלאותה בקשה. הערכים נכנסים ל-SQL ללא ולידציה.order_manager:tbl_ord ASCעם טבלה חיצונית, אחרתord ASC.order_byשל אובייקט ה-DB::query(הארגומנט השלישי שלDB::query).default_order.
ordBy ו-ordDir מגיעים מהלקוח ומשורשרים ל-ORDER BY. הפאנל נגיש רק למנהלים מחוברים, אבל אל תעתיקו את הדפוס לקוד שחשוף למשתמשי אתר.סידור בגרירה#
order(בקשה):OrderPage()ממספר מחדש אתordל-1 עד n לכל השאילתה, ואז קובע אתordשל העמוד הנוכחי לפיdata.order_ids(הזזה של(pgnm-1)*limit). מחזירfalseעל שאילתת מחרוזת. התשובה{"success": true|false}, ואחריה נקראorder_success.- עם
order_manager_external_tbl: הסדר נשמר בטבלהpanel_table_order(type,item_id,item_ord) עםINSERT ... ON DUPLICATE KEY UPDATE, כך שאפשר לסדר טבלה שאין לך שליטה בסכמה שלה.
פעולות שורה#
הערך המוחזר מ-actions הוא מערך של פעולות:
| מפתח | משמעות |
|---|---|
title | טקסט הכפתור. גם מפתח ה-v-for בלקוח, לכן כותרות שונות בין פעולות |
icon | HTML של אייקון (<i class="fas fa-edit"></i>) |
link | כתובת לפתיחה. "EDIT" הופך ל-btn_add_url עם action_type של edit |
target | "inner" (ברירת מחדל, adminMovePage), "popup" (פאנל צד), "_blank" (לשונית) |
func | fn($row): פעולה בשרת. הפעולה נשלחת כ-POST, והערך המוחזר מוצג ללקוח |
alert | טקסט אישור. מציג חלון אישור לפני ההפעלה |
perms | הרשאה נדרשת |
class, style | מחלקה וסגנון על הכפתור |
action_type | delete או edit. מזוהה אוטומטית ב-detect_action_type, ומשפיע על תפריט ההקשר |
token | נוצר אוטומטית: MISC::encode(json_encode(action + id)) |
כללי הקישור:
- קישור יחסי (לא
http,https,ftp) שאין בו id מקבל/<id>בסוף, או&id=או?id=אם כבר יש בו?. - קישור שכבר מסתיים ב-
/Nאו?id=Nמקבל את ה-id של השורה במקום. dblclick_urlמוסיף פעולה{title: "כניסה", link, target: "inner", class: "btn_enter", action_type: "edit"}.- לחיצה על
funcשולחתtbl_action: "action"עםidו-token. השרת מחשב מחדש את פעולות השורה ומתאים לפי הטוקן וה-id לפני הפעלה, כך שלא ניתן להפעיל פעולה שלא הוצגה. - תוצאת
func(more_data.alert) מוצגת כ-HTML, ואם היא מתחילה ב-<scriptהיא מורצת. - לחיצת גלגלת על קישור פותחת לשונית חדשה.
מחיקה: כש-delete מוגדר וההרשאה delete קיימת, מתווספת אוטומטית פעולה עם func => fn($rows) => $del($rows["id"], $rows), alert של ARE_YOU_SURE, class: "delete_btn" ו-action_type: "delete".
פעולות קבוצה#
group_actions הן פעולות על שורות מסומנות. כל פעולה: title, icon, class, style, alert, ו-func שהחתימה שלה fn($row, $action) ומורצת פעם לכל שורה מסומנת (השרת שולף כל שורה עם WHERE id = N). הערך המוחזר נשלח ללקוח כ-more_data.alert. הפעולות מזוהות ב-token שנוצר כמו בפעולות שורה. כש-delete מוגדר ויש הרשאה, מתווספת פעולת קבוצה של מחיקה.
$lstListManager->group_actions[] = [
"title" => "הפעל",
"class" => "btn_activate",
"func" => function ($row, $action) {
DB::update("cron_tasks")->set_var("is_active", 1)->Update((int)$row["id"]);
},
];
עריכה בתוך הטבלה#
עריכה היא POST עם tbl_action = "editable_field", id, editable_field_name, editable_value. השרת מוצא את השורה (מהשאילתה, או מ-rows_func כשאין שאילתה) ואם אינה קיימת מחזיר "row_not_in_list".
העמודה ניתנת לעריכה אם editable === true, או editable הוא callable שמחזיר true, או שהוגדר editable_field_table, או editable_field_func. אחרת התשובה false. ערך של עמודת list (מערך או אובייקט) מומר ל-|1||2| עם MISC::bgl_implode.
דרכי השמירה, לפי סדר העדיפות:
editable_field_table:DB::update(table)->set_var(field, value)->Update(id), ואזeditable_success.editable_field_func($row, $value, $title).- שאילתת
DB::query:DB::update($query->table)->set_var(field, value, "conf"|"content"). טבלת היעד היאeditable_table("conf"או"content"), וכשהעמודה קיימת רק ב-<table>_contentהשרת עובר אוטומטית ל-content. אחר כךeditable_success. - אחרת:
false.
התשובה היא true או false.
["title" => "שפה", "field" => "lang_id", "type" => "select",
"select_options" => [1 => "עברית", 2 => "English"],
"editable_field_func" => function ($row, $value, $title) {
DB::update("ui_langs")->set_var("lang_id", (int)$value)->Update((int)$row["id"]);
return true;
}],
הקוד שלמעלה מדגים את החתימה בלבד. טבלאות ועמודות בדוגמה הן לצורך המחשה.
ייצוא ל-Excel#
הבקשה tbl_action = "xls" קוראת ל-xls(): קובץ xlsx (PhpSpreadsheet), מימין לשמאל, שורת כותרות עם רקע FF0850a2 וגופן לבן, גליון בשם Simple, כל התאים מחרוזות והתגיות מוסרות. שם הקובץ <name>-d-m-Y-H-i.xlsx (עם filename*=UTF-8'' לפי RFC 5987), set_time_limit(0) ו-memory_limit -1, ואז exit. data.limit מספרי מגביל ל-LIMIT n, אחרת אין הגבלה.
כפתור הייצוא מוסתר בלקוח לפי has_perms("export") (ב-index.tpl), אבל xls בשרת לא בודק הרשאה. מי שיש לו גישה לפאנל יכול לשלוח את הבקשה ישירות. אם הנתונים רגישים, בדקו הרשאה בקוד הפאנל.
פרוטוקול הבקשות#
get_html() קורא ל-init(), ואז:
- אם המשתמש מנהל והכותרת
AI-Table-Discoveryקיימת: מחזירoutput_table_json()(תיאור הטבלה לסוכני AI) ויוצא. - אם יש POST עם
tbl_actionו-data["tblID"] == tblID: מטפל בפעולה ועונהContent-Type: application/json. - אחרת מצייר את
assets/panel_table_vue/index.tpl.
tbl_action | מה קורה |
|---|---|
get_lines, search | מחזיר שורות |
order | {"success": ...} ו-order_success |
xls | ייצוא |
DELETE | דורש delete, data.id והרשאת delete (או ignore_perms). שולף את השורה ב-WHERE id = N, קורא ל-delete($id, $row) ומחזיר שורות |
group_action | LinesFuncs(): מריץ פעולת קבוצה על checkgroup |
כל ערך אחר (editable_field, action) | do_actions($tbl_action) |
תשובת שורות:
{
"more_data": {},
"lines": [],
"paging": {},
"order_manager": true,
"action_result": null,
"additional_content": "..."
}
הקידוד: JSON_THROW_ON_ERROR | JSON_UNESCAPED_UNICODE | JSON_INVALID_UTF8_SUBSTITUTE. additional_content מופיע רק כש-additional_content מוגדר.
פלט הגילוי של AI#
output_table_json() מחזיר: tblID, title, table, base_query (עד 1000 תווים), columns (title, field, type, editable, ו-select_options או select_options_dynamic), limit, default_order, order_manager, btn_add_url, has_delete, group_actions (רק הכותרות).
מתודות ציבוריות#
| חתימה | החזרה | הערה |
|---|---|---|
static load_assets() | מוסיף את קבצי ה-CSS וה-JS של panel_table_vue, ה-datepicker, ה-bottom sheet וייבוא ה-Excel | |
init() | מכין את הטבלה: pgnm, כיבוי order_manager כשאין DB::query, יצירת עמודת ord, סינון עמודות לפי perms, השלמת type, הוספת פעולת מחיקה, ושליחת הכותרת add_action. נקרא אוטומטית מ-get_html() | |
get_html() | string או JSON (ו-die) | נקודת הכניסה. ראו "פרוטוקול הבקשות" |
output_table_json() | מדפיס את תיאור הטבלה ל-AI | |
realtime_tracking_add_url($url) | מוסיף כתובת ל-realtime_tracking_urls | |
main_table_name() | string | query->table, או הטבלה מ-FROM הראשון של שאילתת מחרוזת (בלי הקידומת), או "" |
fill_lines() | מערך שורות | מריץ את השאילתה עם LIMIT, מוסיף את שורות rows_func, ובונה את התאים ואת הפעולות |
xls() | מייצא ו-exit | |
get_sql_string() | string או false | מחרוזת השאילתה, או BuildQuery() של אובייקט, אחרת false |
bulid_basic_query() | string | בונה את ה-SQL הסופי (סינון, חיפוש, מיון). שם המתודה כתוב כך בקוד, עם הטעות |
paging() | מערך | {pages: [{page, text, active?}], total_results, page, total_pages, limit}. חלון של 10 עמודים וכפתורים <<, <, ..., >, >>. שאילתת הספירה נגזרת בביטוי רגולרי מהשאילתה, ועם rows_func בלבד total_results = 0 |
LinesFuncs() | מריץ פעולת קבוצה על כל שורה ב-checkgroup | |
OrderPage() | bool | שמירת סדר העמוד. false על שאילתת מחרוזת |
OrderItem($direction, $id) | "UP" או "DOWN": מחליף ord עם השכן | |
do_actions($action) | עריכה בתוך הטבלה ופעולות שורה | |
get_actions($rows) | מערך | פעולות השורה אחרי סינון הרשאות, עם טוקנים ופעולת מחיקה |
detect_action_type($action) | "delete", "edit" או null | delete אם המחלקה מכילה delete, edit אם הקישור מכיל btn_add_url |
מלכודות#
- שורות מ-
rows_funcמוצגות לפני תוצאות ה-DB ולא נספרות ב-paging(). rows_funcבליquery: איןDESCRIBE, אין מיון בגרירה, ואין עימוד אמיתי, וצריךselect_optionsמפורשים.DELETEועריכה שולפים את השורה בתת-שאילתהWHERE id = N, ולכן שאילתת מחרוזת חייבת להחזיר עמודהid.- אין תמיכה בכמה טבלאות באותו דף בלי
tblIDשונה לכל אחת.
ראו גם#
- panel_table: מדריך שימוש
- בניית פאנל ניהול
- טפסים ו-FormInput_*: הטפסים שנפתחים מכפתורי ההוספה והעריכה
- ממשק JSON של הניהול
- רפרנס הניהול
- רפרנס DB