Can a jQuery script be added to a dataviewjs snippet to change progress bar appearance?

I am running a dataviewjs snippet in a markdown file, specifically Obsidian, but I am not happy with the progess bar appearance, which uses green for 'barely started or bad' and red for 'finished or good'. I'd like to reverse that. I found a jQuery script that I think would help, but I can't make it work (extreme js rookie, here).

Here is the dataviewjs snippet:

const createProgressBar = (char_count, char_goal, words_count, words_goal) => { let percents = 0 if (char_goal != undefined) { percents = Math.round(char_count / char_goal * 100) else if (words_goal != undefined) { percents = Math.round(words_count / words_goal * 100) } dv.paragraph("<progress max=100 value=" + percents + "> </progress> " + percents + "%") } const getFirstSplit = (split) => { if (split.type == "tabs") { return split else if (split.type == "split") { return getFirstSplit(split.children[0]) } } let firstSplit = getFirstSplit(app.workspace.rootSplit) let current = firstSplit.children[firstSplit.currentTab].view.file if (current != null) { let page = dv.page(current.path) if (page != undefined) { let char_goal = page.char_goal let words_goal = page.words_goal let synopsis = page.synopsis let POV = page.pov let location = page.location let characters = page.characters let tags = page.tags let project = page.project let highlights if (project != undefined) { dv.header(4, "[[" + project + "]]") } if (synopsis != undefined) { dv.span("***") dv.header(5, "Synopsis") dv.span(synopsis) } if (POV != undefined) { dv.span("***") dv.header(5, "POV") dv.span(POV) } if (page.type == "writing scene") { let content = await dv.io.load(current.path) highlights = content.match(/==.*?==/g) content = content.replace(/^---\n.*?\n---/ms, "").trim().replaceAll("—", "").replaceAll(/[\n]+/mg, " ").replaceAll(/[ ]+/mg, " ").replaceAll("==", "").replaceAll("*", "").replaceAll("#", "") let words = content.split(" ") dv.span("***") dv.header(5, "Scene progress") if (words_goal != undefined) { dv.paragraph(words.length + " / " + words_goal + " words") } if (char_goal != undefined) { dv.paragraph(content.length + " / " + char_goal + " characters") } createProgressBar(content.length, char_goal, words.length, words_goal) } if (page.type == "writing project") { let path = '"' + page.file.folder + '"' let scenePages = dv.pages(path).filter(p => p.type == "writing scene") let words_count = 0 let char_count = 0 let scenesData = [] for (let scene of scenePages) { let sceneContent = await dv.io.load(scene.file.path) sceneContent = sceneContent.replace(/^---\n.*?\n---/ms, "").trim().replaceAll("—", "").replaceAll(/[\n]+/mg, " ").replaceAll(/[ ]+/mg, " ").replaceAll("==", "").replaceAll("*", "").replaceAll("#", "") let sceneWords = sceneContent.split(" ") words_count = words_count + sceneWords.length char_count = char_count + sceneContent.length scenesData.push({ words_count: sceneWords.length, char_count: sceneContent.length, link: scene.file.link, words_goal: scene.words_goal, char_goal: scene.char_goal }) } dv.span("***") dv.header(5, "Novel progress") if (words_goal != undefined) { dv.paragraph(words_count + " / " + words_goal + " words") } if (char_goal != undefined) { dv.paragraph(char_count + " / " + char_goal + " characters") } createProgressBar(char_count, char_goal, words_count, words_goal) dv.span("***") dv.header(5, "Scenes progress") scenesData.forEach(scene => { dv.span(scene.link) createProgressBar(scene.char_count, scene.char_goal, scene.words_count, scene.words_goal) }) } if (location != undefined) { dv.span("***") dv.header(5, "Location") dv.span(location.map(c => " [[" + c + "]]") + "") } if (characters != undefined) { dv.span("***") dv.header(5, "Characters") dv.span(characters.map(c => " [[" + c + "]]") + "") } if (tags != undefined) { dv.span("***") dv.header(5, "Tags") dv.span(tags.map(c => " #" + c) + "") } if (highlights != undefined) { highlights = highlights.map(h => h.replaceAll("==", "")) dv.span("***") dv.header(5, "Highlights") dv.paragraph(highlights) } } }

Here is the jQuery script:

$(document).ready(function() { const show_percent = true; var progressBars = $(".progress-bar"); for (i = 0; i < progressBars.length; i++) { var progress = $(progressBars[i]).attr("aria-valuenow"); $(progressBars[i]).width(progress + "%"); if (show_percent) { $(progressBars[i]).text(progress + "%"); } if (progress >= "90") { //90 and above $(progressBars[i]).addClass("bg-success"); else if (progress >= "30" && progress < "45") { $(progressBars[i]).addClass("bg-warning"); //From 30 to 44 else if (progress >= "45" && progress < "90") { $(progressBars[i]).addClass("bg-info"); //From 45 to 89 else { //29 and under $(progressBars[i]).addClass("bg-danger"); } } });

Is it possible to add the jquery to the dataview snippet, and if so, where and how would I do so?

I tried using the jQuery script with the attribute changed to match my dataviewjs parameters, but I got the following error message:

Evaluation Error: TypeError: Cannot set properties of undefined (setting '__k') at S$1 (plugin:dataview:14624:8423) at q$1 (plugin:dataview:14624:8598) at $ (plugin:dataview:14628:5017) at eval (eval at <anonymous> (plugin:dataview), <anonymous>:1:39) 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 DataviewJSRenderer.onload (plugin:dataview:18020:14) at e.load (app://)

1 Answer

I do NOT think jQuery is supported in Obsidian.

As an alternative, you can add the following CSS snippet

.progress-red::-webkit-progress-value { background-color: red !important;
}
.progress-orange::-webkit-progress-value { background-color: orange !important; }
.progress-greenyellow::-webkit-progress-value {
background-color: greenyellow !important;
}

And also tweak your JS createProgressBar as follows

const createProgressBar = (char_count, char_goal, words_count, words_goal) => { let percents = 0 if (char_goal != undefined) { percents = Math.round(char_count / char_goal * 100) } else if (words_goal != undefined) { percents = Math.round(words_count / words_goal * 100) } let color='red'; if(percents >=75) color = 'greenyellow'; else if(percents >=50) color = 'orange'; dv.paragraph(`<progress max=100 value=${percents}></progress> ${percents}% `)
}
createProgressBar(12, undefined, 30.8, 100)
createProgressBar(400, 500, 30.8, 100)
createProgressBar(400, undefined, 234, 423)

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

You Might Also Like