Now.js Framework Documentation

Now.js Framework Documentation

Special Elements (อิลิเมนต์พิเศษ)

TH 04 Sep 2026 01:40

Special Elements (อิลิเมนต์พิเศษ)

เอกสารสำหรับ form elements พิเศษ: ColorElementFactory, RangeElementFactory, TagsElementFactory, MaskElementFactory และ TextareaElementFactory

📋 สารบัญ

  1. ภาพรวม
  2. ColorElementFactory
  3. RangeElementFactory
  4. TagsElementFactory
  5. MaskElementFactory
  6. TextareaElementFactory
  7. แนวทางปฏิบัติที่ดี

ภาพรวม

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">

เอกสารที่เกี่ยวข้อง