Velvet Star Monitor

Standout celebrity highlights with iconic style.

news

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

Writer Matthew Martinez

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.