Live filtering of dataviewjs table

I looked at your post, but I’m afraid, I didn’t understand much. Maybe it’s my poor understanding of English, but I’m just confused about what are you trying to do. I’m also not really that much of a technical person either, I just happen to know a bit of javascript.

The basic principles of my script are pretty simple. The table is filtered based on the value, stored in the frontmatter of the current note. Change the value - filtering is changed too. Than we add the button that changes the value in the frontmatter, so we have not to do it manually. The button script takes all the pages, finds the needed properties in them and creates the list of property values to suggest - then puts the chosen value to the frontmatter. Then there is a lot of code to create suggester modals, to apply the different rules for different types of properties, etc. What part are you exactly need help with?

About your question - your mean the button changing color? You need to apply some css to it. The active button gets the class “button-blue” (actually I justh thought that I should change it to something more semantic, but nevermind), then I add the snippet:

button.button-blue {
  background-color: rgba(102,140,179, .2);
  border-color: rgba(102,140,179, .4);
}

Я говорю на русском, поэтому предлагаю перейти на него. Извините за долгий ответ. К сожалению, ваш snippet у меня не действует. Я менял дизайн кнопки в вашей таблице только за счет изменения дефолтной кнопки. С изменением дизайна обычных кнопок проблем нет.

Кроме того, по какой-то причине у меня работает только ваша старая таблица. Новая версия с multiselection выдает ошибку:

И подскажите пожалуйста, как можно добавить фильтрацию страниц. В dataviewjs почти не разбираюсь.

Судя по ошибке, у вас скрипт вообще не подключился. Возможно, путь к файлу неправильно указан. Можете показать ваш код?

Со старой таблицей цвет кнопки работать и не будет, там не было этого функционала. Нужно класс к кнопке добавлять.

Сложно объяснять, как сделать пагинацию, если вы в джаваскрипте не разбираетесь. Это довольно большой кусок кода. Лучше всё-таки попробовать скрипт подключить нормально.

Я собственно ваш код и не менял. Я создал отдельное хранилище, объекты которого я сделал исходя из значений атрибутов в вашем коде. Видимо, я допустил какую-то примитивную ошибку)

```dataviewjs
await dv.view("_/scripts/views/dv_filter_functions")
const df = new dataviewFunctions
let current = dv.current()
let view = current.view
let views = ["View1", "View2"]
let defaultView = "View1"
let paginationNum = 20
let filteredPages = []
let props = []
let  newNote = {
		buttonName: "+", 
		fileName: "New note", 
		templatePath: "_/templates/New note.md", 
		folderName: "Inbox", 
		open: true
	}
let pages = dv.pages('"Test folder"')
 
await df.changeViewButton(views, "view", defaultView)

if (!view) view = defaultView



if (view == "View1") {

  pages = pages.filter(p => p.type == "type 1" )
  
  props = [
  {prop: "link", type: "file prop", header: "Name"},
  {prop: "tags", type: "list", multiSelect: true, span: true, buttonName: "Tags", header: "Tags"}
  ]
    
   newNote.templatePath = "_/templates/Template 1.md"
   newNote.folderName = "Folder 1"
 

} else if (view == "View2") {

  pages = pages.filter(p => p.type == "type 2" )
  
  props = [
  {prop: "link", type: "file prop", header: "Name"},
  {prop: "category", type: "text", buttonName: "Category", header: "Category"},
  {prop: "cover", type: "text", imageWidth: 100, header: "Cover"},
  {prop: "check", type: "boolean", header: "Check", buttonName: "Check"}
  ]
    
   newNote.templatePath = "_/templates/Template 2.md"
   newNote.folderName = "Folder 2"
 
}
 
filteredPages = [...pages]
await df.newEntryButton(newNote)
await df.createTable(props, pages, filteredPages, paginationNum)
```

You are using my path to the script file, but your file has different path. Change the first line to match your path:

await dv.view("scripts/views/dv_filter_functions")

Many thanks for the help. Sorry for the long response. Everything works, your table is cool and convenient. As I wrote above, I made a stupid mistake due to my carelessness (instead of “views” there was a “view”), I had previously removed the underscore.

Now back to my original difficult question. Today I added an explanation to topic about the classifier. I think now I managed to describe what exactly I want to do. If you want, I can send the Russian version wherever it is convenient for you.

In short, and keeping the focus only on your table, the task comes down to creating a variable in the FROM field (dv.pages), the value of which is set using a button, which in the worst case calls tp.system.prompt, in the field of which manually enter the hashtag code #UDC/x/x/x, and in the best case, call tp.system.suggester, which shows a hierarchical list of topics in text form (excluding user interaction with the digital hashtag code). It’s true that such functionality is not easy to achieve (the reason for the monstrosity of the diagram), but I think it’s worth it.

