Now.js Framework Documentation

Now.js Framework Documentation

Autocomplete

TH 15 Dec 2025 08:52

Autocomplete

ภาพรวม

Autocomplete คือ component สำหรับ input autocomplete ใน Now.js Framework รองรับทั้ง datalist และ AJAX suggestions

ใช้เมื่อ:

  • ต้องการ autocomplete suggestions
  • ต้องการ search suggestions จาก API
  • ต้องการ typeahead functionality
  • ต้องการ filter จาก datalist

ทำไมต้องใช้:

  • ✅ Keyboard navigation (Arrow keys, Enter, Escape)
  • ✅ AJAX support
  • ✅ Datalist filtering
  • ✅ Debounced input
  • ✅ Customizable appearance
  • ✅ Loading state

การใช้งานพื้นฐาน

With Static Datalist

<input type="text" id="city" list="cities">
<datalist id="cities">
  <option value="Bangkok">กรุงเทพฯ</option>
  <option value="Chiang Mai">เชียงใหม่</option>
  <option value="Phuket">ภูเก็ต</option>
  <option value="Pattaya">พัทยา</option>
</datalist>

<script>
const instance = Autocomplete.create(document.getElementById('city'));
</script>

With AJAX URL

<input type="text" id="search" placeholder="ค้นหา...">

<script>
const instance = Autocomplete.create(document.getElementById('search'), {
  url: '/api/search',
  minLength: 2,
  delay: 300,
  limit: 10
});
</script>

การตั้งค่า

Autocomplete.create(element, {
  // Minimum characters before searching
  minLength: 2,

  // Debounce delay (ms)
  delay: 300,

  // Maximum suggestions
  limit: 10,

  // API URL for AJAX
  url: '/api/search',

  // CSS classes
  listClass: 'autocomplete-list',
  activeClass: 'active',
  loadingClass: 'loading'
});

AJAX Response Format

API ควร return array of objects หรือ strings:

// Objects with value and label
[
  { value: 'th', label: 'Thailand' },
  { value: 'jp', label: 'Japan' },
  { value: 'us', label: 'United States' }
]

// Or simple strings
['Apple', 'Banana', 'Cherry']

Query parameter ที่ส่งไป:

  • q - search term
  • limit - maximum results

API อ้างอิง

Autocomplete.create(element, options)

สร้าง autocomplete instance

Parameter Type Description
element HTMLInputElement Input element
options.url string API URL สำหรับ AJAX
options.minLength number ตัวอักษรขั้นต่ำ (default: 2)
options.delay number Debounce delay ms (default: 300)
options.limit number จำนวน suggestions สูงสุด
options.listClass string CSS class สำหรับ list
options.activeClass string CSS class สำหรับ active item
options.loadingClass string CSS class สำหรับ loading

Returns: Object - Instance

Autocomplete.destroy(instance)

ทำลาย instance

Parameter Type Description
instance Object Instance ที่สร้างจาก create()

Keyboard Navigation

Key Action
เลือก item ถัดไป
เลือก item ก่อนหน้า
Enter เลือก item ปัจจุบัน
Escape ปิด suggestions

เหตุการณ์

เมื่อเลือก item จะ dispatch change event:

input.addEventListener('change', (e) => {
  console.log('Selected:', e.target.value);
});

การจัดรูปแบบ CSS

/* Suggestion list */
.autocomplete-list {
  position: absolute;
  width: 100%;
  max-height: 200px;
  overflow-y: auto;
  background: white;
  border: 1px solid #ddd;
  border-radius: 4px;
  box-shadow: 0 2px 8px rgba(0,0,0,0.1);
  list-style: none;
  margin: 0;
  padding: 0;
  z-index: 1000;
}

.autocomplete-list li {
  padding: 8px 12px;
  cursor: pointer;
}

.autocomplete-list li:hover,
.autocomplete-list li.active {
  background: #f0f0f0;
}

/* Loading state */
input.loading {
  background-image: url('/images/spinner.gif');
  background-repeat: no-repeat;
  background-position: right 8px center;
}

ตัวอย่างการใช้งานจริง

<div class="search-container">
  <input type="text" id="product-search" placeholder="ค้นหาสินค้า...">
</div>

<script>
const searchInput = document.getElementById('product-search');
const autocomplete = Autocomplete.create(searchInput, {
  url: '/api/products/search',
  minLength: 2,
  delay: 300,
  limit: 8
});

searchInput.addEventListener('change', async (e) => {
  const productId = e.target.value;
  // Navigate to product page
  window.location.href = `/products/${productId}`;
});
</script>

User Mention

<textarea id="comment" placeholder="พิมพ์ @ เพื่อ mention ผู้ใช้"></textarea>

<script>
// Custom trigger on @
const textarea = document.getElementById('comment');
let mentionStart = -1;

textarea.addEventListener('input', async (e) => {
  const value = e.target.value;
  const cursorPos = e.target.selectionStart;

  // Check for @ trigger
  const lastAt = value.lastIndexOf('@', cursorPos);
  if (lastAt >= 0) {
    const query = value.substring(lastAt + 1, cursorPos);
    if (query.length >= 2) {
      // Use Autocomplete API
      const users = await fetch(`/api/users/search?q=${query}`);
      // Show suggestions...
    }
  }
});
</script>

ข้อควรระวัง

⚠️ 1. Parent Position

/* ❌ ถ้า parent ไม่มี position - list จะไม่ตรงที่ */
.container {
  /* no position */
}

/* ✅ ต้องมี position relative */
.container {
  position: relative;
}

⚠️ 2. API Response Format

// ❌ Response format ไม่ถูกต้อง
{ success: true, products: [...] }

// ✅ Return array โดยตรง
[{ value: '1', label: 'Product 1' }, ...]

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