Live filtering of dataviewjs table

I figured the way to filter dataviewjs tables without editing the code, you need to only click the button. For it to work you also need the Buttons plugin and the Templater plugin.

Here is the demo:

demo

And here is the code. It’s a bit complicated, but I refactored it so it is easy enough to use and edit. You can add as many filters as you want to.

```dataviewjs
// Don't change this code

const {createButton} = app.plugins.plugins["buttons"]
const tp = app.plugins.plugins["templater-obsidian"].templater.current_functions_object

let current = dv.current()
let currentFile = app.vault.getAbstractFileByPath(current.file.path)

const changeFilter = async(prop) => {
  let propName = "filter-" + prop
  let values = pages.map(p => p[prop])
  values = [...new Set(values)]
  values.unshift("all")
  let val = await tp.system.suggester(values, values)
    app.fileManager.processFrontMatter(currentFile, (frontmatter) => { 
		frontmatter[propName] = val
	})
  }

const filterButton = async(name, prop) => {
  createButton({
	app, 
	el: this.container, 
	args: {
		name: name}, 
	clickOverride: {
		click: await changeFilter, 
		params: [prop]
	}
  })
}

const filterFunction = async(prop) => {
  let propName = "filter-" + prop
  let filter = current[propName]
  if (filter != "all" && filter != null) {
	filteredPages = filteredPages.filter(p => p[prop] == filter)
  }
}




// Only edit the code below

let pages = dv.pages('"Test folder"')
let filteredPages = [...pages]


// Apply filters
await filterFunction("color")
await filterFunction("number")

// Add filter buttons
await filterButton("Filter color", "color")
await filterButton("Filter number", "number")


let headers = ["Name", "Color", "Number"]
let rows = filteredPages.map(p => [p.file.link, p.color, p.number])

dv.table(headers, rows)
```

Unfortunately this code doesn’t support multiselect or complicated data formats, but it can be tweaked to support it probably.


Update: I actually liked this idea so much, that I decided to use the same principle to create pagination and also add new notes to the table. As a result I created absolutely monstous script, that is too big to put here, so you can find it on my Github.

Here is the demo:


Update: Okay, so I decided that that huge script was to hard to reuse, so I separated it in two files, removing all the hard coding stuff into separate module.

Now if you want to use it, you need to download this file and put it to your vault, and then copy this code and put it in your dataviewjs codeblock. Now it is very straightforward and easy to edit, and I am pretty happy with this solution.

10 Likes

This is great. This is something I was tinkering with a while back (Filterable Dataview Table / Change Work Mode / Filter Note List), but js is above my pay grade. Your implementation is MUCH better.

I notice that the filters are persistent through note closings and even Obsidian restarts. How long will it stay filtered?

Actually, I think I found a bug; after testing the Obsidian restart, I am no longer able to click the buttons. Just nothing happens when I click.

Filters values are saved in the note frontmatter, so they will stay forever unless you click the buttons again or edit frontmatter manually.

If buttons don’t work after restart, it is problem with templater. I use templater’s functions for the suggester, but they don’t work untill some template is activated at least once. I recommend workaround: create empty template and set it as a startup template in templater’s options. Then everything should work after restart.

Filters values are saved in the note frontmatter, so they will stay forever unless you click the buttons again or edit frontmatter manually.

That’s clever. I really like that. I didn’t notice because I keep mine hidden.

If buttons don’t work after restart, it is problem with templater. I use templater’s functions for the suggester, but they don’t work untill some template is activated at least once. I recommend workaround: create empty template and set it as a startup template in templater’s options. Then everything should work after restart.

Thanks for the workaround. I’ll give that a shot.

I actually liked this idea so much, that I decided to use the same principle to create pagination and also add new notes to the table. And added the ability to filter by list properties too (only by one at once). As a result I created absolutely monstous script, that is too big to put here, so you can find it on my Github.

Here is the demo:

1 Like

Okay, so I decided that that huge script was to hard to reuse, so I separated it in two files, removing all the hard coding stuff into separate module.

Now if you want to use it, you need to download this file and put it to your vault, and then copy this code and put it in your dataviewjs codeblock. Now it is very straightforward and easy to edit, and I am pretty happy with this solution.

4 Likes

That is aaaawwesome!!! :slight_smile:
I hope that becomes a core feature!!! Great work! :slight_smile:

You really made an awesome feature

But can I customize the suggester?

You can, but you need to edit the main code file for this, and it’s not very convenient.
I’m currently in the process of rewriting the whole code to make it easier to use and customize without fiddling with javascript to much…

2 Likes