In addition, given the logic of your table with the Where field, where the Suggester list is formed based on a summary of all attribute values from all entities that match the value in the FROM field, adding the ability to influence the FROM value will result in filtering of attribute values in the Where fields, which in my opinion will significantly improve the efficiency of your table when you have a large number of entities and a large number of attribute values.

In any case, thanks for the existing table.

This is absolutely great!
I have two questions, though:

  • Is there a way to turn off pagination, i.e., remove the turn page buttons, too?
  • Can I style the buttons?

Thanks a lot!

I really like your feature, but I can’t implement it

I don’t understand which file or folder corresponds to the following code

fileName: "New note", 
templatePath: "_/templates/New note.md", 
folderName: "Inbox", 

I would like to know how to filter documents that contain the following two properties
properties name=keywords (type=list)
properties name=project (type=text)

Hello, everyone, I am back with the big update!

I completely rewrote all the code, so if you used the previus version, you will have to rewrite your tables to use the new one, but the good news are:

  • the code is more simple now;
  • there are some shiny new functions, the most important of which is — you can now edit properties directly from the table!

I also fixed some bugs, made rendering a bit faster and added ability to switch between table, cards and list views, and there are a couple of css-files to make it all look better. Also now the script requires to install the CustomJS plugin, but it is worth it. You can find the instructions how to install the new version here: obsidian-snippets/Dataview-interactive-tables/dvit-info-en.md at main · anareaty/obsidian-snippets · GitHub.

3 Likes

Тема. Сортировка по дате/другим свойствам, для отображения последних просмотренных сериалов. | Topic. Sort by date/other properties to display the most recently watched TV series.


[ru]

Привет! :fairy:t2: :wave:t2:
Благодарю вас за это замечательное дополнение, оно греет мне душу. :heart_hands:

Я уже адаптировал ваш пример под себя, для отслеживания просмотренных сериалов.


Как все выглядит.

Вот собственно код, который у меня получился:

---
show_search: true
pagination: 0
view: cards
tags: []
search: ""
 filter_rating: ★8
---

