大佬,您那个把查询结果添加到侧边的css要怎么用啊
我在外观添加了css后,选上了,但是右侧还是没有这个查询出来的结果,我没找到对应的按钮,大佬,要如何继续操作
我不懂,如何把那个查询结果到右边,我现在建立了css文件,勾选了以后 还是没有看到查询结果到右边,或者左边,是因为 有好几个地方创建了这些文件吗?
@熊猫别熬夜 我自己写了个任务管理面版,但遇到问题了,看到你解决了这个问题,所以想请你帮忙给看看我的代码哪里出问题了
想要通过Dataviewjs代码实现:
- 收集多个项目文件夹下的全部任务;
- 按照时间状态分类任务(如:逾期、进行中、待办、今日、明日、一周内、一周后(未来)、完成),并显示所属分类的任务数量;
- 最终展示点击分类名称切换显示不同分类的任务列表,如:
- 当点击「逾期」分类时,下方只显示「逾期」的任务列表
- 当点击「进行中」分类时,下方只显示「进行中」的任务列表
- 使用
tasks
插件语法动态生成查询并渲染任务列表,方便在当前页面对任务进行操作(比如编辑等)
效果图:
dataviewjs代码:
// ==== 1. 收集任务 ====
let tasks1 = dv.pages('"01Projects"').file.tasks;
let tasks2 = dv.pages('"02Business"').file.tasks;
let tasks3 = dv.pages('"00Todolist"').file.tasks;
let tasks4 = dv.pages('"07People"').file.tasks;
let tasks5 = dv.pages('"00Journal"').file.tasks;
let tasks = [...tasks1, ...tasks2, ...tasks3, ...tasks4, ...tasks5];
let today = dv.date("today");
let tomorrow = dv.date("tomorrow");
let oneWeekLater = today.plus({ days: 6 });
// ==== 2. 分类任务 ====
let expiredTasks = tasks.filter(t => t.status === " " && (
(t.due && dv.date(t.due).toJSDate() < today.toJSDate()) ||
(t.scheduled && dv.date(t.scheduled).toJSDate() < today.toJSDate())
));
let ongoingTasks = tasks.filter(t => t.status === "/");
let todoTasks = tasks.filter(t => t.status === " " && (!t.due && !t.scheduled));
let todayTasks = tasks.filter(t => t.status === " " && (
(t.due && dv.date(t.due).toJSDate().toDateString() === today.toJSDate().toDateString()) ||
(t.scheduled && dv.date(t.scheduled).toJSDate().toDateString() === today.toJSDate().toDateString())
));
let tomorrowTasks = tasks.filter(t => t.status === " " && (
(t.due && dv.date(t.due).toJSDate().toDateString() === tomorrow.toJSDate().toDateString()) ||
(t.scheduled && dv.date(t.scheduled).toJSDate().toDateString() === tomorrow.toJSDate().toDateString())
));
let thisWeekTasks = tasks.filter(t => t.status === " " && (
(t.due && dv.date(t.due).toJSDate() > tomorrow.toJSDate() && dv.date(t.due).toJSDate() <= oneWeekLater.toJSDate()) ||
(t.scheduled && dv.date(t.scheduled).toJSDate() > tomorrow.toJSDate() && dv.date(t.scheduled).toJSDate() <= oneWeekLater.toJSDate())
));
let afterSevenDaysTasks = tasks.filter(t => t.status === " " && (
(t.due && dv.date(t.due).toJSDate() > oneWeekLater.toJSDate()) ||
(t.scheduled && dv.date(t.scheduled).toJSDate() > oneWeekLater.toJSDate())
));
let completedTasks = tasks.filter(t => t.status === "x");
// ==== 3. 分类设置 ====
let container = dv.container;
container.empty();
let cardsContainer = container.createDiv({cls: "cards-container"});
let categories = [
{ name: "逾期", query: `((due before today) OR (scheduled before today)) AND (not done) AND (status.type is not IN_PROGRESS)`, tasks: expiredTasks, color: "#ff4c4c" },
{ name: "进行中", query: `status.type is IN_PROGRESS`, tasks: ongoingTasks, color: "#4caf50" },
{ name: "今天", query: `((scheduled on today) OR (due on today)) AND (not done) AND (status.type is not IN_PROGRESS)`, tasks: todayTasks, color: "#ffffff" },
{ name: "明天", query: `((due on tomorrow) OR (scheduled on tomorrow)) AND (not done) AND (status.type is not IN_PROGRESS)`, tasks: tomorrowTasks, color: "#00bcd4" },
{ name: "待办", query: `(not done) AND ((no due date) AND (no scheduled date)) AND (status.type is not IN_PROGRESS)`, tasks: todoTasks, color: "#ff9800" },
{ name: "一周内", query: `((due after tomorrow) AND (due before in 7 day)) OR ((scheduled after tomorrow) AND (scheduled before in 7 day)) AND (not done) AND (status.type is not IN_PROGRESS)`, tasks: thisWeekTasks, color: "#8bc34a" },
{ name: "未来", query: `((due after in 7 day) OR (scheduled after in 7 day)) AND (not done) AND (status.type is not IN_PROGRESS)`, tasks: afterSevenDaysTasks, color: "#bbbbbb" },
{ name: "已完成", query: `done`, tasks: completedTasks, color: "#9e9e9e" },
];
// 当前选中分类
let currentIndex = 0;
// 生成卡片
categories.forEach((cat, index) => {
let card = cardsContainer.createDiv({cls: "card"});
card.onclick = () => showTasks(index);
let numberDiv = card.createDiv({cls: "number", text: cat.tasks.length});
numberDiv.style.color = cat.color;
let labelDiv = card.createDiv({cls: "label", text: cat.name});
let underline = card.createDiv({cls: "underline"});
underline.style.backgroundColor = cat.color;
});
// 创建任务列表区域
let taskListContainer = container.createDiv({cls: "task-list"});
// 展示对应分类的任务(使用 tasks 语法插入)
function showTasks(index) {
currentIndex = index;
taskListContainer.innerHTML = ""; // ✅ 清空旧内容
// ✅ 创建新的子容器用于插入任务块
let queryContainer = taskListContainer.createDiv();
// ✅ 拼接任务查询语句
let basePaths = `(path includes 01Projects) OR (path includes 02Business) OR (path includes 00Todolist) OR (path includes People) OR (path includes 00Journal)`;
let query = [
categories[index].query,
basePaths,
"sort by priority",
"sort by created reverse",
"group by function task.due.category.groupText",
"short mode",
"show tree"
].join("\n");
// ✅ 构造完整 Markdown 代码块
let fullBlock = "```tasks\n" + query + "\n```";
// ✅ 插入查询语句(作为纯 Markdown 块,由 Obsidian Task 插件解析)
dv.paragraph(fullBlock, queryContainer);
}
// 默认加载第一个分类
showTasks(3);
现在遇到的问题
点击分类名称时,上一个分类的任务列表还在下面显示,虽然代码里设置的清除容器内容,但实际结果并没有清除,所以导致新分类任务会叠加到老任务列表上,最终任务列表越来越多。
希望解决的问题
帮忙看看dvjs代码那里出了问题,导致不能清空老分类的任务列表,请大神给改改。
你这是因为dv.container内容需要重置,但是你的控件不能重置,每次重置就需要重新添加一次,不能用dv来创建容器,可以用DOM直接创建容器,之后添加。
这是修改后的,不过我有点看不懂你其他的的功能,比如currentIndex 这个指定页面,这个函数后面并没有引用,我没有配套的收集的任务清单来测试,所以只解决了点击按钮后重复添加查询的bug,其他的还需要你自己探索。
// ==== 1. 收集任务 ====
let tasks1 = dv.pages('"01Projects"').file.tasks;
let tasks2 = dv.pages('"02Business"').file.tasks;
let tasks3 = dv.pages('"00Todolist"').file.tasks;
let tasks4 = dv.pages('"07People"').file.tasks;
let tasks5 = dv.pages('"00Journal"').file.tasks;
let tasks = [...tasks1, ...tasks2, ...tasks3, ...tasks4, ...tasks5];
let today = dv.date("today");
let tomorrow = dv.date("tomorrow");
let oneWeekLater = today.plus({ days: 6 });
// ==== 2. 分类任务 ====
let expiredTasks = tasks.filter(t => t.status === " " && (
(t.due && dv.date(t.due).toJSDate() < today.toJSDate()) ||
(t.scheduled && dv.date(t.scheduled).toJSDate() < today.toJSDate())
));
let ongoingTasks = tasks.filter(t => t.status === "/");
let todoTasks = tasks.filter(t => t.status === " " && (!t.due && !t.scheduled));
let todayTasks = tasks.filter(t => t.status === " " && (
(t.due && dv.date(t.due).toJSDate().toDateString() === today.toJSDate().toDateString()) ||
(t.scheduled && dv.date(t.scheduled).toJSDate().toDateString() === today.toJSDate().toDateString())
));
let tomorrowTasks = tasks.filter(t => t.status === " " && (
(t.due && dv.date(t.due).toJSDate().toDateString() === tomorrow.toJSDate().toDateString()) ||
(t.scheduled && dv.date(t.scheduled).toJSDate().toDateString() === tomorrow.toJSDate().toDateString())
));
let thisWeekTasks = tasks.filter(t => t.status === " " && (
(t.due && dv.date(t.due).toJSDate() > tomorrow.toJSDate() && dv.date(t.due).toJSDate() <= oneWeekLater.toJSDate()) ||
(t.scheduled && dv.date(t.scheduled).toJSDate() > tomorrow.toJSDate() && dv.date(t.scheduled).toJSDate() <= oneWeekLater.toJSDate())
));
let afterSevenDaysTasks = tasks.filter(t => t.status === " " && (
(t.due && dv.date(t.due).toJSDate() > oneWeekLater.toJSDate()) ||
(t.scheduled && dv.date(t.scheduled).toJSDate() > oneWeekLater.toJSDate())
));
let completedTasks = tasks.filter(t => t.status === "x");
// ==== 3. 分类设置 ====
const cardsContainer = document.createElement('div');
cardsContainer.className = 'cards-container';
let categories = [
{ name: "逾期", query: `((due before today) OR (scheduled before today)) AND (not done) AND (status.type is not IN_PROGRESS)`, tasks: expiredTasks, color: "#ff4c4c" },
{ name: "进行中", query: `status.type is IN_PROGRESS`, tasks: ongoingTasks, color: "#4caf50" },
{ name: "今天", query: `((scheduled on today) OR (due on today)) AND (not done) AND (status.type is not IN_PROGRESS)`, tasks: todayTasks, color: "#ffffff" },
{ name: "明天", query: `((due on tomorrow) OR (scheduled on tomorrow)) AND (not done) AND (status.type is not IN_PROGRESS)`, tasks: tomorrowTasks, color: "#00bcd4" },
{ name: "待办", query: `(not done) AND ((no due date) AND (no scheduled date)) AND (status.type is not IN_PROGRESS)`, tasks: todoTasks, color: "#ff9800" },
{ name: "一周内", query: `((due after tomorrow) AND (due before in 7 day)) OR ((scheduled after tomorrow) AND (scheduled before in 7 day)) AND (not done) AND (status.type is not IN_PROGRESS)`, tasks: thisWeekTasks, color: "#8bc34a" },
{ name: "未来", query: `((due after in 7 day) OR (scheduled after in 7 day)) AND (not done) AND (status.type is not IN_PROGRESS)`, tasks: afterSevenDaysTasks, color: "#bbbbbb" },
{ name: "已完成", query: `done`, tasks: completedTasks, color: "#9e9e9e" },
];
// 当前选中分类
let currentIndex = 0;
// 生成卡片
categories.forEach((cat, index) => {
let card = cardsContainer.createDiv({cls: "card"});
card.onclick = () => showTasks(index);
let numberDiv = card.createDiv({cls: "number", text: cat.tasks.length});
numberDiv.style.color = cat.color;
let labelDiv = card.createDiv({cls: "label", text: cat.name});
let underline = card.createDiv({cls: "underline"});
underline.style.backgroundColor = cat.color;
});
// 创建任务列表区域
const taskListContainer = document.createElement('div');
cardsContainer.className = 'task-list';
// 展示对应分类的任务(使用 tasks 语法插入)
function showTasks(index) {
dv.container.innerHTML = "";
dv.container.appendChild(cardsContainer);
dv.container.appendChild(taskListContainer);
currentIndex = index;
// ✅ 创建新的子容器用于插入任务块
let queryContainer = taskListContainer.createDiv();
// ✅ 拼接任务查询语句
let basePaths = `(path includes 01Projects) OR (path includes 02Business) OR (path includes 00Todolist) OR (path includes People) OR (path includes 00Journal)`;
let query = [
categories[index].query,
basePaths,
"sort by priority",
"sort by created reverse",
"group by function task.due.category.groupText",
"short mode",
"show tree"
].join("\n");
// ✅ 构造完整 Markdown 代码块
let fullBlock = "```tasks\n" + query + "\n```";
// ✅ 插入查询语句(作为纯 Markdown 块,由 Obsidian Task 插件解析)
dv.paragraph(fullBlock, queryContainer);
}
// 默认加载第一个分类
showTasks(3);
感谢 @熊猫别熬夜 !
按照你修改的代码成功解决了问题,不过其中有个小bug,在下边这部分代码正确的写法是:
// 创建任务列表区域
const taskListContainer = document.createElement('div');
taskListContainer.className = 'task-list';
就是把原来代码
cardsContainer.className = 'task-list'`
修改为
taskListContainer.className = 'task-list';
tasks插件吗,我还没更新
你好,请教一个问题:我用了你的代码,采用的方式是嵌入到周笔记中。
我遇到一个问题,当光标从别的笔记返回周笔记时,或者在当前笔记编辑时,光标会自动跳到(聚焦到)这个嵌入语法中,偶尔不注意就会误操作。
我试了在周笔记中这句![[Tasks_weekly_panel]]
的前后加入其它嵌入块,光标还是会跳到这句。
不知道我的是个例还是别人也有这样的情况。