Now.js Framework Documentation

Now.js Framework Documentation

Autocomplete

TH 04 Sep 2026 01:40

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' }, ...]

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