```dataviewjs

// Выберите и отфильтруйте страницы как обычно с помощью dataviewjs
let pages = dv.pages('"01 - Отслеживание/Просмотр/Сериалы"')

// Общие настройки представления

const settings = {
    "entries on page": false,
    "full width": true,
    "add new note button": true,
}

// Настройки свойств

const props = [
   {
    prop: "poster", 
    name: "Постер",
    image: true,
    width: 200,
    filter: false,
    column: true
  },
  
  {
    prop: "file.link", 
    name: "Название",
    filter: true,
    column: true
  },
  {
    prop: "director", 
    name: "Режисер",
    filter: true,
    column: true
  },
  {
    prop: "genre",
    name: "Жанр",
    filter: true,
    column: true
  },
  {
    prop: "kinopoisk",
    name: "Кинопоиск",
    filter: true,
    column: true
  },
  {
    prop: "rating",
    name: "Рейтинг",
    filter: true,
    column: true
  },
  {
    prop: "seasons",
    name: "Сезоны",
    filter: true,
    column: true
  },
  {
    prop: "dateo",
    name: "Год",
    filter: true,
    column: true
  },
  {
    prop: "fdate",
    name: "Просмотр",
    filter: true,
    column: true
  },
] 

await customJS.dvIT.renderView(settings, props, pages, dv)

Всё отлично работает, но есть одно но: “Сортировка по дате или по другим параметрам в режиме ‘cards’ не работает”.


Насколько я понимаю, значок в красном кружочке и выполняет эту функцию.

При наведении отображаются свойства которые были созданы, но при нажатии ничего не происходит:


Вот собственно и проблема.

Хотел бы у вас узнать, что можно сделать и нормально ли это? (Уж очень хочется сортировать сериалы от старых, до недавно просмотренных).

P.S Ещё раз спасибо за вашу работу.

Yeah, it seems that the Sortable plugin does not work with my script anymore, because it renders table as markdown.
I think I will have to write my own sorting function. I’ll try to fix it soon. For now you will have to write sorting directly in the code, like this:

let pages = dv.pages('"01 - Отслеживание/Просмотр/Сериалы"').sort(p => p["fdate"], "desc")

(Btw, it is against the rules of the forum to write in non-english languages, if you want to add something in Russian, you can write me an issue on Github).

1 Like

I added sorting.

1 Like

Thank you for your quick response.

And thank you for mentioning the rule about non-English languages, I will keep in mind.

Function request/Help with adding a new feature.

Hello again.
I’m still improving my database with your project and I still can’t get enough of it.

Now I have an idea to display the rating of TV series/movies/books in the “cards” mode using the card border.
This is how the borders look now (I edited the dvit-cards.css file):


Instead of gray borders, the borders of each card should be individual.

And I would like that when the property changes (for example, “Rating”, on a scale from 1 to 10), the border color for each of the cards also changes. For example, from 1 to 4 is red, from 5 to 6 is gray, and from 7 to 10 is green.

That’s how I see it roughly:


The rating is 4, so the border color is red.

The rating is 6, so the border color is gray.

Rating is 7.2, so the border color is green.

So that the color at the borders of each card changes individually and independently of each other and depends on the property.

Please tell me, is it possible to implement this function?
Thank you very much in advance.

You can add span: true to your rating property. It will wrap you rating into the span tag with class, and then you can use this class in css.
For example, if your rating value is “3”, you can use this css:

tr:has(.dv-tag-3) {
box-shadow: 0px 0px 0px 3px red;
}

But you will need to write css for every separate value.

1 Like

Hello, I have a quite unique way of using your script. Instead of having a catalogue of pages, I’m transitioning my movies collection into a single csv file (the whole setup with getting the data and saving it is fine so don’t worry about it). Pretty much everything works except I can’t quite figure out how to properly filter my list items:


// DataviewJS code to replicate the provided Dataview query 
const movies = await dv.io.csv("movies-series-db.csv");
const sortedMovies = movies.sort(movie => movie.title);

const moviePages = sortedMovies.map(movie => {
	return { 
		file: { path: movie.title, name: movie.title },
		poster: movie.poster,
		title: movie.title,
		year: movie.year,
		country: movie.country.split(',').map(c => `${c.trim().replace(/\s+/g, '')}`),
		genre: movie.genre.split(',').map(g => `${g.trim().replace(/\s+/g, '')}`),
		imdbRating: `⭐ ${movie.imdbRating}`,
		myRating: `${movie.rating}`
	}; 
});


// General view settings
const settings = {
    "entries on page": 10,
    "cards image position": "horizontal",
    "full width": true,
}

// Properties settings
const props = [
	{
		"prop": "title",
		"name": "Title",
		"filter": true,
		"column": true
	},
	{
		"prop": "poster",
		"name": "Poster",
		"image": true,
		"column": true
	},
	{
		"prop": "year",
		"name": "Year",
		"filter": true,
		"column": true
	},
	{
		"prop": "country",
		"name": "Country",
		"filter": true,
		"column": true,
		"multiSelect": true
	},
	{
		"prop": "genre",
		"name": "Genre",
		"filter": true,
		"column": true,
		"multiSelect": true
	},
	{
		"prop": "imdbRating",
		"name": "⭐ IMDB",
		"filter": true,
		"column": true
	},
	{
		"prop": "myRating",
		"name": "My rating",
		"filter": true,
		"column": true
	},
]

await customJS.dvIT.renderView(settings, props, moviePages, dv)

As you can see I’m basically tricking the script to think that moviePages are of the correct format that is returned by dv.pages() (Since I don’t have real pages). For country and genre columns/properties I return them as arrays of strings (from what I’ve debugged seems to be correct page structure), but when I try to filter I get this error:

image

That’s because the suggester function gets these as a value:
image

I know that’s wrong because when I tested it for another page, the categories should be split up like: “all”, “-”, “Action”, “Comedy”, … instead of having them as arrays here.

Any immediate tips for that problem or where I could trace the issue? Thanks.

I’m not really sure I understand how your csv thing works, but your bug seems to be related to the script not being able to figure out the property type correctly. Normally it gets the type saved in Obsidian, but if you don’t have any or it has inconsistent formattings, the script will not know your property is a list, so it will try to treat it as the text property instead.

You may try to add the properties to some other Obsidian note with the correct types or you can try to edit the function “getPropType” in the script.

Awesome! I made it work by hardcoding additional propTypes, now it works flawlessly thanks :slight_smile:

I’ve been trying the latest version for about a week. There are many great new features, especially editing properties directly from the table. But it doesn’t seem to work on inline properties. I tried with the metadata menu and it didn’t work. Can this be solved by slightly changing the JS script?
And one more thing, the “View change” feature in the previous version, I’ve lowkey become dependent on that feature. If I want to add that feature to the latest version, do I have to change the entire JS script file?