DataviewJS - Changing Font Color of Task based on Tag

What I’m trying to do

I create notes for individual projects to manage todos. If there is a todo that I’m waiting on someone else for, I tag it with #WF.

I then have a master note that uses dataviewjs to sort all actions into project based lists of actions. It would be great to be able to change the color of the tasks tagged with #WF just to quickly flag for me that these are actions I’m waiting on someone else for. CSS style snippet will style the original task but it doesn’t style it within the dataviewjs query.

Note I’m trying to use dataviewjs, not dataview.

Thanks for any help!

Things I have tried

Searched a ton of forum threads and no one seems to have been interested in this before. Also spent a lot of time with Chat GPT but it couldn’t figure it out either.

```dataviewjs
const currentFilePath = dv.current().file.path;

const tasks = dv.pages()
    .where((page) => page.file.path.includes(currentFilePath))
    .file.tasks
    .where((t) => !t.completed && t.text.includes("#WF"));

if (tasks.length > 0) {
    dv.el("h2", "Waiting for");
    dv.taskList(tasks, false);
}

CSS styling is the way to go, but since your output is from within a dataviewjs your selectors have changed as opposed to ordinary markdown in live preview and/or reading mode.

This means that you need to use Developer Tools to find the new selectors to use, and/ or use dv.container to your script add extra classes.

Thank you so much for your help! When I try to use a dv.container though I still get an error. This is my datajsview script: As an experiment I’m trying to change tasks tagged with high priority emoji to red font

And here is the error I get

const today = DateTime.now().toISODate();

const pagesWithTasks = dv.pages()
    .where((page) => page.tags && page.tags.includes("Active") && page.tags.includes("Incomplete") && page.tags.includes("Personal") && !page.tags.includes("BB"))
    .map(page => ({
        title: page.file.name,
        tasks: page.file.tasks.where((t) => {
            const taskText = t.text.replace(/-\s*\[\s*\]\s*/, '').trim();
            if (!taskText.includes("⏳")) {
                return !t.completed && (!t.due || dv.date(t.due).toISODate() <= today) && taskText !== "" && !taskText.includes("#Task-Input");
            } else {
                const scheduledDate = dv.date(taskText.match(/⏳\s*(\d{4}-\d{2}-\d{2})/)[1]).toISODate();
                return !t.completed && (!t.due || dv.date(t.due).toISODate() <= today) && scheduledDate <= today && taskText !== "" && !taskText.includes("#Task-Input");
            }
        })
    }))
    .filter(page => page.tasks.length > 0);

for (let page of pagesWithTasks) {
    dv.header(3, page.title);
    dv.taskList(page.tasks, false);

    // Add custom CSS styling for high-priority tasks
    page.tasks.forEach(task => {
        if (task.text.includes("⏫")) {
            // Use dv.container to add extra classes and style the task text color
            dv.container(`.markdown-embed[data-file="${page.title}"] .task-item`, (el) => {
                if (el.innerText.includes(task.text)) {
                    el.style.color = "red";
                }
            });
        }
    });
}

Evaluation Error: TypeError: dv.container is not a function
at eval (eval at (plugin:dataview), :27:16)
at Proxy.forEach (plugin:dataview:8233:13)
at eval (eval at (plugin:dataview), :24:16)
at DataviewInlineApi.eval (plugin:dataview:18404:16)
at evalInContext (plugin:dataview:18405:7)
at asyncEvalInContext (plugin:dataview:18415:32)
at DataviewJSRenderer.render (plugin:dataview:18436:19)
at DataviewRefreshableRenderer.maybeRefresh (plugin:dataview:18014:22)
at e.tryTrigger (app://obsidian.md/app.js:1:695499)
at e.trigger (app://obsidian.md/app.js:1:695432)

which I itnerpret to mean I dv.container isn’t supported

dv.container is an object where you can set some stuff, and in particular the classname associated with the output of this query. In the thread below, you can see one example of such usage (near the third line) where onechan adds the TaskTable class to the list, if it’s not there from before.

Then one could use CSS to target this particular query since we now know a class related to it.

Regarding the handling of high priority items, you would then rather change the visual element of a given task, and include some extra information, e.g. adding yet another class using <span> element or similar.

A similar example extending formatting for some of the elements using visual, see the thread below, where I first learned about this kind of trickery.

1 Like

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