Create dataview table of multiple tasks within notes

What I’d like to do

I would like to create a dataview table of annotated tasks. I see some great implementations of this using atomic notes for each task (e.g., Dataview task and project examples and Inbox and Task Management Database using Atomic Notes as Tasks and Dataview). However, I like to keep single-line tasks scattered across notes more in the style of obsidian-tasks and would like to be able to display this style of annotated tasks as a dataview table with the annotations (i.e., [metadata:: value]) as columns. I’m having trouble building the correct dataviewjs query to accomplish this with some combination of dv.taskList, dv.table and dv.pages().file.tasks. Below is an example of my desired input and output. I appreciate your suggestions!

Ideally, I would like to also recognize different statuses, such as cancelled, per GitHub - deathau/obsidian-snippets, as well as subtasks.

Example

Here are some tasks, which could be scattered across different files:

  • [ ] put your right foot in [created:: 2021-08-09]
  • [-] take your right foot out [created:: 2021-08-09] [due:: 2021-08-16]
  • [ ] put your right foot in [created:: 2021-08-10] [priority:: high]
    • [ ] shake it all about [created:: 2021-08-10]
  • [X] do the hokey pokey [created:: 2021-08-11] [due:: 2021-08-16] [completion: :2021-08-15]
  • [>] turn yourself around [created:: 2021-08-12] [priority:: low]

Here’s what the dataview table should look like:

Task Status Completion Date Due Date Created Date Priority Subtasks Parent File
put your right foot in incomplete 2021-08-09 myfile
take your right foot out cancelled 2021-08-16 2021-08-09 myfile
put your right foot in incomplete 2021-08-10 high shake it all about myfile
shake it all about incomplete 2021-08-10 put your right foot in myfile
do the hokey pokey complete 2021-08-15 2021-08-16 2021-08-11 myfile
turn yourself around deferred 2021-08-12 low myfile

An attempt

The closest I’ve gotten is one row per file listing all tasks:

TABLE file.tasks.text
WHERE file.tasks 

2 Likes

Hi.

To start use this query:

```dataview
TABLE WITHOUT ID regexreplace(Tasks.text, "\[.*$", "") AS Task, choice(Tasks.completed, "completed", "incompleted") AS Status, Tasks.completion AS "Completion Date", Tasks.due AS "Due Date", Tasks.created AS "Created Date", Tasks.priority AS "Priority", regexreplace(Tasks.subtasks.text, "\[.*$", "") AS Subtasks, choice(Tasks.subtasks.completed, "completed", "incompleted") AS "Subtasks status", file.link AS "File"
FROM "your-folder"
WHERE file.tasks
FLATTEN file.tasks AS Tasks
```

BUT…

  1. can’t list subtasks in first column
  2. can’t recognize different statuses (attention: different checklist symbols implies not recognition as tasks)
1 Like

Thanks so much! This gets most of the way there. For some reason the dates are not displaying – any ideas?

  1. You need to check your “Date format” in Settings > Dataview. Maybe you have removed the default Date format and you don’t defined a new one.
  2. Your completion field has a error: not “: :” but “::”
  3. For “completed” / “incompleted” you can also use a symbol/emoji…
```dataview
TABLE WITHOUT ID regexreplace(Tasks.text, "\[.*$", "") AS Task, choice(Tasks.completed, "🟢", "🔴") AS Status, Tasks.completion AS "Completion Date", Tasks.due AS "Due Date", Tasks.created AS "Created Date", Tasks.priority AS "Priority", regexreplace(Tasks.subtasks.text, "\[.*$", "") AS Subtasks, choice(Tasks.subtasks.completed, "🟢", "🔴") AS "Subtasks status", file.link AS "File"
FROM "your-folder"
WHERE file.tasks
FLATTEN file.tasks AS Tasks
```
2 Likes

Thank you @mnvwvnm ! 1 and 2 solved it. I appreciate your suggestion of emojis, and am also thinking of using emojis within the tasks to match the Tasks plugin. For example, instead of [priority:: high], I would like to use :arrow_double_up:. There are 4 possible levels: high/:arrow_double_up:, medium​:arrow_up_small:, low​:arrow_down_small:, none. I’m trying to build this with choice() and regexmatch() to get this from Tasks.text (ideally, also remove these from Tasks.text) but am stuck. Thank you in advance for your suggestion!

