Task list of a specific section of all daily notes

I’m using dataview(js) to get a listing of all unfinished todos over all my past daily notes. This is easy enough using dataviewjs and a folder template.

I have now introduced a new section (a # My New Section heading) into my daily notes. This section may also contain checkboxes which, however, should not be displayed in my listing of yet-to-do todos. How would I go about aggregating todos of the past which do not belong to # My New Section (or, alternatively, which belong exclusively to a # Todo section)?

I’d appreciate any input. Thank you very much and kind regards.

P.S.: Here’s my current folder template for my daily notes, whose files are named according to their respective date (e.g. 2022-12-31):

```dataviewjs
/* Selects unfinished tasks or tasks, which were completed today. */
function selectTasks(t) {
	if ((!t.completed) ||
	    (t.completion?.toFormat(`yyyy-LL-dd`) === dv.current().file.name)) {
		return true
	}
	return false
}

const tasks = dv.pages('"' + dv.current().file.folder + '"') // note the extra '"'
    .where(p => p.file.name < dv.current().file.name) // past daily files
	.file
	.tasks
	.where(selectTasks)

if (tasks.length !== 0) {
	dv.paragraph("---") // render hbar
	dv.taskList(tasks, false)
}
`` `

Every now and then there are parts of a post which triggers me, and this time it was the task within a given section, can that be extracted? So let us go on a journey together, related to this question. The journey consists of multiple stepscollapsable sections, so lets go.

My task list

Instead of spreading the task out into multiple files, I made one file, Task examples.md with this content:

### ToDo

- [ ] ToDo 1
- [ ] ToDo 2

### Not ToDo

  - [ ] Not ToDo 3
  - [ ] Not ToDo 4

Two tasks under the section “ToDo”, and two not under that section to be eliminated.

Base search for tasks

(For the rest of this post I’m going to post snippets and queries, which you can insert into any note, and see the result in the preview/reading view of that note. And I suggest you actually do that if you really want to see the progress, as it took place in my note.)

```dataview
TASK
WHERE file.name = "Task examples"
```

This lists all four tasks, as expected. But from prior knowledge I do know that there exists some extra information related to tasks, so lets go hunting for that information.

All details for a random task

My next step in such a journey is then to switch to a table query, and list all information available for either item I’m working with, in this case a task.

```dataview
TABLE WITHOUT ID  t
FLATTEN file.tasks as t
WHERE file.name = "Task examples"
LIMIT 1
```

I knew from prior experience that file.tasks would give me a list, so I used FLATTEN on it to get each task as a separate row, and I added LIMIT 1 at the end, just to get just one row of result.

I snipped the top part of this result, which gave me:
image
And here I see that both the section- and link-links contains the ToDo header I’m looking for. Interesting. I also see the task text, in the text variable, so now I’m ready for a slightly tighter search.

From earlier runs, I’ve also discovered that doing meta() on a link, reveals more information about the link, so let’s do that on section.

The key information to succeed with this query
TABLE WITHOUT ID
T.text, meta(T.section)
FLATTEN file.tasks as T
WHERE file.name = "Task examples"
LIMIT 1

Which gives me:
image

So, meta(T.section).subpath, will give me the header, if it exists. Nice.

Can I now list info on one task from that section?
## List only from ToDo section

```dataview
LIST WITHOUT ID T.text
FLATTEN file.tasks as T
WHERE file.name = "Task examples"
  AND meta(T.section).subpath = "ToDo"
```

image

We’re almost there, now only to apply the same where clause in a task query…

Detour before task query

I wasn’t quite sure which information was available in the task query, and it’s the least informative query, as you can’t add many extra fields for debugging, so I took a little detour via dataviewJS to utilise the Console of Developers Tools. Very useful.

```dataviewjs
const tasks = await dv.query(`task where file.name = "Task examples"`)
console.log(tasks)
```

This gave me the following:

And from this I can read that it’s not file.tasks.section, nor tasks.section, nor …, but actually just section which gives me the section link within a task query. Similarily I could pull the text field if I wanted to, and all (or most of) the other variables shown beneath the 0: header in the image.

This all leads up to the following basic query to search for tasks belonging to a given ToDo section:

## Task only from ToDo section

```dataview
TASK 
WHERE file.name = "Task examples"
  AND meta(section).subpath = "ToDo"
```

And it sure does:
image

Final adaption into a dataviewJS query

This journey started out with a dataviewJS query, so lets do the final adaption into a similar query, just to see how to handle the meta() within that format, and we get this query:

```dataviewjs
## Task only from ToDo section, DVJS

const tasks = dv.pages(`"${ dv.current().file.folder }"`)
    .where (p => p.file.name == "Task examples")
    .file.tasks
    .where(t => t.section?.subpath == "ToDo")

dv.taskList(tasks, false)
```

Notice the usage of t.section?.subpath, in an attempt to make it a little more robust in case it’s not enclosed in a section. Not sure if it matters, or not. But the output is still:
image

So there you have a rather long and windy post, proving that Yes, it’s possible to get tasks only from a given section. And I leave it to the reader to make something useful out of it, and to possibly negate the searches to get tasks outside of the given section.

Hope this is helpful to someone, with regards to how to deep dive into a “unknown” query, and how to locate useful information.

7 Likes

Thank you very much, kind stranger! I’m elated that it turned out to be that simple in the end :slight_smile:

1 Like

Superb as usual - thanks very much.

1 Like

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