🤔چطور میتوانم یک آیتم از نوع Number Filed را تبدیل به Numeric Spinner کنم؟
نیازمندیها
-
دو دکمه در جلوی آیتم که روی هم قراربگیرند و برای کم و زیاد کردن مقدار استفاده شوند.
-
برای دکمهها +/- مقدار پیشفرض مقدار یک باشد و توسط کاربر قابل تنظیم باشد.
-
اگر آیتم دارای focus بود، با حرکت غلتک (scroll) ماوس، مقدار کم و زیاد شود.
-
برای غلتک، مقدار پیشفرض 10 باشد و توسط کاربر هم قابل تنظیم باشد.
-
امکان منفی شدن مقدار، توسط کاربر مشخص شود. در حالت پیشفرض مقدار منفی مجاز نیست.
-
اعداد ممکن است دارای جدا کننده (Grouping Separator) باشند.
به صورت پیشفرض برای این نوع آیتم type = text هست که میشود آن را به number تغییر داد تا دکمههای inc/dec نمایان شوند. اما من از این روش استفاده نمیکنم.
پیادهسازی
- بر روی آیتم مورد نظر (مثلا P7_ORDER_NO) کلیک کرده و برای Post Text آن، مقداری به دلخواه مینویسیم. من از * استفاده کردم. بدین ترتیب span این قسمت با کلاس «t-Form-itemText–post» فعال میشود. با استفاده از jQuery ، دکمهها را در این قسمت قرار میدهیم.
Advanced | Post Text: *
- برای قرارگرفتن کادر دور دکمهها Display as Block مربوط به آیتم را انتخاب میکنیم.
Appearance | Template Options | Item Post Text: Display as Block
- در قسمت JavaScript صفحه در Execute when Page Loads از متد Item_NumericSpinner استفاده میکنیم.

کد JS را میتوانیم در قسمت Function and Global Variable Declaration بنویسیم. من از فایل در قسمت static fileها استفاده میکنم ( لینک GitHub ).
/**
* ایجاد حالت +/- کردن به فیلد عددی
*
** type: number field
** برای قرارگرفتن دکمه > post text = *
*
*
* @param itemName > نام آیتم
* @param wheel_step > مقداری که با چرخ موس باید اضافه/کم شود
* @param ud_step > up-down مقداری که باید اضافه/کم شود
* @param negative > باشد false جلوگیری از مقدار منفی اگر مقدار
* @param groupingSymbol > کاراکتر جداکننده ارقام
*/
function Item_NumericSpinner(itemName, wheel_step = 10, ud_step = 1, negative = false, groupingSymbol = ',') {
let containter$ = $("#" + itemName + "_CONTAINER .t-Form-itemText--post");
let css_btn = { background: "none", border: "none", cursor: "pointer" };
let css_div = { display: "inline-flex", "flex-direction": "column", "vertical-align": "middle" };
let div$ = $('<div>').css(css_div);
let btnUp$ = $('<button>', { type: "button", text: '▲' }).css(css_btn);
let btnDown$ = $('<button>', { type: "button", text: '▼' }).css(css_btn);
div$.append(btnUp$);
div$.append(btnDown$);
containter$.html(div$);
//----------------------------------------------
let item$ = $("#" + itemName);
btnUp$.on("click", inc.bind(null,ud_step));
btnDown$.on("click", dec.bind(null,ud_step));
item$.on("wheel", function (e) {
e.preventDefault();
// آیا فوکوس دارد؟
if (document.activeElement.id !== itemName)
return;
let delta = e.originalEvent.deltaY;
if (delta < 0) {
inc(wheel_step);
} else {
dec(wheel_step);
}
});
function inc(step) {
let val = parseFloat(item$.val().replace(groupingSymbol, '')) || 0;
item$.val(val + step);
// apex.item(itemName).setValue(item$.val());
}
function dec(step) {
let val = parseFloat(item$.val().replace(groupingSymbol, '')) || 0;
val = val - step
if (negative == false & val < 0) val = 0;
item$.val(val);
// apex.item(itemName).setValue(item$.val());
}
}
🧐🧠خلاصه کارهایی که انجام دادم
- آیا میشود در قسمت Post Text از کد HTML استفاده کرد؟ بله
- از ChatGPT خواستم کد این کار را برایم ایجاد کند … که در نهایت خروجی آن شامل سه قسمت شد: کد دکمهها، CSS و کد JS.
- چرخهی تست، رفع اشکال، بازبینی، ایدهی جدید و …
- برای اینکه بتوانم از این کد به دفعات استفاده کنم، آن را تبدیل به function کردم.
- برای اینکه کاربر مجبور به استفاده از کد CSS و کد دکمهها نباشد، آن را در متد JS ادغام کردم.
- برای حذف تکرار، از nested function استفاده کردم (تابع تو در تو).
- چون این کد را برای Item استفاده کردم، برای دسته بندی بهتر، آن را در فایلی به نام site_Item.js نگهداری میکنم که در این فایل برای نام متدها از پیشوند Item استفاده کردم و خواهم کرد.
تمام فایلهای JS را در نهایت به فایل site.js تبدیل میکنم و در محیط production استفاده میکنم.