Now.js Framework Documentation
Special Elements (อิลิเมนต์พิเศษ)
Special Elements (อิลิเมนต์พิเศษ)
เอกสารสำหรับ form elements พิเศษ: ColorElementFactory, RangeElementFactory, TagsElementFactory, MaskElementFactory และ TextareaElementFactory
📋 สารบัญ
- ภาพรวม
- ColorElementFactory
- RangeElementFactory
- TagsElementFactory
- MaskElementFactory
- TextareaElementFactory
- แนวทางปฏิบัติที่ดี
ภาพรวม
Special elements มอบ UI ที่ปรับปรุงสำหรับ input types เฉพาะที่ต้องการมากกว่าการจัดการ text หรือ number พื้นฐาน
| Element | data-element | คำอธิบาย |
|---|---|---|
| ColorElementFactory | color |
Color picker พร้อม palette |
| RangeElementFactory | range |
Single/dual range slider |
| TagsElementFactory | tags |
Tags/chips input พร้อม autocomplete |
| MaskElementFactory | mask |
Input masking (โทรศัพท์, วันที่, ฯลฯ) |
| TextareaElementFactory | textarea |
Auto-resize textarea |
ColorElementFactory
ColorElementFactory สร้าง custom color picker พร้อม predefined palette และ hex input
การใช้งานพื้นฐาน
<input type="color"
data-element="color"
name="theme_color"
value="#007bff">HTML Attributes
| Attribute | ประเภท | ค่าเริ่มต้น | คำอธิบาย |
|---|---|---|---|
data-element |
string | - | ตั้งค่าเป็น color |
value |
string | #000000 |
สีเริ่มต้น (hex) |
disabled |
boolean | false |
ปิดการใช้งาน picker |
readonly |
boolean | false |
โหมดอ่านอย่างเดียว |
จานสีเริ่มต้น
const COLOR_PALETTE = [
'#FF5722', '#F44336', '#E91E63', '#9C27B0',
'#673AB7', '#3F51B5', '#2196F3', '#03A9F4',
'#00BCD4', '#009688', '#4CAF50', '#8BC34A',
'#CDDC39', '#FFEB3B', '#FFC107', '#FF9800',
// ... and more standard colors
'#FFFFFF', '#000000'
];JavaScript API
const instance = ElementManager.getInstance(colorInput);
// รับสีปัจจุบัน
const color = instance.getColor(); // '#007bff'
// ตั้งค่าสี
instance.setColor('#ff5722');
// เปิด/ปิด picker
instance.open();
instance.close();
instance.toggle();
// ปิด/เปิดการใช้งาน
instance.setDisabled(true);
instance.setReadonly(true);ฟีเจอร์
- Color Palette: คลิกสีที่กำหนดไว้
- Hex Input: พิมพ์ค่า hex กำหนดเอง
- Preview: แสดงตัวอย่างสีในปุ่ม
- Copy/Paste: Ctrl+C คัดลอก, Ctrl+V วาง
- Contrast Text: สีตัวอักษรบนปุ่มปรับเองให้อ่านออกเสมอ
เหตุการณ์
colorInput.addEventListener('change', (e) => {
console.log('Selected color:', e.target.value);
});RangeElementFactory
RangeElementFactory สร้าง range sliders พร้อม UX ที่ดีกว่า native range inputs รองรับ single และ dual range modes
การใช้งานพื้นฐาน
<!-- Single range slider -->
<input type="range"
data-element="range"
min="0"
max="100"
value="50"
name="volume">
<!-- Dual range slider (min-max) -->
<input type="range"
data-element="range"
min="0"
max="1000"
data-value="200-800"
data-dual="true"
name="price_range">HTML Attributes
| Attribute | ประเภท | ค่าเริ่มต้น | คำอธิบาย |
|---|---|---|---|
data-element |
string | - | ตั้งค่าเป็น range |
min |
number | 0 |
ค่าขั้นต่ำ |
max |
number | 100 |
ค่าสูงสุด |
step |
number | 1 |
ค่าเพิ่ม/ลด |
data-dual |
boolean | false |
เปิด dual handles |
data-show-value |
boolean | true |
แสดง value label |
data-format |
string | - | รูปแบบค่า (เช่น {value}%) |
value |
string | - | ค่าเดี่ยว หรือ "min-max" สำหรับ dual |
disabled |
boolean | false |
ปิดการใช้งาน slider |
readonly |
boolean | false |
โหมดอ่านอย่างเดียว |
Range เดี่ยว
<input type="range"
data-element="range"
min="0"
max="100"
step="5"
value="75"
data-format="{value}%"
name="opacity">Range คู่ (ต่ำสุด-สูงสุด)
<input type="range"
data-element="range"
min="0"
max="10000"
step="100"
data-value="2000-8000"
data-dual="true"
data-format="฿{value}"
name="budget">JavaScript API
const instance = ElementManager.getInstance(rangeInput);
// รับค่า
const value = instance.getValue();
// Single: 75
// Dual: {min: 2000, max: 8000}
// ตั้งค่า
instance.setValue(80); // Single
instance.setValue({min: 1000, max: 5000}); // Dual
// อัพเดท constraints
instance.setMin(10);
instance.setMax(200);
instance.setStep(10);
// ปิด/เปิดการใช้งาน
instance.setDisabled(true);
instance.setReadonly(true);การใช้คีย์บอร์ด
| ปุ่ม | การทำงาน |
|---|---|
← / ↓ |
ลดลงทีละ step |
→ / ↑ |
เพิ่มขึ้นทีละ step |
Home |
ไปค่าต่ำสุด |
End |
ไปค่าสูงสุด |
Page Up |
เพิ่มขึ้น 10 step |
Page Down |
ลดลง 10 step |
เหตุการณ์
// Input event (while dragging)
rangeInput.addEventListener('input', (e) => {
console.log('Current value:', e.detail.value);
});
// Change event (after release)
rangeInput.addEventListener('change', (e) => {
console.log('Final value:', e.detail.value);
});TagsElementFactory
TagsElementFactory แปลง text input เป็น tags/chips input พร้อม visual tags, keyboard navigation และ optional autocomplete
การใช้งานพื้นฐาน
<!-- Simple tags input -->
<input type="text"
data-element="tags"
name="keywords"
placeholder="เพิ่ม tags...">
<!-- Tags พร้อม autocomplete -->
<input type="text"
data-element="tags"
data-source="/api/tags"
name="categories">HTML Attributes
| Attribute | ประเภท | ค่าเริ่มต้น | คำอธิบาย |
|---|---|---|---|
data-element |
string | - | ตั้งค่าเป็น tags |
data-source |
string/array | - | Autocomplete source |
data-separator |
string | , |
ตัวคั่นสำหรับค่าที่วาง |
data-max-tags |
number | null | จำนวน tags สูงสุด |
data-duplicate |
boolean | false |
อนุญาต tags ซ้ำ |
data-placeholder |
string | 'Add tags...' |
placeholder ของช่องกรอก |
data-min-length |
number | 2 |
จำนวนตัวอักษรขั้นต่ำก่อนเริ่ม autocomplete |
data-options-key |
string | - | คีย์ของข้อมูล options จาก parent |
list |
string | - | id ของ datalist ที่ใช้เป็น options |
การตั้งค่า
TagsElementFactory.config = {
type: 'text',
placeholder: 'Add tags...',
separator: ',',
maxTags: null,
allowDuplicate: false,
minLength: 2,
maxResults: 10,
delay: 300
};Keyboard Interaction
| ปุ่ม | การทำงาน |
|---|---|
Enter |
เพิ่ม text ปัจจุบันเป็น tag |
Backspace |
ลบ tag สุดท้าย (เมื่อ input ว่าง) |
↓ / ↑ |
Navigate autocomplete |
Escape |
ปิด autocomplete |
JavaScript API
const instance = ElementManager.getInstance(tagsInput);
// รับ tags ทั้งหมด
const tags = instance.getTags();
// [{key: '1', value: 'JavaScript'}, {key: '2', value: 'Python'}]
// เพิ่ม tag
instance.addTag('3', 'React');
// ลบ tag
instance.removeTag('2');
// ล้างทั้งหมด
instance.clear();การส่งค่าไปกับฟอร์ม
tags ถูกส่งไปเป็น hidden input
<!-- Original input -->
<input data-element="tags" name="skills">
<!-- Generated hidden inputs -->
<input type="hidden" name="skills[]" value="1">
<input type="hidden" name="skills[]" value="2">
<input type="hidden" name="skills[]" value="3">เหตุการณ์
tagsInput.addEventListener('change', (e) => {
const instance = ElementManager.getInstance(e.target);
console.log('Tags:', instance.getTags());
});TagsElementFactory ไม่ได้ส่งเหตุการณ์ tags:* เลย การเพิ่มหรือลบแท็กยิงแค่
change แบบ native เท่านั้น ถ้าต้องการรู้ว่าแท็กไหนเปลี่ยน ให้เทียบ
instance.getTags() กับรายการก่อนหน้าเอง
MaskElementFactory
MaskElementFactory ใช้ input masks สำหรับข้อมูลที่มีโครงสร้าง เช่น หมายเลขโทรศัพท์ วันที่ หมายเลขบัตร ฯลฯ
การใช้งานพื้นฐาน
<!-- หมายเลขโทรศัพท์ไทย -->
<input type="tel"
data-element="tel"
name="mobile">
<!-- บัตรเครดิต -->
<input type="text"
data-element="mask"
data-mask="#### #### #### ####"
name="card">
<!-- วันที่ -->
<input type="text"
data-element="mask"
data-mask="##/##/####"
name="date">HTML Attributes
| Attribute | ประเภท | ค่าเริ่มต้น | คำอธิบาย |
|---|---|---|---|
data-element |
string | - | mask หรือ tel |
data-mask |
string | - | รูปแบบ mask |
data-placeholder-char |
string | _ |
ตัวอักษรแทนตำแหน่งที่ยังไม่กรอก |
data-mask-on-init |
boolean | true |
ใส่ mask ตอนเริ่มต้น |
data-mask-on-change |
boolean | true |
ใส่ mask เมื่อค่าเปลี่ยน |
data-mask-on-blur |
boolean | true |
ใส่ mask เมื่อออกจากช่อง |
data-unmask-on-submit |
boolean | false |
ถอด mask ออกตอนส่งฟอร์ม |
Mask Pattern Characters
| ตัวอักษร | รับ |
|---|---|
# |
ตัวเลข (0-9) |
A |
ตัวอักษร (A-Z, a-z) |
* |
ตัวอักษรหรือตัวเลข |
| อื่นๆ | Literal (แสดงตามที่เป็น) |
Common Patterns
| กรณีใช้งาน | Pattern | ตัวอย่าง |
|---|---|---|
| โทรศัพท์สหรัฐ | (###) ###-#### |
(123) 456-7890 |
| โทรศัพท์ไทย | ###-###-#### |
081-234-5678 |
| วันที่ | ##/##/#### |
31/12/2025 |
| เวลา | ##:## |
14:30 |
| บัตรเครดิต | #### #### #### #### |
1234 5678 9012 3456 |
| SSN | ###-##-#### |
123-45-6789 |
| Zip+4 | #####-#### |
12345-6789 |
TelElementFactory
mask เฉพาะสำหรับหมายเลขโทรศัพท์ไทย
<input type="tel"
data-element="tel"
name="phone">
<!-- Auto applies: ###-###-#### -->JavaScript API
const instance = ElementManager.getInstance(maskedInput);
// รับค่าที่ยังไม่ใส่ mask
const raw = instance.getUnmaskedValue(); // '0812345678'
// รับค่าที่ใส่ mask แล้ว
const masked = instance.getValue(); // '081-234-5678'
// ตั้งค่า (ใส่ mask ให้เอง)
instance.setValue('0898765432');
// Shows: 089-876-5432เหตุการณ์
maskedInput.addEventListener('change', (e) => {
const instance = ElementManager.getInstance(e.target);
console.log('Masked:', e.target.value);
console.log('Raw:', instance.getUnmaskedValue());
});TextareaElementFactory
TextareaElementFactory ปรับปรุง textarea ด้วยฟังก์ชัน auto-resize
การใช้งานพื้นฐาน
<textarea data-element="textarea"
name="description"
rows="3"
placeholder="กรอกคำอธิบาย..."></textarea>HTML Attributes
| Attribute | ประเภท | ค่าเริ่มต้น | คำอธิบาย |
|---|---|---|---|
data-element |
string | - | ตั้งค่าเป็น textarea |
data-auto-resize |
boolean | true |
เปิด auto-resize |
data-min-rows |
number | 3 |
จำนวนแถวขั้นต่ำ |
data-max-rows |
number | 10 |
จำนวนแถวสูงสุดก่อน scroll |
maxlength |
number | - | จำกัดตัวอักษร |
data-show-counter |
boolean | false |
แสดงตัวนับตัวอักษร |
พฤติกรรมการขยายอัตโนมัติ
textarea ปรับความสูงตามเนื้อหาให้เอง
/* Textarea expands with content */
[data-element="textarea"] {
min-height: calc(3 * 1.5em); /* 3 rows minimum */
max-height: calc(10 * 1.5em); /* 10 rows maximum */
overflow-y: auto; /* Scroll when max reached */
resize: vertical; /* Allow manual resize */
}ตัวนับตัวอักษร
<textarea data-element="textarea"
data-show-counter="true"
maxlength="500"
name="bio"></textarea>
<!-- Shows: 0/500 characters -->JavaScript API
const instance = ElementManager.getInstance(textareaEl);
// สั่งคำนวณความสูงใหม่
instance.resize();
// อ่านความสูงปัจจุบัน
const height = instance.getHeight();แนวทางปฏิบัติที่ดี
1. ✅ ใช้ Element ที่เหมาะกับประเภทข้อมูล
<!-- ✅ สี -->
<input data-element="color" name="theme">
<!-- ✅ ช่วงราคา -->
<input data-element="range" data-dual="true" name="budget">
<!-- ✅ หลายหมวดหมู่ -->
<input data-element="tags" name="categories">
<!-- ✅ Input มีโครงสร้าง -->
<input data-element="mask" data-mask="##/##/####" name="date">2. ✅ กำหนดขอบเขตที่สมเหตุสมผล
<!-- ✅ ดี: จำกัด tags -->
<input data-element="tags" data-max-tags="5" name="keywords">
<!-- ✅ ดี: จำกัด textarea -->
<textarea data-element="textarea" maxlength="1000" data-max-rows="15"></textarea>3. ✅ ใส่ Autocomplete ให้ Tags
<!-- ✅ ดี: ผู้ใช้เห็น tag ที่มีอยู่แล้ว -->
<input data-element="tags"
data-source="/api/tags"
name="skills">
<!-- ❌ ไม่ดี: ผู้ใช้ต้องเดาชื่อ tag เอง -->
<input data-element="tags" name="skills">4. ✅ ใช้ tel Type สำหรับหมายเลขโทรศัพท์
<!-- ✅ ดี: Keyboard มือถือแสดงตัวเลข -->
<input type="tel"
data-element="tel"
name="phone">5. ✅ พิจารณาถอด mask ก่อนส่ง
<!-- ✅ ดี: เซิร์ฟเวอร์ได้ตัวเลขล้วน -->
<input data-element="mask"
data-mask="(###) ###-####"
data-unmask-on-submit="true"
name="phone">
<!-- Form submits: 1234567890 instead of (123) 456-7890 -->6. ✅ ใช้ Dual Range สำหรับ Filters
<!-- ✅ ดี: Price filter พร้อม min-max -->
<input data-element="range"
data-dual="true"
min="0"
max="10000"
step="100"
data-format="฿{value}"
name="price">เอกสารที่เกี่ยวข้อง
- Form Elements ภาพรวม
- ElementFactory - Base class
- Text Elements - Text inputs
- Number Elements - Number inputs
- FormManager - Form-level validation