Here are tasks:

  • [ ] put your right foot in :arrow_double_up: [created:: 2021-08-09]
  • [ ] take your right foot out :arrow_up_small: [created:: 2021-08-10]
  • [X] do the hokey pokey :arrow_down_small: [created:: 2021-08-11] [due:: 2021-08-16] [completion::2021-08-15]
  • [ ] turn yourself around [created:: 2021-08-12]

Here’s an attempt:

TABLE WITHOUT ID
	regexreplace(Tasks.text, "\[.*$", "") AS Task, 
	choice(regexmatch(".*⏫.*", Tasks.text), "⏫", "other") AS "Priority"
FROM #testingdates2
WHERE file.tasks
FLATTEN file.tasks AS Tasks

My knowledge in regex in almost zero (as in code in general). My simple suggestion is:

  • as regexreplace(Tasks.text, "\[.*$", "") remove everything after the first “[” in task text, then the best place to add your priority emoji is after any inline field. :arrow_up_small:
- [ ] put your right foot in [created:: 2021-08-09] ⏫
- [ ] take your right foot out [created:: 2021-08-10] ⏫
- [x] do the hokey pokey [created:: 2021-08-11] [due:: 2021-08-16] [completion:: 2021-08-15] ⏫
- [ ] turn yourself around [created:: 2021-08-12]

Thanks! I’ve been playing with dataview and regex (using https://regex101.com/) and got most of the way there. However I get this odd character showing up and have no clue why…I may open an issue in dataview since the issue doesn’t seem to happen elsewhere.

TABLE WITHOUT ID
	regexreplace(Tasks.text, "[⏫🔼🔽]? \[.*$", "") AS Task, 
	regexreplace(Tasks.text, "[^⏫🔼🔽]", "") AS "Priority"
FROM #testingdates2
WHERE file.tasks
FLATTEN file.tasks AS Tasks

1 Like

Apologies for jumping in/hijacking this topic - I have a similar idea of scattering tasks throughout the vault, and annotating them with various ‘things’, such as do dates, due dates, hashtags, etc, which I would like to show up as columns. A few sample tasks would be:

  • [ ] write introduction [[2022-01-26]]
  • [ ] submit article [due:: [[2022-01-25]]]
  • [ ] prep lecture #week2 #projectX

I am happy to adjust the annotations to make it easier for Dataview, as long as it can be typed reasonably easily. I am not sure, for example, if #projectX wouldn’t be better off as [[Project X]]. if it would need to be [project:: "[[project X]]] that would be a bit awkward…

one complication is that I would like the query to find tasks for a specific time frame, e.g. a particular week.

In the example above, the first task would be a DO date, but is not as time critical as a DUE date. The hashtag corresponds to a particular week in the semester, which, ideally would somehow be linked to the corresponding dates, eg. [[2022-01-31]] - [[2022-02-04]] would be #week2

I have tried to modify the query above, but failed miserably…in plain English, I would like to say:

“please show me all tasks that are due next week (denoted either by the hashtag or a date which falls inside the date range), and please turn the task text, do dates, due dates, hashtags and links into columns. Thank you”

Is something like tis possible? It would be for a weekly dashboard, so each week would have it’s own query, I suppose…

I love how polite we can be to the machines we use, as if when we talk to them with respect the code should be more likely to understand haha!


Why do you need the link to that day’s daily note? Is that actually important to include in this table?

I think I saw previously that one of the solutions to make the date a link is by reconstructing it with something like "[[" + datefield +"]]" which tends to make the code messy.

I keep trying, however futile it is… :stuck_out_tongue_closed_eyes:

Why do you need the link to that day’s daily note? Is that actually important to include in this table?

Well, I want the task to show up in the daily note backlinks, and/or the daily note task query (what’s due/do today? - this should hopefully be a much easier query!)

Is it possible to limit the table to only show those tasks that have a particular key::value pair, eg

[created:: 2021-08-09]?

Perhaps with one of these?

Where created = "2021-08-09"
Where contains(created, "2021-08-09")

Or something like this?

In table you are working in page-level (not in tasks-level, as in task queries), but I think the inline fields inside tasks working in tasks-level.
So, you can filter by task content (file.tasks.text) or, better, by the field inside tasks (file.tasks.created).

But (always a “but”) as table queries working at page-level you have results per page.

Let’s say you add this:
WHERE contains(file.tasks.created, date(2021-08-09))

This filter is applied to the pages that “contains” this condition, but returns all the tasks inside that pages, not only the wanted tasks.

But, taken the query above, if we add the filter bellow after the FLATTEN file.tasks AS Tasks, maybe it works:
WHERE Tasks.created = date(2021-08-09)

1 Like

Thanks this works! Albeit with some wonky date format, but that is in the existing table already and not that important for me…

But when I apply the same logic to [keyword:: pride]

WHERE Tasks.keyword = pride
WHERE Tasks.keyword = keyword(pride)
WHERE Tasks.keyword = "pride"

and so on…it disappears all tasks with keywords from the table, not just the keyword in question.

What is happening?

1 Like

In logic, it should works. But sometimes things are in details.
I need more information (the query, examples, etc.) to check what is happening!

ok!

TABLE WITHOUT ID regexreplace(Tasks.text, "\[.*$", "") AS Task, choice(Tasks.completed, "done", "todo") AS Status, Tasks.due AS "Due Date", Tasks.created AS "Created Date", Tasks.priority AS "Priority", Tasks.project as  "Project", Tasks.keyword as "Keyword", Tasks.section AS "link", file.link AS "File" 
from "films and tv series"
WHERE file.tasks
FLATTEN file.tasks AS Tasks 

here are some test tasks:

## Tasks #tasks 
- [ ] dickinson task with [priority:: 1] and keyword without tag [keyword:: week2]
- [ ] dickinson with tag as keyword [keyword:: #week2]
- [x] dickinson with tag as tag #week2 


From a different page:

## Tasks

- [ ] watch the 1995 version (keyword:: pride)
- [ ] test task from Pride and Prejudice [created:: 2022-02-02]
- [ ] how about another on from P&P [keyword:: pride]

This works fine:

But if I add a WHERE clause at the end about Tasks.keyword, nothing works…

Does this help?

Some notes:

  1. (about the re-use of other queries) Do you know what regexreplace(Tasks.text, "\[.*$", "") AS Task do? This is important to you? Tasks.text As Task isn’t enough?
    regexreplace(Tasks.text, "\[.*$", "") AS Task do this: take the text of each task and remove everything from the first “[” to the end in the original text, i.e., for example, take - [ ] dickinson task with [priority:: 1] and keyword without tag [keyword:: week2] and removes everything after “with”.
    So, in the original query this is created to separate text from all metadata things (created with the format [key:: value], not with the format (key:: value). That’s why all metadata to extract are placed after the main text of the tasks.
    In your tasks examples there’s no rule! That’s why you get weird results (for example, in the task - [ ] dickinson task with [priority:: 1] and keyword without tag [keyword:: week2] if you want to see all text until the word “tag”, you need to use (priority:: 1) in the middle of the string instead of [priority:: 1]).

  2. If at the end of the query (after FLATTEN file.tasks AS Tasks) you add WHERE Tasks.keyword = "pride" it works.

  1. What do you do with the date format in dataview settings?
1 Like

Many many thanks! Especially for the explanation - as I’m sure you guessed I had no idea what the Regex was doing.

I have now made sure to follow the order of things properly (the text in between the key:: value pairs was just notes for myself).

Much appreciate your help with this!

how did you become so proficient with dataview with 0 coding knowledge?

:slight_smile:
Just using the try-error method; reading the documentation; following other discussions; helping (challenging myself) in this Forum; follow and helping in Discord Obsidian channel; etc.
With my limitations. For example, the lack of knowledge in javascript (I’m a zero); knowing only one or two regex expressions; etc.

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.