'
@@ -592,7 +887,7 @@
return
}
if (!state.items.length) {
- var isFiltered = state.status !== 'all' || state.priority || state.category || state.keyword
+ var isFiltered = state.status !== 'all' || state.priority || state.keyword
elList.innerHTML = '
'
+ '
' + (isFiltered ? '🔍' : '🌱') + ''
+ '
' + (isFiltered ? '没有符合条件的待办' : '清单还是空的') + '
'
@@ -605,7 +900,6 @@
function renderAll() {
renderStats()
- renderCategoryOptions()
renderList()
}
@@ -619,7 +913,6 @@
if (state.status === 'active') params.status = 0
if (state.status === 'done') params.status = 1
if (state.priority) params.priority = state.priority
- if (state.category) params.category = state.category
if (state.keyword) params.keyword = state.keyword
return post('/list', params).then(function (res) {
@@ -661,14 +954,13 @@
if (!title) { toast('先写点什么吧'); elQuick.focus(); return }
var data = {
title: title,
- priority: $('quickPriority').value,
- category: $('quickCat').value,
- dueDate: $('quickDue').value
+ priority: getSel('quickPriority'),
+ dueDate: getSel('quickDue')
}
post('/add', data).then(function (res) {
if (!res || res.code !== 200) throw new Error((res && res.message) || '添加失败')
elQuick.value = ''
- $('quickDue').value = ''
+ setDateSel($('quickDue'), '')
toast('已添加')
return fetchList(true).then(fetchStats)
}).catch(function (e) { toast(e.message || '添加失败', true) })
@@ -681,37 +973,34 @@
}).catch(function (e) { toast(e.message || '操作失败', true) })
}
- function removeTodo(id) {
- if (!confirm('确定删除这条待办吗?')) return
- post('/remove', { id: id }).then(function (res) {
- if (!res || res.code !== 200) throw new Error((res && res.message) || '删除失败')
- toast('已删除')
- return fetchList(true).then(fetchStats)
- }).catch(function (e) { toast(e.message || '删除失败', true) })
+ function removeTodo(id, title) {
+ confirmDialog({
+ title: '删除这条待办?',
+ text: '删除后不再显示,且无法恢复。',
+ quote: title,
+ okText: '删除'
+ }).then(function (ok) {
+ if (!ok) return
+ return post('/remove', { id: id }).then(function (res) {
+ if (!res || res.code !== 200) throw new Error((res && res.message) || '删除失败')
+ toast('已删除')
+ return fetchList(true).then(fetchStats)
+ }).catch(function (e) { toast(e.message || '删除失败', true) })
+ })
}
/* ===== 编辑弹窗 ===== */
function openEdit(item) {
var isNew = !item
- item = item || { priority: 2, category: '', dueDate: '', remark: '', title: '' }
+ item = item || { priority: 2, dueDate: '', remark: '', title: '' }
var html = '
'
+ '
' + (isNew ? '新建待办' : '编辑待办') + '
'
+ '
'
+ '
'
+ '
'
- + '
'
- + '
'
+ + '
' + selHtml('mPriority', String(item.priority || 2), PRI_OPTS) + '
'
+ + '
' + dateSelHtml('mDue', item.dueDate || '') + '
'
+ '
'
- + '
'
- + '
'
+ '
'
+ '
'
+ '
'
elModalRoot.innerHTML = html
+ initSel($('mPriority'))
+ initDate($('mDue'))
var mask = $('mask')
var mTitle = $('mTitle')
setTimeout(function () { mTitle.focus() }, 60)
@@ -735,9 +1026,8 @@
if (!title) { toast('标题不能为空'); mTitle.focus(); return }
var data = {
title: title,
- priority: $('mPriority').value,
- category: $('mCategory').value,
- dueDate: $('mDue').value,
+ priority: getSel('mPriority'),
+ dueDate: getSel('mDue'),
remark: $('mRemark').value
}
var req
@@ -789,7 +1079,6 @@
return post('/add', {
title: it.title,
priority: it.priority || 2,
- category: it.category || '',
dueDate: it.dueDate || '',
remark: it.remark || ''
}).then(function (r) { if (r && r.code === 200) okCount++ })
@@ -804,15 +1093,37 @@
}
function clearDone() {
- if (!confirm('确定清除所有已完成的待办吗?此操作不可撤销。')) return
- post('/removeDone', {}).then(function (res) {
- if (!res || res.code !== 200) throw new Error((res && res.message) || '清理失败')
- toast('已清除')
- return fetchList(true).then(fetchStats)
- }).catch(function (e) { toast(e.message || '清理失败', true) })
+ var n = computed().done
+ if (!n) { toast('没有已完成的待办'); return }
+ confirmDialog({
+ title: '清除全部已完成?',
+ text: '共 ' + n + ' 条已完成的待办会被清除,此操作不可恢复。',
+ okText: '清除'
+ }).then(function (ok) {
+ if (!ok) return
+ return post('/removeDone', {}).then(function (res) {
+ if (!res || res.code !== 200) throw new Error((res && res.message) || '清理失败')
+ toast('已清除 ' + n + ' 条')
+ return fetchList(true).then(fetchStats)
+ }).catch(function (e) { toast(e.message || '清理失败', true) })
+ })
}
/* ===== 事件绑定 ===== */
+ // 下拉:用 HTML 占位槽替换成自绘组件,避免原生 select 的展开面板无法美化
+ $('quickPriSlot').outerHTML = selHtml('quickPriority', '2', PRI_OPTS)
+ $('quickDueSlot').outerHTML = dateSelHtml('quickDue', '')
+ $('filterPriSlot').outerHTML = selHtml('filterPri', '', FILTER_PRI_OPTS)
+ $('sortSlot').outerHTML = selHtml('sortBy', 'created', SORT_OPTS)
+
+ initSel($('quickPriority'))
+ initDate($('quickDue'))
+ initSel($('filterPri'), function (v) { state.priority = v; fetchList() })
+ initSel($('sortBy'), function (v) { state.sort = v; fetchList() })
+
+ // 点击空白处收起所有下拉
+ document.addEventListener('click', function () { closeAllSels() })
+
$('addBtn').addEventListener('click', addTodo)
elQuick.addEventListener('keydown', function (e) {
if (e.key === 'Enter') { e.preventDefault(); addTodo() }
@@ -844,10 +1155,6 @@
fetchList()
})
- $('filterPri').addEventListener('change', function () { state.priority = this.value; fetchList() })
- $('filterCat').addEventListener('change', function () { state.category = this.value; fetchList() })
- $('sortBy').addEventListener('change', function () { state.sort = this.value; fetchList() })
-
var searchTimer = null
$('searchInput').addEventListener('input', function () {
var v = this.value.trim()
@@ -869,7 +1176,7 @@
if (!item) return
if (act === 'toggle') toggleStatus(item.id, item.status)
else if (act === 'edit') openEdit(item)
- else if (act === 'del') removeTodo(item.id)
+ else if (act === 'del') removeTodo(item.id, item.title)
})
$('exportBtn').addEventListener('click', exportJson)
@@ -881,8 +1188,9 @@
$('clearDoneBtn').addEventListener('click', clearDone)
document.addEventListener('keydown', function (e) {
+ if (elModalRoot.innerHTML) return // 弹窗打开时不响应快捷键
var tag = (e.target.tagName || '').toLowerCase()
- if (tag === 'input' || tag === 'textarea' || tag === 'select') return
+ if (tag === 'input' || tag === 'textarea') return
if (e.key === 'n' || e.key === 'N') { e.preventDefault(); openEdit(null) }
else if (e.key === '/') { e.preventDefault(); $('searchInput').focus() }
})