small fix
This commit is contained in:
parent
b160624e4e
commit
004a2023a6
|
@ -16,14 +16,20 @@ export class JsmindSearch {
|
||||||
* @param {Function} searchAPI - 遠程搜尋 API 函式 (Remote search API function)
|
* @param {Function} searchAPI - 遠程搜尋 API 函式 (Remote search API function)
|
||||||
* @param {string} tableUID
|
* @param {string} tableUID
|
||||||
*/
|
*/
|
||||||
constructor(jm, searchAPI, tableUID) {
|
constructor(jm, searchAPI, tableUID) {
|
||||||
this.jm = jm
|
this.jm = jm
|
||||||
this.searchAPI = searchAPI
|
this.searchAPI = searchAPI
|
||||||
this.container = document.getElementById(jm.options.container)
|
this.container = document.getElementById(jm.options.container)
|
||||||
this.suggestionBox = null
|
this.suggestionBox = null
|
||||||
this.tableUID = tableUID
|
this.tableUID = tableUID
|
||||||
this.init()
|
|
||||||
}
|
// 新增記錄節點與事件 handler
|
||||||
|
this.currentNode = null
|
||||||
|
this._keydownHandler = null
|
||||||
|
this._inputHandler = null
|
||||||
|
|
||||||
|
this.init()
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 初始化搜尋事件
|
* 初始化搜尋事件
|
||||||
|
@ -59,41 +65,49 @@ export class JsmindSearch {
|
||||||
* Start handling search
|
* Start handling search
|
||||||
* @param {Object} node - 當前選中節點 (Selected node)
|
* @param {Object} node - 當前選中節點 (Selected node)
|
||||||
*/
|
*/
|
||||||
handleSearch(node) {
|
handleSearch(node) {
|
||||||
const inputField = document.querySelector(`.${EDITOR_CLASS}`)
|
const inputField = document.querySelector(`.${EDITOR_CLASS}`)
|
||||||
if (!inputField) return
|
if (!inputField) return
|
||||||
|
|
||||||
// 確保不會重複綁定 input 事件
|
// 記住目前的 node
|
||||||
// Ensure input event is not bound multiple times
|
this.currentNode = node
|
||||||
inputField.removeEventListener('input', this.onInput)
|
|
||||||
inputField.addEventListener('input', this.onInput.bind(this, node))
|
|
||||||
|
|
||||||
inputField.removeEventListener('keydown', this.onKeyDown)
|
// 清除之前的 handler
|
||||||
inputField.addEventListener('keydown', this.onKeyDown.bind(this, node))
|
if (this._keydownHandler) inputField.removeEventListener('keydown', this._keydownHandler)
|
||||||
}
|
if (this._inputHandler) inputField.removeEventListener('input', this._inputHandler)
|
||||||
|
|
||||||
|
// 新綁定 handler
|
||||||
|
this._keydownHandler = this.onKeyDown.bind(this)
|
||||||
|
this._inputHandler = this.onInput.bind(this)
|
||||||
|
|
||||||
|
inputField.addEventListener('keydown', this._keydownHandler)
|
||||||
|
inputField.addEventListener('input', this._inputHandler)
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* 處理 Enter 鍵完成輸入
|
* 處理 Enter 鍵完成輸入
|
||||||
* Handle Enter key to finalize input
|
* Handle Enter key to finalize input
|
||||||
* @param {Object} node - 當前節點
|
* @param {Object} node - 當前節點
|
||||||
* @param {KeyboardEvent} e - 鍵盤事件
|
* @param {KeyboardEvent} e - 鍵盤事件
|
||||||
*/
|
*/
|
||||||
onKeyDown(node, e) {
|
onKeyDown(e) {
|
||||||
if (e.key === 'Enter') {
|
if (e.key === 'Enter') {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
const input = e.target.value.trim()
|
|
||||||
if (input) {
|
|
||||||
// 更新節點文字
|
|
||||||
node.data.text = input
|
|
||||||
this.jm.end_edit()
|
|
||||||
this.jm.update_node(node.id, input)
|
|
||||||
|
|
||||||
// 隱藏 suggestion box(避免未選建議但仍留下)
|
const input = e.target.value.trim()
|
||||||
if (this.suggestionBox) {
|
const node = this.currentNode
|
||||||
this.suggestionBox.style.display = 'none'
|
if (input && node) {
|
||||||
}
|
node.data.text = input
|
||||||
}
|
this.jm.end_edit()
|
||||||
|
this.jm.update_node(node.id, input)
|
||||||
|
|
||||||
|
if (this.suggestionBox) {
|
||||||
|
this.suggestionBox.style.display = 'none'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.currentNode = null // 清除參考
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 處理使用者輸入
|
* 處理使用者輸入
|
||||||
|
@ -101,18 +115,17 @@ export class JsmindSearch {
|
||||||
* @param {Object} node - 當前選中節點 (Selected node)
|
* @param {Object} node - 當前選中節點 (Selected node)
|
||||||
* @param {Event} e - 輸入事件 (Input event)
|
* @param {Event} e - 輸入事件 (Input event)
|
||||||
*/
|
*/
|
||||||
async onInput(node, e) {
|
async onInput(e) {
|
||||||
const query = e.target.value.trim()
|
const query = e.target.value.trim()
|
||||||
if (!query) return
|
if (!query) return
|
||||||
await new Promise(resolve => setTimeout(resolve, 500));
|
await new Promise((resolve) => setTimeout(resolve, 500))
|
||||||
try {
|
try {
|
||||||
const results = await this.searchAPI(query, this.tableUID)
|
const results = await this.searchAPI(query, this.tableUID)
|
||||||
this.showSuggestion(node, e.target, results)
|
this.showSuggestion(this.currentNode, e.target, results)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// Search API error handling
|
console.error('搜尋 API 錯誤:', error)
|
||||||
console.error('搜尋 API 錯誤:', error)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 顯示搜尋建議框
|
* 顯示搜尋建議框
|
||||||
|
|
|
@ -111,14 +111,16 @@ wb.add_worksheet(name: "Structure") do |sheet|
|
||||||
when "file"
|
when "file"
|
||||||
file_links = []
|
file_links = []
|
||||||
locale = I18n.locale.to_s
|
locale = I18n.locale.to_s
|
||||||
column.column_entry_files.desc(:sort_number).each do |entry_file|
|
if !column.nil?
|
||||||
next unless entry_file.choose_lang_display(locale)
|
column.column_entry_files.desc(:sort_number).each do |entry_file|
|
||||||
file_links << (url + entry_file.get_link)
|
next unless entry_file.choose_lang_display(locale)
|
||||||
end
|
file_links << (url + entry_file.get_link)
|
||||||
row << file_links.join("\r\n")
|
end
|
||||||
|
end
|
||||||
|
row << file_links.join(";")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
row << entry.table_tags.pluck("title").map { |t| "#{t}" }.join(", ")
|
row << entry.table_tags.pluck("title").map { |t| "#{t}" }.join("; ")
|
||||||
row << entry.get_related_entries_uid
|
row << entry.get_related_entries_uid
|
||||||
sheet.add_row row, style: wrap
|
sheet.add_row row, style: wrap
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue