From 2fe662ce2e3eefadb04aacef649c777cd552545e Mon Sep 17 00:00:00 2001 From: LynetteCullens <45722611+LynetteCullens@users.noreply.github.com> Date: Tue, 13 Aug 2024 16:33:48 -0500 Subject: [PATCH 1/9] Add files via upload --- .../Database Editor/Database Editor.md | 80 +++++++++++++++++++ .../Database Editor/Database/Acceleration.md | 21 +++++ .../Database Editor/Database/Force.md | 24 ++++++ .../Database/Gravitational Constant.md | 14 ++++ exampleVault/Database Editor/Database/Mass.md | 22 +++++ 5 files changed, 161 insertions(+) create mode 100644 exampleVault/Database Editor/Database Editor.md create mode 100644 exampleVault/Database Editor/Database/Acceleration.md create mode 100644 exampleVault/Database Editor/Database/Force.md create mode 100644 exampleVault/Database Editor/Database/Gravitational Constant.md create mode 100644 exampleVault/Database Editor/Database/Mass.md diff --git a/exampleVault/Database Editor/Database Editor.md b/exampleVault/Database Editor/Database Editor.md new file mode 100644 index 00000000..dce69821 --- /dev/null +++ b/exampleVault/Database Editor/Database Editor.md @@ -0,0 +1,80 @@ +--- +note title: + - Mass + - Force + - Acceleration +--- +# Select the files to edit their frontmatter + +`INPUT[inlineListSuggester(optionQuery("Database Editor/Database"), useLinks(false)):["note title"]]` + +# Generate Table With Editing Row and Rendered Row for Each File + +```js-engine +const currentFilePath = context.file.path; + +// Initialize Meta Bind plugin API +const mb = engine.getPlugin('obsidian-meta-bind-plugin').api; +const dv = engine.getPlugin('dataview').api; + +// Define bind targets for the frontmatter fields +const bindTargetTitle = mb.parseBindTarget('["note title"]', currentFilePath); +console.log(bindTargetTitle); +const columns = ["title", "Type", "mathLink", "parent", "related", "dimensions", "staticdimensions", "Dimensions", "MKS", "CGS", "FPS", "Formula"]; +const lines = ["title", "Type", "mathLink", "parent", "related", "dimensions", "staticdimensions", "mathLink-blocks.Dimensions", "mathLink-blocks.MKS", "mathLink-blocks.CGS", "mathLink-blocks.FPS", "mathLink-blocks.Formula"]; + +function updateFrontmatter(newContent) { + mb.updateMetadata(bindTargetTitle, () => newContent); +} + +function createWrappedInputField(inputType, filePath, container, component) { + const div = container.createDiv(); + const inputField = mb.createInlineFieldFromString(inputType, filePath, undefined); + mb.wrapInMDRC(inputField, div, component); + return div; +} + +return mb.reactiveMetadata([bindTargetTitle], component, async (titleList) => { + if (!titleList || !Array.isArray(titleList) || titleList.length === 0) { + new Notice("Title list is undefined, not an array, or empty"); + return; + } + + let markdownTable = ` +| ${columns.map(c => `${c}:`).join(' | ')} | +| ${columns.map(() => '---').join(' | ')} |`; + + for (const title of titleList) { + const page = dv.page(title); + if (!page || !page.file || !page.file.path) { + new Notice(`Invalid page or path for title "${title}"`); + continue; + } + + const inputFields = [ + createWrappedInputField(`INPUT[text:${title}#title]`, currentFilePath, container, component), + createWrappedInputField(`INPUT[inlineSelect(option(Variable), option(Sub_Variable), option(Dimension), option(Sub_Dimension), option(Vocabulary), option(Math_Operation), option(Constant), option(Folder)):${title}#Type]`, currentFilePath, container, component), + createWrappedInputField(`INPUT[text:${title}#mathLink]`, currentFilePath, container, component), + createWrappedInputField(`INPUT[inlineListSuggester(optionQuery("Database"), useLinks(partial)):${title}#parent]`, currentFilePath, container, component), + createWrappedInputField(`INPUT[inlineListSuggester(optionQuery("Database"), useLinks(partial)):${title}#related]`, currentFilePath, container, component), + createWrappedInputField(`INPUT[inlineListSuggester(optionQuery("Database"), useLinks(partial)):${title}#dimensions]`, currentFilePath, container, component), + createWrappedInputField(`INPUT[inlineListSuggester(optionQuery("Database"), useLinks(partial)):${title}#staticdimensions]`, currentFilePath, container, component), + createWrappedInputField(`INPUT[text:${title}#mathLink-blocks.Dimensions]`, currentFilePath, container, component), + createWrappedInputField(`INPUT[text:${title}#mathLink-blocks.MKS]`, currentFilePath, container, component), + createWrappedInputField(`INPUT[text:${title}#mathLink-blocks.CGS]`, currentFilePath, container, component), + createWrappedInputField(`INPUT[text:${title}#mathLink-blocks.FPS]`, currentFilePath, container, component), + createWrappedInputField(`INPUT[text:${title}#mathLink-blocks.Formula]`, currentFilePath, container, component), + ]; + + const viewColumns = lines.map(l => `\`VIEW[{${title}#${l}}][text(renderMarkdown)]\``); + + const inputRow = inputFields.map(field => field.outerHTML).join(' | '); + const viewRow = viewColumns.join(' | '); + + markdownTable += `\n| ${inputRow} |\n| ${viewRow} |`; + } + + new Notice("Markdown table generated successfully"); + return engine.markdown.create(markdownTable); +}); +``` diff --git a/exampleVault/Database Editor/Database/Acceleration.md b/exampleVault/Database Editor/Database/Acceleration.md new file mode 100644 index 00000000..3dc9fadb --- /dev/null +++ b/exampleVault/Database Editor/Database/Acceleration.md @@ -0,0 +1,21 @@ +--- +parent: + - "[[Length#^Dimensions]]" + - "[[Time#^Dimensions]]" +dimensions: + - "[[Length#^Dimensions]]" + - "[[Time#^Dimensions]]" +related: + - "[[Force]]" + - "[[Gravitational Constant]]" + - "[[Mass]]" +mathLink: ${\color{red}a}\left[\pu{m//s2},\pu{cm//s2},\pu{ft//s2} \right]$ +mathLink-blocks: + MKS: ${\color{red}a}[\pu{m//s2}]$ + CGS: ${\color{red}a}[\pu{cm//s2}]$ + FPS: ${\color{red}a}[\pu{ft//s2}]$ + Dimensions: $\left[ \frac{\boldsymbol{L}}{\boldsymbol{T}^{2}} \right]$ + Formula: ${\color{red}a}\left[\pu{m//s2},\pu{cm//s2},\pu{ft//s2} \right]=\frac{{\boldsymbol{F}[\pu{N},\pu{dyn},\pu{lb_{f}}]*{\color{blue}g}_{c}[\pu{1kg*m//N*s2}][\pu{32.2lb_{m}*ft//lb_{f}*s2}]}}{\boldsymbol{M}[\pu{kg},\pu{g},lb_{m}]}$ +Type: Variable +title: Acceleration +--- diff --git a/exampleVault/Database Editor/Database/Force.md b/exampleVault/Database Editor/Database/Force.md new file mode 100644 index 00000000..d16f386b --- /dev/null +++ b/exampleVault/Database Editor/Database/Force.md @@ -0,0 +1,24 @@ +--- +related: + - "[[Mass]]" + - "[[Acceleration]]" + - "[[Gravitational Constant]]" +mathLink: $\boldsymbol{F}[\pu{N},\pu{dyn},\pu{lb_{f}}]$ +mathLink-blocks: + Dimensions: $\left[ \frac{\boldsymbol{ML}}{\boldsymbol{T}^{2}} \right]$ + StaticDimensions: $\boldsymbol{F}$ + MKS: $\boldsymbol{F}[\pu{N},\pu{kg*m//s2}]$ + CGS: $\boldsymbol{F}[\pu{dyn},\pu{g*cm//s2}]$ + FPS: $\boldsymbol{F}[\pu{lb_{f}},\pu{lb_{m}*ft//s2}]$ + Formula: $\boldsymbol{F}[\pu{N},\pu{dyn},\pu{lb_{f}}]=\frac{\boldsymbol{M}[\pu{kg},\pu{g},lb_{m}]*{\color{red}a}\left[\pu{m//s2},\pu{cm//s2},\pu{ft//s2} \right]}{{{\color{blue}g}_{c}[\pu{1kg*m//N*s2}][\pu{32.2lb_{m}*ft//lb_{f}*s2}]}}$ +parent: + - "[[Mass#^Dimensions]]" + - "[[Length#^Dimensions]]" + - "[[Time#^Dimensions]]" +Type: Sub_Dimension +title: Force +dimensions: + - "[[Mass#^Dimensions]]" + - "[[Length#^Dimensions]]" + - "[[Time#^Dimensions]]" +--- diff --git a/exampleVault/Database Editor/Database/Gravitational Constant.md b/exampleVault/Database Editor/Database/Gravitational Constant.md new file mode 100644 index 00000000..0585e512 --- /dev/null +++ b/exampleVault/Database Editor/Database/Gravitational Constant.md @@ -0,0 +1,14 @@ +--- +related: + - "[[Mass]]" + - "[[Acceleration]]" + - "[[Force]]" +parent: + - "[[Constant|Constant]]" +fileClass: Variables +mathLink-blocks: + Formula: ${{\color{blue}g}_{c}[\pu{1kg*m//N*s2}][\pu{32.2lb_{m}*ft//lb_{f}*s2}]}=\frac{\boldsymbol{M}[\pu{kg},\pu{g},lb_{m}]*{\color{red}a}\left[\pu{m//s2},\pu{cm//s2},\pu{ft//s2} \right]}{\boldsymbol{F}[\pu{N},\pu{dyn},\pu{lb_{f}}]}$ +mathLink: ${\color{blue}g}_{c}[\pu{1kg*m//N*s2}][\pu{32.2lb_{m}*ft//lb_{f}*s2}]$ +Type: Constant +title: Gravitational Constant +--- diff --git a/exampleVault/Database Editor/Database/Mass.md b/exampleVault/Database Editor/Database/Mass.md new file mode 100644 index 00000000..2d480900 --- /dev/null +++ b/exampleVault/Database Editor/Database/Mass.md @@ -0,0 +1,22 @@ +--- +parent: + - "[[Glossary/Dimension/Dimension|Dimension]]" +mathLink: $\boldsymbol{M}[\pu{kg},\pu{g},lb_{m}]$ +mathLink-blocks: + MKS: $\boldsymbol{M}[\pu{kg},\pu{N*s2//m}]$ + CGS: $\boldsymbol{M}[\pu{g},\pu{erg*s2//cm}]$ + FPS: $\boldsymbol{M}[\pu{lb_{m}},\pu{lb_{f}*s2//ft}]$ + Dimensions: $\boldsymbol{M}$ + StaticDimensions: $\left[ \frac{\boldsymbol{FT^2}}{\boldsymbol{L}} \right]$ + Formula: $\boldsymbol{M}[\pu{kg},\pu{g},lb_{m}]=\frac{\boldsymbol{F}[\pu{N},\pu{dyn},\pu{lb_{f}}]*{{\color{blue}g}_{c}[\pu{1kg*m//N*s2}][\pu{32.2lb_{m}*ft//lb_{f}*s2}]}}{{\color{red}a}\left[\pu{m//s2},\pu{cm//s2},\pu{ft//s2} \right]}$ +Type: Dimension +staticdimensions: + - "[[Force#^StaticDimensions]]" + - "[[Time#^Dimensions]]" + - "[[Length#^Dimensions]]" +title: Mass +related: + - "[[Force]]" + - "[[Gravitational Constant]]" + - "[[Acceleration]]" +--- From a91e63e58757f2ecc916d1289a25771bf8786404 Mon Sep 17 00:00:00 2001 From: LynetteCullens <45722611+LynetteCullens@users.noreply.github.com> Date: Tue, 13 Aug 2024 16:54:55 -0500 Subject: [PATCH 2/9] Update Database Editor.md Fixed the file path from note title function to work with the input/view fields --- .../Database Editor/Database Editor.md | 44 ++++++++++++------- 1 file changed, 28 insertions(+), 16 deletions(-) diff --git a/exampleVault/Database Editor/Database Editor.md b/exampleVault/Database Editor/Database Editor.md index dce69821..b92dbf6a 100644 --- a/exampleVault/Database Editor/Database Editor.md +++ b/exampleVault/Database Editor/Database Editor.md @@ -17,7 +17,6 @@ const currentFilePath = context.file.path; const mb = engine.getPlugin('obsidian-meta-bind-plugin').api; const dv = engine.getPlugin('dataview').api; -// Define bind targets for the frontmatter fields const bindTargetTitle = mb.parseBindTarget('["note title"]', currentFilePath); console.log(bindTargetTitle); const columns = ["title", "Type", "mathLink", "parent", "related", "dimensions", "staticdimensions", "Dimensions", "MKS", "CGS", "FPS", "Formula"]; @@ -51,30 +50,43 @@ return mb.reactiveMetadata([bindTargetTitle], component, async (titleList) => { continue; } - const inputFields = [ - createWrappedInputField(`INPUT[text:${title}#title]`, currentFilePath, container, component), - createWrappedInputField(`INPUT[inlineSelect(option(Variable), option(Sub_Variable), option(Dimension), option(Sub_Dimension), option(Vocabulary), option(Math_Operation), option(Constant), option(Folder)):${title}#Type]`, currentFilePath, container, component), - createWrappedInputField(`INPUT[text:${title}#mathLink]`, currentFilePath, container, component), - createWrappedInputField(`INPUT[inlineListSuggester(optionQuery("Database"), useLinks(partial)):${title}#parent]`, currentFilePath, container, component), - createWrappedInputField(`INPUT[inlineListSuggester(optionQuery("Database"), useLinks(partial)):${title}#related]`, currentFilePath, container, component), - createWrappedInputField(`INPUT[inlineListSuggester(optionQuery("Database"), useLinks(partial)):${title}#dimensions]`, currentFilePath, container, component), - createWrappedInputField(`INPUT[inlineListSuggester(optionQuery("Database"), useLinks(partial)):${title}#staticdimensions]`, currentFilePath, container, component), - createWrappedInputField(`INPUT[text:${title}#mathLink-blocks.Dimensions]`, currentFilePath, container, component), - createWrappedInputField(`INPUT[text:${title}#mathLink-blocks.MKS]`, currentFilePath, container, component), - createWrappedInputField(`INPUT[text:${title}#mathLink-blocks.CGS]`, currentFilePath, container, component), - createWrappedInputField(`INPUT[text:${title}#mathLink-blocks.FPS]`, currentFilePath, container, component), - createWrappedInputField(`INPUT[text:${title}#mathLink-blocks.Formula]`, currentFilePath, container, component), + const inputColumns = [ + `\`INPUT[text:${title}#title]\``, + `\`INPUT[inlineSelect(option(Variable), option(Sub_Variable), option(Dimension), option(Sub_Dimension), option(Vocabulary), option(Math_Operation), option(Constant), option(Folder)):${title}#Type]\``, + `\`INPUT[text:${title}#mathLink]\``, + `\`INPUT[inlineListSuggester(optionQuery("Glossary"), useLinks(partial)):${title}#parent]\``, + `\`INPUT[inlineListSuggester(optionQuery("Glossary"), useLinks(partial)):${title}#related]\``, + `\`INPUT[inlineListSuggester(optionQuery("Glossary"), useLinks(partial)):${title}#dimensions]\``, + `\`INPUT[inlineListSuggester(optionQuery("Glossary"), useLinks(partial)):${title}#staticdimensions]\``, + `\`INPUT[text:${title}#mathLink-blocks.Dimensions]\``, + `\`INPUT[text:${title}#mathLink-blocks.MKS]\``, + `\`INPUT[text:${title}#mathLink-blocks.CGS]\``, + `\`INPUT[text:${title}#mathLink-blocks.FPS]\``, + `\`INPUT[text:${title}#mathLink-blocks.Formula]\``, ]; const viewColumns = lines.map(l => `\`VIEW[{${title}#${l}}][text(renderMarkdown)]\``); - const inputRow = inputFields.map(field => field.outerHTML).join(' | '); + const inputRow = inputColumns.join(' | '); const viewRow = viewColumns.join(' | '); markdownTable += `\n| ${inputRow} |\n| ${viewRow} |`; } new Notice("Markdown table generated successfully"); - return engine.markdown.create(markdownTable); + const markdownElement = engine.markdown.create(markdownTable); + + // Wrap each input field in MDRC after rendering + setTimeout(() => { + const inputFields = markdownElement.querySelectorAll('span.cm-inline-code'); + inputFields.forEach(field => { + const div = document.createElement('div'); + field.parentNode.insertBefore(div, field); + div.appendChild(field); + mb.wrapInMDRC(field, div, component); + }); + }, 0); + + return markdownElement; }); ``` From 9bc6a2c063260cc5fd61fb4ea81660cb59f1256f Mon Sep 17 00:00:00 2001 From: LynetteCullens <45722611+LynetteCullens@users.noreply.github.com> Date: Wed, 14 Aug 2024 16:45:21 -0500 Subject: [PATCH 3/9] Update Database Editor.md Got rid of the set time out that did nothing --- .../Database Editor/Database Editor.md | 121 +++++++++++------- 1 file changed, 72 insertions(+), 49 deletions(-) diff --git a/exampleVault/Database Editor/Database Editor.md b/exampleVault/Database Editor/Database Editor.md index b92dbf6a..ed80d821 100644 --- a/exampleVault/Database Editor/Database Editor.md +++ b/exampleVault/Database Editor/Database Editor.md @@ -17,32 +17,22 @@ const currentFilePath = context.file.path; const mb = engine.getPlugin('obsidian-meta-bind-plugin').api; const dv = engine.getPlugin('dataview').api; +// Define bind targets for the frontmatter fields const bindTargetTitle = mb.parseBindTarget('["note title"]', currentFilePath); -console.log(bindTargetTitle); + const columns = ["title", "Type", "mathLink", "parent", "related", "dimensions", "staticdimensions", "Dimensions", "MKS", "CGS", "FPS", "Formula"]; const lines = ["title", "Type", "mathLink", "parent", "related", "dimensions", "staticdimensions", "mathLink-blocks.Dimensions", "mathLink-blocks.MKS", "mathLink-blocks.CGS", "mathLink-blocks.FPS", "mathLink-blocks.Formula"]; -function updateFrontmatter(newContent) { - mb.updateMetadata(bindTargetTitle, () => newContent); -} - -function createWrappedInputField(inputType, filePath, container, component) { - const div = container.createDiv(); - const inputField = mb.createInlineFieldFromString(inputType, filePath, undefined); - mb.wrapInMDRC(inputField, div, component); - return div; -} - return mb.reactiveMetadata([bindTargetTitle], component, async (titleList) => { if (!titleList || !Array.isArray(titleList) || titleList.length === 0) { new Notice("Title list is undefined, not an array, or empty"); return; } - let markdownTable = ` -| ${columns.map(c => `${c}:`).join(' | ')} | -| ${columns.map(() => '---').join(' | ')} |`; + const container = component.containerEl; + // Create and store input fields + const inputFields = []; for (const title of titleList) { const page = dv.page(title); if (!page || !page.file || !page.file.path) { @@ -50,43 +40,76 @@ return mb.reactiveMetadata([bindTargetTitle], component, async (titleList) => { continue; } - const inputColumns = [ - `\`INPUT[text:${title}#title]\``, - `\`INPUT[inlineSelect(option(Variable), option(Sub_Variable), option(Dimension), option(Sub_Dimension), option(Vocabulary), option(Math_Operation), option(Constant), option(Folder)):${title}#Type]\``, - `\`INPUT[text:${title}#mathLink]\``, - `\`INPUT[inlineListSuggester(optionQuery("Glossary"), useLinks(partial)):${title}#parent]\``, - `\`INPUT[inlineListSuggester(optionQuery("Glossary"), useLinks(partial)):${title}#related]\``, - `\`INPUT[inlineListSuggester(optionQuery("Glossary"), useLinks(partial)):${title}#dimensions]\``, - `\`INPUT[inlineListSuggester(optionQuery("Glossary"), useLinks(partial)):${title}#staticdimensions]\``, - `\`INPUT[text:${title}#mathLink-blocks.Dimensions]\``, - `\`INPUT[text:${title}#mathLink-blocks.MKS]\``, - `\`INPUT[text:${title}#mathLink-blocks.CGS]\``, - `\`INPUT[text:${title}#mathLink-blocks.FPS]\``, - `\`INPUT[text:${title}#mathLink-blocks.Formula]\``, - ]; - - const viewColumns = lines.map(l => `\`VIEW[{${title}#${l}}][text(renderMarkdown)]\``); - - const inputRow = inputColumns.join(' | '); - const viewRow = viewColumns.join(' | '); - - markdownTable += `\n| ${inputRow} |\n| ${viewRow} |`; + const path = page.file.path; + console.log(`Processing title: ${title}, Path: ${path}`); + + const titleInputs = columns.map(column => { + let inputString; + switch (column) { + case "Type": + inputString = `INPUT[inlineSelect(option(Variable), option(Sub_Variable), option(Dimension), option(Sub_Dimension), option(Vocabulary), option(Math_Operation), option(Constant), option(Folder)):${title}#Type]`; + break; + case "parent": + case "related": + case "dimensions": + case "staticdimensions": + inputString = `INPUT[inlineListSuggester(optionQuery("Glossary"), useLinks(partial)):${title}#${column}]`; + break; + default: + inputString = `INPUT[text:${title}#${column.startsWith('mathLink-blocks.') ? column : column.toLowerCase()}]`; + } + + const div = container.createDiv(); + try { + const inputField = mb.createInlineFieldFromString(inputString, path); + mb.wrapInMDRC(inputField, div, component); + return div; + } catch (error) { + console.error(`Error creating input field for ${inputString}:`, error); + div.textContent = `Error: ${error.message}`; + return div; + } + }); + inputFields.push(titleInputs); } - new Notice("Markdown table generated successfully"); - const markdownElement = engine.markdown.create(markdownTable); - - // Wrap each input field in MDRC after rendering - setTimeout(() => { - const inputFields = markdownElement.querySelectorAll('span.cm-inline-code'); - inputFields.forEach(field => { - const div = document.createElement('div'); - field.parentNode.insertBefore(div, field); - div.appendChild(field); - mb.wrapInMDRC(field, div, component); + // Create table structure + const table = container.createEl('table'); + const tableHead = table.createEl('thead'); + const headerRow = tableHead.createEl('tr'); + columns.forEach(column => { + const th = headerRow.createEl('th'); + th.textContent = column; + }); + + const tableBody = table.createEl('tbody'); + + // Populate table with input fields and views + inputFields.forEach((titleInputs, index) => { + const inputRow = tableBody.createEl('tr'); + titleInputs.forEach((inputDiv, colIndex) => { + const td = inputRow.createEl('td'); + td.appendChild(inputDiv); + }); + + const viewRow = tableBody.createEl('tr'); + lines.forEach((line, colIndex) => { + const td = viewRow.createEl('td'); + const title = titleList[index]; + const viewString = `VIEW[{${title}#${line}}][text(renderMarkdown)]`; + const viewDiv = container.createDiv(); + try { + const viewField = mb.createInlineFieldFromString(viewString, currentFilePath); + mb.wrapInMDRC(viewField, viewDiv, component); + td.appendChild(viewDiv); + } catch (error) { + console.error(`Error creating view field for ${viewString}:`, error); + td.textContent = `Error: ${error.message}`; + } }); - }, 0); + }); - return markdownElement; + new Notice("Table generated successfully"); + return table; }); ``` From 5156ca258a15a2b546abec74966edd62017b241d Mon Sep 17 00:00:00 2001 From: LynetteCullens <45722611+LynetteCullens@users.noreply.github.com> Date: Wed, 14 Aug 2024 16:49:34 -0500 Subject: [PATCH 4/9] Add files via upload --- exampleVault/Database Editor/Database/Acceleration.md | 10 +++------- exampleVault/Database Editor/Database/Force.md | 4 ---- .../Database Editor/Database/Gravitational Constant.md | 5 ++--- exampleVault/Database Editor/Database/Mass.md | 5 +---- 4 files changed, 6 insertions(+), 18 deletions(-) diff --git a/exampleVault/Database Editor/Database/Acceleration.md b/exampleVault/Database Editor/Database/Acceleration.md index 3dc9fadb..bec3bb4a 100644 --- a/exampleVault/Database Editor/Database/Acceleration.md +++ b/exampleVault/Database Editor/Database/Acceleration.md @@ -1,16 +1,12 @@ --- -parent: - - "[[Length#^Dimensions]]" - - "[[Time#^Dimensions]]" -dimensions: - - "[[Length#^Dimensions]]" - - "[[Time#^Dimensions]]" +parent: [] +dimensions: related: - "[[Force]]" - "[[Gravitational Constant]]" - "[[Mass]]" mathLink: ${\color{red}a}\left[\pu{m//s2},\pu{cm//s2},\pu{ft//s2} \right]$ -mathLink-blocks: +mathLink-blocks: MKS: ${\color{red}a}[\pu{m//s2}]$ CGS: ${\color{red}a}[\pu{cm//s2}]$ FPS: ${\color{red}a}[\pu{ft//s2}]$ diff --git a/exampleVault/Database Editor/Database/Force.md b/exampleVault/Database Editor/Database/Force.md index d16f386b..0c719ba4 100644 --- a/exampleVault/Database Editor/Database/Force.md +++ b/exampleVault/Database Editor/Database/Force.md @@ -13,12 +13,8 @@ mathLink-blocks: Formula: $\boldsymbol{F}[\pu{N},\pu{dyn},\pu{lb_{f}}]=\frac{\boldsymbol{M}[\pu{kg},\pu{g},lb_{m}]*{\color{red}a}\left[\pu{m//s2},\pu{cm//s2},\pu{ft//s2} \right]}{{{\color{blue}g}_{c}[\pu{1kg*m//N*s2}][\pu{32.2lb_{m}*ft//lb_{f}*s2}]}}$ parent: - "[[Mass#^Dimensions]]" - - "[[Length#^Dimensions]]" - - "[[Time#^Dimensions]]" Type: Sub_Dimension title: Force dimensions: - "[[Mass#^Dimensions]]" - - "[[Length#^Dimensions]]" - - "[[Time#^Dimensions]]" --- diff --git a/exampleVault/Database Editor/Database/Gravitational Constant.md b/exampleVault/Database Editor/Database/Gravitational Constant.md index 0585e512..5bfc322d 100644 --- a/exampleVault/Database Editor/Database/Gravitational Constant.md +++ b/exampleVault/Database Editor/Database/Gravitational Constant.md @@ -3,11 +3,10 @@ related: - "[[Mass]]" - "[[Acceleration]]" - "[[Force]]" -parent: - - "[[Constant|Constant]]" +parent: [] fileClass: Variables mathLink-blocks: - Formula: ${{\color{blue}g}_{c}[\pu{1kg*m//N*s2}][\pu{32.2lb_{m}*ft//lb_{f}*s2}]}=\frac{\boldsymbol{M}[\pu{kg},\pu{g},lb_{m}]*{\color{red}a}\left[\pu{m//s2},\pu{cm//s2},\pu{ft//s2} \right]}{\boldsymbol{F}[\pu{N},\pu{dyn},\pu{lb_{f}}]}$ + Formula: ${{\color{blue}g}_{c}[\pu{1kg*m//N*s2}][\pu{32.2lb_{m}*ft//lb_{f}*s2}]}=\frac{\boldsymbol{M}[\pu{kg},\pu{g},lb_{m}]*{\color{red}a}\left[\pu{m//s2},\pu{cm//s2},\pu{ft//s2} \right]}{\boldsymbol{F}[\pu{N},\pu{dyn},\pu{lb_{f}}]}$ mathLink: ${\color{blue}g}_{c}[\pu{1kg*m//N*s2}][\pu{32.2lb_{m}*ft//lb_{f}*s2}]$ Type: Constant title: Gravitational Constant diff --git a/exampleVault/Database Editor/Database/Mass.md b/exampleVault/Database Editor/Database/Mass.md index 2d480900..2e555974 100644 --- a/exampleVault/Database Editor/Database/Mass.md +++ b/exampleVault/Database Editor/Database/Mass.md @@ -1,6 +1,5 @@ --- -parent: - - "[[Glossary/Dimension/Dimension|Dimension]]" +parent: [] mathLink: $\boldsymbol{M}[\pu{kg},\pu{g},lb_{m}]$ mathLink-blocks: MKS: $\boldsymbol{M}[\pu{kg},\pu{N*s2//m}]$ @@ -12,8 +11,6 @@ mathLink-blocks: Type: Dimension staticdimensions: - "[[Force#^StaticDimensions]]" - - "[[Time#^Dimensions]]" - - "[[Length#^Dimensions]]" title: Mass related: - "[[Force]]" From a10aa7373d33e4cd86862485ebcf6aafb10b2440 Mon Sep 17 00:00:00 2001 From: LynetteCullens <45722611+LynetteCullens@users.noreply.github.com> Date: Wed, 14 Aug 2024 20:43:29 -0500 Subject: [PATCH 5/9] Update Database Editor.md I don't recall what I changed since the site has been down. --- exampleVault/Database Editor/Database Editor.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/exampleVault/Database Editor/Database Editor.md b/exampleVault/Database Editor/Database Editor.md index ed80d821..e4794933 100644 --- a/exampleVault/Database Editor/Database Editor.md +++ b/exampleVault/Database Editor/Database Editor.md @@ -41,11 +41,11 @@ return mb.reactiveMetadata([bindTargetTitle], component, async (titleList) => { } const path = page.file.path; - console.log(`Processing title: ${title}, Path: ${path}`); + //console.log(`Processing title: ${title}, Path: ${path}`); - const titleInputs = columns.map(column => { + const titleInputs = lines.map(lines => { let inputString; - switch (column) { + switch (lines) { case "Type": inputString = `INPUT[inlineSelect(option(Variable), option(Sub_Variable), option(Dimension), option(Sub_Dimension), option(Vocabulary), option(Math_Operation), option(Constant), option(Folder)):${title}#Type]`; break; @@ -53,10 +53,10 @@ return mb.reactiveMetadata([bindTargetTitle], component, async (titleList) => { case "related": case "dimensions": case "staticdimensions": - inputString = `INPUT[inlineListSuggester(optionQuery("Glossary"), useLinks(partial)):${title}#${column}]`; + inputString = `INPUT[inlineListSuggester(optionQuery("Glossary"), useLinks(partial)):${title}#${lines}]`; break; default: - inputString = `INPUT[text:${title}#${column.startsWith('mathLink-blocks.') ? column : column.toLowerCase()}]`; + inputString = `INPUT[text:${title}#${lines}]`; } const div = container.createDiv(); From aa38f1c3128469d936be3b18cbc32d4760ec82c6 Mon Sep 17 00:00:00 2001 From: LynetteCullens <45722611+LynetteCullens@users.noreply.github.com> Date: Fri, 16 Aug 2024 19:54:41 -0500 Subject: [PATCH 6/9] Update Database Editor.md --- .../Database Editor/Database Editor.md | 203 +++++++++++++++++- 1 file changed, 202 insertions(+), 1 deletion(-) diff --git a/exampleVault/Database Editor/Database Editor.md b/exampleVault/Database Editor/Database Editor.md index e4794933..26fc51f9 100644 --- a/exampleVault/Database Editor/Database Editor.md +++ b/exampleVault/Database Editor/Database Editor.md @@ -8,6 +8,8 @@ note title: `INPUT[inlineListSuggester(optionQuery("Database Editor/Database"), useLinks(false)):["note title"]]` + + # Generate Table With Editing Row and Rendered Row for Each File ```js-engine @@ -53,7 +55,7 @@ return mb.reactiveMetadata([bindTargetTitle], component, async (titleList) => { case "related": case "dimensions": case "staticdimensions": - inputString = `INPUT[inlineListSuggester(optionQuery("Glossary"), useLinks(partial)):${title}#${lines}]`; + inputString = `INPUT[inlineListSuggester(optionQuery("Database Editor"), useLinks(partial)):${title}#${lines}]`; break; default: inputString = `INPUT[text:${title}#${lines}]`; @@ -113,3 +115,202 @@ return mb.reactiveMetadata([bindTargetTitle], component, async (titleList) => { return table; }); ``` + +# Or Use Values Stored in Memory to Populate a Table with Filters + +```js-engine +const currentFilePath = context.file.path; + +// Initialize Meta Bind and Dataview plugin APIs +const mb = engine.getPlugin('obsidian-meta-bind-plugin').api; +const dv = engine.getPlugin('dataview').api; + +// Component for lifecycle management of fields +const comp = new obsidian.Component(component); + +// Extract unique options for each filter +const parentOptions = Array.from(new Set(dv.pages('"Database Editor"').flatMap(p => p.file.frontmatter.parent || []).filter(Boolean))); +const TypeOptions = Array.from(new Set(dv.pages('"Database Editor"').map(p => p.file.frontmatter.Type || '').filter(Boolean))); +const relatedOptions = Array.from(new Set(dv.pages('"Database Editor"').flatMap(p => p.file.frontmatter.related || []).filter(Boolean))); +const dimensionsOptions = Array.from(new Set(dv.pages('"Database Editor"').flatMap(p => p.file.frontmatter.dimensions || []).filter(Boolean))); + +// Define bind targets for filters +const bindTargetLocked = mb.parseBindTarget('memory^locked', currentFilePath); +const bindTargetFileName = mb.parseBindTarget('memory^fileNameFilter', currentFilePath); +const bindTargetParent = mb.parseBindTarget('memory^parentFilter', currentFilePath); +const bindTargetType = mb.parseBindTarget('memory^TypeFilter', currentFilePath); +const bindTargetRelated = mb.parseBindTarget('memory^relatedFilter', currentFilePath); +const bindTargetDimensions = mb.parseBindTarget('memory^dimensionsFilter', currentFilePath); + +// Table columns and lines +const columns = ["title", "Type", "mathLink", "parent", "related", "dimensions", "staticdimensions", "down", "Dimensions", "MKS", "CGS", "FPS", "Formula"]; +const lines = ["title", "Type", "mathLink", "parent", "related", "dimensions", "staticdimensions", "down", "mathLink-blocks.Dimensions", "mathLink-blocks.MKS", "mathLink-blocks.CGS", "mathLink-blocks.FPS", "mathLink-blocks.Formula"]; + +// Create dropdown inputs +function createDropdown(id, options) { + return `INPUT[inlineSelect(title(${id}), defaultValue(null), option(null), ${options.map(option => `option(${option})`).join(',')}):memory^${id}]`; +} + +// Render filters and table +async function renderTable() { + comp.unload(); + comp.load(); + container.empty(); + + // Check if the locked toggle is activated + const isLocked = await mb.getMetadata(bindTargetLocked); + + // Define filter fields and labels + const filterFields = [ + { + label: "Display Table:", + field: `INPUT[toggle:memory^locked]` + }, + { + label: "File Name:", + field: isLocked ? `VIEW[{memory^fileNameFilter}][text(renderMarkdown)]` : `INPUT[text(placeholder(File Name)):memory^fileNameFilter]` + }, + { + label: "Parent:", + field: isLocked ? `VIEW[{memory^parentFilter}][text(renderMarkdown)]` : createDropdown('parentFilter', parentOptions) + }, + { + label: "Type:", + field: isLocked ? `VIEW[{memory^TypeFilter}][text(renderMarkdown)]` : createDropdown('TypeFilter', TypeOptions) + }, + { + label: "Related:", + field: isLocked ? `VIEW[{memory^relatedFilter}][text(renderMarkdown)]` : createDropdown('relatedFilter', relatedOptions) + }, + { + label: "Dimensions:", + field: isLocked ? `VIEW[{memory^dimensionsFilter}][text(renderMarkdown)]` : createDropdown('dimensionsFilter', dimensionsOptions) + } + ]; + + // Create a container to hold the filter fields with labels + const filterContainer = container.createDiv({ cls: 'filter-container' }); + + // Render filter fields with labels + filterFields.forEach(({ label, field }) => { + const labelEl = filterContainer.createEl('div', { cls: 'filter-label', text: label }); + labelEl.style.marginBottom = '5px'; + labelEl.style.fontWeight = 'bold'; + + const fieldContainer = filterContainer.createDiv({ cls: 'filter-field' }); + const renderedField = mb.createInlineFieldFromString(field, currentFilePath, undefined); + mb.wrapInMDRC(renderedField, fieldContainer, comp); + }); + + if (!isLocked) { + return; // Do not proceed with metadata retrieval or table rendering if not locked + } + + // Get the filter values dynamically from memory + const fileName = await mb.getMetadata(bindTargetFileName); + const parent = await mb.getMetadata(bindTargetParent); + const type = await mb.getMetadata(bindTargetType); + const related = await mb.getMetadata(bindTargetRelated); + const dimensions = await mb.getMetadata(bindTargetDimensions); + + // Perform query using filters + const query = dv.pages('"Database Editor"') + .where(p => (!fileName || p.file.name.toLowerCase().includes(fileName.toLowerCase())) && + (!parent || (p.file.frontmatter.parent || []).includes(parent)) && + (!type || p.file.frontmatter.Type === type) && + (!related || (p.file.frontmatter.related || []).includes(related)) && + (!dimensions || (p.file.frontmatter.dimensions || []).includes(dimensions)) + ); + + if (!query || query.length === 0) { + new Notice("No files found with the selected filters"); + return; + } + + // Create and store input fields + const inputFieldsArr = []; + for (const page of query) { + const title = page.file.name; + const titleInputs = lines.map(line => { + let inputString; + switch (line) { + case "Type": + inputString = `INPUT[inlineSelect(option(Variable), option(Sub_Variable), option(Dimension), option(Sub_Dimension), option(Vocabulary), option(Math_Operation), option(Constant), option(Folder)):${title}#Type]`; + break; + case "parent": + case "related": + case "dimensions": + case "staticdimensions": + case "down": + inputString = `INPUT[inlineListSuggester(optionQuery("Database Editor"), useLinks(partial)):${title}#${line}]`; + break; + default: + inputString = `INPUT[text:${title}#${line}]`; + } + const div = container.createDiv(); + try { + const inputField = mb.createInlineFieldFromString(inputString, page.file.path); + mb.wrapInMDRC(inputField, div, comp); + return div; + } catch (error) { + console.error(`Error creating input field for ${inputString}:`, error); + div.textContent = `Error: ${error.message}`; + return div; + } + }); + inputFieldsArr.push(titleInputs); + } + + // Create table structure + const table = container.createEl('table'); + const tableHead = table.createEl('thead'); + const headerRow = tableHead.createEl('tr'); + columns.forEach(column => { + const th = headerRow.createEl('th'); + th.textContent = column; + }); + const tableBody = table.createEl('tbody'); + + // Populate table with input fields and views + inputFieldsArr.forEach((titleInputs, index) => { + const inputRow = tableBody.createEl('tr'); + titleInputs.forEach((inputDiv, colIndex) => { + const td = inputRow.createEl('td'); + td.appendChild(inputDiv); + }); + + const viewRow = tableBody.createEl('tr'); + lines.forEach((line, colIndex) => { + const td = viewRow.createEl('td'); + const title = query[index].file.name; + const viewString = `VIEW[{${title}#${line}}][text(renderMarkdown)]`; + const viewDiv = container.createDiv(); + try { + const viewField = mb.createInlineFieldFromString(viewString, currentFilePath); + mb.wrapInMDRC(viewField, viewDiv, comp); + td.appendChild(viewDiv); + } catch (error) { + console.error(`Error creating view field for ${viewString}:`, error); + td.textContent = `Error: ${error.message}`; + } + }); + }); + + new Notice("Table generated successfully"); + return table; +} + +// Create a reactive component that listens to the locked toggle +const reactive = engine.reactive(async () => { + await renderTable(); +}, [ + mb.getMetadata(bindTargetLocked) // Only react to changes in the locked state +]); + +// Subscribe to metadata changes for the locked state +mb.subscribeToMetadata(bindTargetLocked, component, () => reactive.refresh()); + +// Initial render +renderTable(); + +``` From dab81d49cab9c27606e021a6d9db1643cf6ae363 Mon Sep 17 00:00:00 2001 From: LynetteCullens <45722611+LynetteCullens@users.noreply.github.com> Date: Fri, 16 Aug 2024 20:00:43 -0500 Subject: [PATCH 7/9] Update Database Editor.md --- exampleVault/Database Editor/Database Editor.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/exampleVault/Database Editor/Database Editor.md b/exampleVault/Database Editor/Database Editor.md index 26fc51f9..c418890e 100644 --- a/exampleVault/Database Editor/Database Editor.md +++ b/exampleVault/Database Editor/Database Editor.md @@ -129,10 +129,10 @@ const dv = engine.getPlugin('dataview').api; const comp = new obsidian.Component(component); // Extract unique options for each filter -const parentOptions = Array.from(new Set(dv.pages('"Database Editor"').flatMap(p => p.file.frontmatter.parent || []).filter(Boolean))); -const TypeOptions = Array.from(new Set(dv.pages('"Database Editor"').map(p => p.file.frontmatter.Type || '').filter(Boolean))); -const relatedOptions = Array.from(new Set(dv.pages('"Database Editor"').flatMap(p => p.file.frontmatter.related || []).filter(Boolean))); -const dimensionsOptions = Array.from(new Set(dv.pages('"Database Editor"').flatMap(p => p.file.frontmatter.dimensions || []).filter(Boolean))); +const parentOptions = Array.from(new Set(dv.pages('"Database Editor/Database"').flatMap(p => p.file.frontmatter.parent || []).filter(Boolean))); +const TypeOptions = Array.from(new Set(dv.pages('"Database Editor/Database"').map(p => p.file.frontmatter.Type || '').filter(Boolean))); +const relatedOptions = Array.from(new Set(dv.pages('"Database Editor/Database"').flatMap(p => p.file.frontmatter.related || []).filter(Boolean))); +const dimensionsOptions = Array.from(new Set(dv.pages('"Database Editor/Database"').flatMap(p => p.file.frontmatter.dimensions || []).filter(Boolean))); // Define bind targets for filters const bindTargetLocked = mb.parseBindTarget('memory^locked', currentFilePath); @@ -214,7 +214,7 @@ async function renderTable() { const dimensions = await mb.getMetadata(bindTargetDimensions); // Perform query using filters - const query = dv.pages('"Database Editor"') + const query = dv.pages('"Database Editor/Database"') .where(p => (!fileName || p.file.name.toLowerCase().includes(fileName.toLowerCase())) && (!parent || (p.file.frontmatter.parent || []).includes(parent)) && (!type || p.file.frontmatter.Type === type) && @@ -242,7 +242,7 @@ async function renderTable() { case "dimensions": case "staticdimensions": case "down": - inputString = `INPUT[inlineListSuggester(optionQuery("Database Editor"), useLinks(partial)):${title}#${line}]`; + inputString = `INPUT[inlineListSuggester(optionQuery("Database Editor/Database"), useLinks(partial)):${title}#${line}]`; break; default: inputString = `INPUT[text:${title}#${line}]`; @@ -313,4 +313,5 @@ mb.subscribeToMetadata(bindTargetLocked, component, () => reactive.refresh()); // Initial render renderTable(); + ``` From 688744550924aaa60328075027bbd8606e777736 Mon Sep 17 00:00:00 2001 From: LynetteCullens <45722611+LynetteCullens@users.noreply.github.com> Date: Fri, 23 Aug 2024 15:53:31 -0500 Subject: [PATCH 8/9] Update Database Editor.md Added scrollbar to view in Live Preview, Included/Excluded filters, and horizontal filters. --- .../Database Editor/Database Editor.md | 280 +++++++++++++++--- 1 file changed, 241 insertions(+), 39 deletions(-) diff --git a/exampleVault/Database Editor/Database Editor.md b/exampleVault/Database Editor/Database Editor.md index c418890e..ac669baa 100644 --- a/exampleVault/Database Editor/Database Editor.md +++ b/exampleVault/Database Editor/Database Editor.md @@ -128,78 +128,184 @@ const dv = engine.getPlugin('dataview').api; // Component for lifecycle management of fields const comp = new obsidian.Component(component); +// Define the order of filters +const filterOrder = [ + "Display Table", + "File Name", + "Type", + "File Class", + "Parent", + "Related", + "Dimensions", + "Static Dimensions" +]; + // Extract unique options for each filter +const fileClassOptions = Array.from(new Set(dv.pages('"Database Editor/Database"').map(p => p.file.frontmatter.fileClass || '').filter(Boolean))); const parentOptions = Array.from(new Set(dv.pages('"Database Editor/Database"').flatMap(p => p.file.frontmatter.parent || []).filter(Boolean))); const TypeOptions = Array.from(new Set(dv.pages('"Database Editor/Database"').map(p => p.file.frontmatter.Type || '').filter(Boolean))); const relatedOptions = Array.from(new Set(dv.pages('"Database Editor/Database"').flatMap(p => p.file.frontmatter.related || []).filter(Boolean))); const dimensionsOptions = Array.from(new Set(dv.pages('"Database Editor/Database"').flatMap(p => p.file.frontmatter.dimensions || []).filter(Boolean))); +const staticdimensionsOptions = Array.from(new Set(dv.pages('"Database Editor/Database"').flatMap(p => p.file.frontmatter.staticdimensions || []).filter(Boolean))); // Define bind targets for filters -const bindTargetLocked = mb.parseBindTarget('memory^locked', currentFilePath); const bindTargetFileName = mb.parseBindTarget('memory^fileNameFilter', currentFilePath); +const bindTargetLocked = mb.parseBindTarget('memory^locked', currentFilePath); +const bindTargetFileClass = mb.parseBindTarget('memory^fileClassFilter', currentFilePath); const bindTargetParent = mb.parseBindTarget('memory^parentFilter', currentFilePath); const bindTargetType = mb.parseBindTarget('memory^TypeFilter', currentFilePath); const bindTargetRelated = mb.parseBindTarget('memory^relatedFilter', currentFilePath); const bindTargetDimensions = mb.parseBindTarget('memory^dimensionsFilter', currentFilePath); +const bindTargetStaticDimensions = mb.parseBindTarget('memory^staticdimensionsFilter', currentFilePath); + +// Define bind targets for inclusion filters +const bindTargetIncludedFileName = mb.parseBindTarget('memory^includedFileNameFilter', currentFilePath); +const bindTargetIncludedFileClass = mb.parseBindTarget('memory^includedFileClassFilter', currentFilePath); +const bindTargetIncludedParent = mb.parseBindTarget('memory^includedParentFilter', currentFilePath); +const bindTargetIncludedType = mb.parseBindTarget('memory^includedTypeFilter', currentFilePath); +const bindTargetIncludedRelated = mb.parseBindTarget('memory^includedRelatedFilter', currentFilePath); +const bindTargetIncludedDimensions = mb.parseBindTarget('memory^includedDimensionsFilter', currentFilePath); +const bindTargetIncludedStaticDimensions = mb.parseBindTarget('memory^includedStaticDimensionsFilter', currentFilePath); + +// Define bind targets for excluded filters +const bindTargetExcludedFileName = mb.parseBindTarget('memory^excludedFileNameFilter', currentFilePath); +const bindTargetExcludedFileClass = mb.parseBindTarget('memory^excludedFileClassFilter', currentFilePath); +const bindTargetExcludedParent = mb.parseBindTarget('memory^excludedParentFilter', currentFilePath); +const bindTargetExcludedType = mb.parseBindTarget('memory^excludedTypeFilter', currentFilePath); +const bindTargetExcludedRelated = mb.parseBindTarget('memory^excludedRelatedFilter', currentFilePath); +const bindTargetExcludedDimensions = mb.parseBindTarget('memory^excludedDimensionsFilter', currentFilePath); +const bindTargetExcludedStaticDimensions = mb.parseBindTarget('memory^excludedStaticDimensionsFilter', currentFilePath); // Table columns and lines -const columns = ["title", "Type", "mathLink", "parent", "related", "dimensions", "staticdimensions", "down", "Dimensions", "MKS", "CGS", "FPS", "Formula"]; -const lines = ["title", "Type", "mathLink", "parent", "related", "dimensions", "staticdimensions", "down", "mathLink-blocks.Dimensions", "mathLink-blocks.MKS", "mathLink-blocks.CGS", "mathLink-blocks.FPS", "mathLink-blocks.Formula"]; +const columns = ["mathLink", "title", "Type", "parent", "related", "dimensions", "staticdimensions", "down", "Dimensions", "StaticDimensions","MKS", "CGS", "FPS", "Formula"]; +const lines = ["mathLink", "title", "Type", "parent", "related", "dimensions", "staticdimensions", "down", "mathLink-blocks.Dimensions", "mathLink-blocks.StaticDimensions", "mathLink-blocks.MKS", "mathLink-blocks.CGS", "mathLink-blocks.FPS", "mathLink-blocks.Formula"]; // Create dropdown inputs function createDropdown(id, options) { return `INPUT[inlineSelect(title(${id}), defaultValue(null), option(null), ${options.map(option => `option(${option})`).join(',')}):memory^${id}]`; } +// Create list suggester input for included and excluded filters +function createListSuggester(id, options) { + return `INPUT[inlineListSuggester(title(${id}), defaultValue(null), option(null),useLinks(false), ${options.map(option => `option(${option})`).join(',')}):memory^${id}]`; +} + // Render filters and table async function renderTable() { comp.unload(); comp.load(); container.empty(); + // Create a wrapper div for both filters and table with always-visible scrolling + const contentWrapper = container.createEl('div', { cls: 'content-wrapper' }); + contentWrapper.style.overflowX = 'scroll'; + contentWrapper.style.overflowY = 'auto'; + contentWrapper.style.width = '100%'; + contentWrapper.style.maxHeight = '80vh'; // Adjust this value as needed + contentWrapper.style.border = '1px solid #ddd'; + // Check if the locked toggle is activated const isLocked = await mb.getMetadata(bindTargetLocked); // Define filter fields and labels const filterFields = [ { - label: "Display Table:", - field: `INPUT[toggle:memory^locked]` + label: "Display Table", + field: `INPUT[toggle:memory^locked]`, + includedField: null, + excludedField: null }, { - label: "File Name:", - field: isLocked ? `VIEW[{memory^fileNameFilter}][text(renderMarkdown)]` : `INPUT[text(placeholder(File Name)):memory^fileNameFilter]` + label: "File Name", + field: isLocked ? `VIEW[{memory^fileNameFilter}][text(renderMarkdown)]` : `INPUT[text(placeholder(File Name)):memory^fileNameFilter]`, + includedField: isLocked ? `VIEW[{memory^includedFileNameFilter}][text(renderMarkdown)]` : createListSuggester('includedFileNameFilter', dv.pages('"Database Editor/Database"').map(p => p.file.name)), + excludedField: isLocked ? `VIEW[{memory^excludedFileNameFilter}][text(renderMarkdown)]` : createListSuggester('excludedFileNameFilter', dv.pages('"Database Editor/Database"').map(p => p.file.name)) }, { - label: "Parent:", - field: isLocked ? `VIEW[{memory^parentFilter}][text(renderMarkdown)]` : createDropdown('parentFilter', parentOptions) + label: "File Class", + field: isLocked ? `VIEW[{memory^fileClassFilter}][text(renderMarkdown)]` : createDropdown('fileClassFilter', fileClassOptions), + includedField: isLocked ? `VIEW[{memory^includedFileClassFilter}][text(renderMarkdown)]` : createListSuggester('includedFileClassFilter', fileClassOptions), + excludedField: isLocked ? `VIEW[{memory^excludedFileClassFilter}][text(renderMarkdown)]` : createListSuggester('excludedFileClassFilter', fileClassOptions) }, { - label: "Type:", - field: isLocked ? `VIEW[{memory^TypeFilter}][text(renderMarkdown)]` : createDropdown('TypeFilter', TypeOptions) + label: "Parent", + field: isLocked ? `VIEW[{memory^parentFilter}][text(renderMarkdown)]` : createDropdown('parentFilter', parentOptions), + includedField: isLocked ? `VIEW[{memory^includedParentFilter}][text(renderMarkdown)]` : createListSuggester('includedParentFilter', parentOptions), + excludedField: isLocked ? `VIEW[{memory^excludedParentFilter}][text(renderMarkdown)]` : createListSuggester('excludedParentFilter', parentOptions) }, { - label: "Related:", - field: isLocked ? `VIEW[{memory^relatedFilter}][text(renderMarkdown)]` : createDropdown('relatedFilter', relatedOptions) + label: "Type", + field: isLocked ? `VIEW[{memory^TypeFilter}][text(renderMarkdown)]` : createDropdown('TypeFilter', TypeOptions), + includedField: isLocked ? `VIEW[{memory^includedTypeFilter}][text(renderMarkdown)]` : createListSuggester('includedTypeFilter', TypeOptions), + excludedField: isLocked ? `VIEW[{memory^excludedTypeFilter}][text(renderMarkdown)]` : createListSuggester('excludedTypeFilter', TypeOptions) }, { - label: "Dimensions:", - field: isLocked ? `VIEW[{memory^dimensionsFilter}][text(renderMarkdown)]` : createDropdown('dimensionsFilter', dimensionsOptions) + label: "Related", + field: isLocked ? `VIEW[{memory^relatedFilter}][text(renderMarkdown)]` : createDropdown('relatedFilter', relatedOptions), + includedField: isLocked ? `VIEW[{memory^includedRelatedFilter}][text(renderMarkdown)]` : createListSuggester('includedRelatedFilter', relatedOptions), + excludedField: isLocked ? `VIEW[{memory^excludedRelatedFilter}][text(renderMarkdown)]` : createListSuggester('excludedRelatedFilter', relatedOptions) + }, + { + label: "Dimensions", + field: isLocked ? `VIEW[{memory^dimensionsFilter}][text(renderMarkdown)]` : createDropdown('dimensionsFilter', dimensionsOptions), + includedField: isLocked ? `VIEW[{memory^includedDimensionsFilter}][text(renderMarkdown)]` : createListSuggester('includedDimensionsFilter', dimensionsOptions), + excludedField: isLocked ? `VIEW[{memory^excludedDimensionsFilter}][text(renderMarkdown)]` : createListSuggester('excludedDimensionsFilter', dimensionsOptions) + }, + { + label: "Static Dimensions", + field: isLocked ? `VIEW[{memory^staticdimensionsFilter}][text(renderMarkdown)]` : createDropdown('staticdimensionsFilter', staticdimensionsOptions), + includedField: isLocked ? `VIEW[{memory^includedStaticDimensionsFilter}][text(renderMarkdown)]` : createListSuggester('includedStaticDimensionsFilter', staticdimensionsOptions), + excludedField: isLocked ? `VIEW[{memory^excludedStaticDimensionsFilter}][text(renderMarkdown)]` : createListSuggester('excludedStaticDimensionsFilter', staticdimensionsOptions) } ]; - // Create a container to hold the filter fields with labels - const filterContainer = container.createDiv({ cls: 'filter-container' }); + // Create a table for filters inside the content wrapper + const filterTable = contentWrapper.createEl('table', { cls: 'filter-table' }); + filterTable.style.borderCollapse = 'collapse'; + filterTable.style.width = '100%'; + + // Create filter rows + const filterRow = filterTable.createEl('tr'); + const includedFilterRow = filterTable.createEl('tr'); + const excludedFilterRow = filterTable.createEl('tr'); + + filterOrder.forEach(label => { + const filterField = filterFields.find(f => f.label === label); + if (filterField) { + // Main filter + const th = filterRow.createEl('th'); + th.textContent = filterField.label; + th.style.fontWeight = 'bold'; + th.style.paddingRight = '10px'; + + const td = filterRow.createEl('td'); + const renderedField = mb.createInlineFieldFromString(filterField.field, currentFilePath, undefined); + mb.wrapInMDRC(renderedField, td, comp); + + // Included filter + const includedTh = includedFilterRow.createEl('th'); + const includedTd = includedFilterRow.createEl('td'); + if (filterField.includedField) { + includedTh.textContent = `Included ${filterField.label}`; + includedTh.style.fontWeight = 'bold'; + includedTh.style.paddingRight = '10px'; + + const renderedIncludedField = mb.createInlineFieldFromString(filterField.includedField, currentFilePath, undefined); + mb.wrapInMDRC(renderedIncludedField, includedTd, comp); + } - // Render filter fields with labels - filterFields.forEach(({ label, field }) => { - const labelEl = filterContainer.createEl('div', { cls: 'filter-label', text: label }); - labelEl.style.marginBottom = '5px'; - labelEl.style.fontWeight = 'bold'; + // Excluded filter + const excludedTh = excludedFilterRow.createEl('th'); + const excludedTd = excludedFilterRow.createEl('td'); + if (filterField.excludedField) { + excludedTh.textContent = `Excluded ${filterField.label}`; + excludedTh.style.fontWeight = 'bold'; + excludedTh.style.paddingRight = '10px'; - const fieldContainer = filterContainer.createDiv({ cls: 'filter-field' }); - const renderedField = mb.createInlineFieldFromString(field, currentFilePath, undefined); - mb.wrapInMDRC(renderedField, fieldContainer, comp); + const renderedExcludedField = mb.createInlineFieldFromString(filterField.excludedField, currentFilePath, undefined); + mb.wrapInMDRC(renderedExcludedField, excludedTd, comp); + } + } }); if (!isLocked) { @@ -208,18 +314,54 @@ async function renderTable() { // Get the filter values dynamically from memory const fileName = await mb.getMetadata(bindTargetFileName); + const fileClass = await mb.getMetadata(bindTargetFileClass); const parent = await mb.getMetadata(bindTargetParent); const type = await mb.getMetadata(bindTargetType); const related = await mb.getMetadata(bindTargetRelated); const dimensions = await mb.getMetadata(bindTargetDimensions); - - // Perform query using filters + const staticdimensions = await mb.getMetadata(bindTargetStaticDimensions); + + // Get the included filter values dynamically from memory + const includedFileName = await mb.getMetadata(bindTargetIncludedFileName) || []; + const includedFileClass = await mb.getMetadata(bindTargetIncludedFileClass) || []; + const includedParent = await mb.getMetadata(bindTargetIncludedParent) || []; + const includedType = await mb.getMetadata(bindTargetIncludedType) || []; + const includedRelated = await mb.getMetadata(bindTargetIncludedRelated) || []; + const includedDimensions = await mb.getMetadata(bindTargetIncludedDimensions) || []; + const includedStaticDimensions = await mb.getMetadata(bindTargetIncludedStaticDimensions) || []; + + // Get the excluded filter values dynamically from memory + const excludedFileName = await mb.getMetadata(bindTargetExcludedFileName) || []; + const excludedFileClass = await mb.getMetadata(bindTargetExcludedFileClass) || []; + const excludedParent = await mb.getMetadata(bindTargetExcludedParent) || []; + const excludedType = await mb.getMetadata(bindTargetExcludedType) || []; + const excludedRelated = await mb.getMetadata(bindTargetExcludedRelated) || []; + const excludedDimensions = await mb.getMetadata(bindTargetExcludedDimensions) || []; + const excludedStaticDimensions = await mb.getMetadata(bindTargetExcludedStaticDimensions) || []; + + // Perform query using filters, included filters, and excluded filters const query = dv.pages('"Database Editor/Database"') .where(p => (!fileName || p.file.name.toLowerCase().includes(fileName.toLowerCase())) && + (!fileClass || p.file.frontmatter.fileClass === fileClass) && (!parent || (p.file.frontmatter.parent || []).includes(parent)) && (!type || p.file.frontmatter.Type === type) && (!related || (p.file.frontmatter.related || []).includes(related)) && - (!dimensions || (p.file.frontmatter.dimensions || []).includes(dimensions)) + (!dimensions || (p.file.frontmatter.dimensions || []).includes(dimensions)) && + (!staticdimensions || (p.file.frontmatter.staticdimensions || []).includes(staticdimensions)) && + (!excludedFileName.includes(p.file.name)) && + (!excludedFileClass.includes(p.file.frontmatter.fileClass)) && + (!excludedParent.some(ep => (p.file.frontmatter.parent || []).includes(ep))) && + (!excludedType.includes(p.file.frontmatter.Type)) && + (!excludedRelated.some(er => (p.file.frontmatter.related || []).includes(er))) && + (!excludedDimensions.some(ed => (p.file.frontmatter.dimensions || []).includes(ed))) && + (!excludedStaticDimensions.some(esd => (p.file.frontmatter.staticdimensions || []).includes(esd))) && + (includedFileName.length === 0 || includedFileName.includes(p.file.name)) && + (includedFileClass.length === 0 || includedFileClass.includes(p.file.frontmatter.fileClass)) && + (includedParent.length === 0 || includedParent.some(ip => (p.file.frontmatter.parent || []).includes(ip))) && + (includedType.length === 0 || includedType.includes(p.file.frontmatter.Type)) && + (includedRelated.length === 0 || includedRelated.some(ir => (p.file.frontmatter.related || []).includes(ir))) && + (includedDimensions.length === 0 || includedDimensions.some(id => (p.file.frontmatter.dimensions || []).includes(id))) && + (includedStaticDimensions.length === 0 || includedStaticDimensions.some(isd => (p.file.frontmatter.staticdimensions || []).includes(isd))) ); if (!query || query.length === 0) { @@ -235,7 +377,7 @@ async function renderTable() { let inputString; switch (line) { case "Type": - inputString = `INPUT[inlineSelect(option(Variable), option(Sub_Variable), option(Dimension), option(Sub_Dimension), option(Vocabulary), option(Math_Operation), option(Constant), option(Folder)):${title}#Type]`; + inputString = `INPUT[inlineSelect(option(Variable), option(Sub_Variable), option(Dimension), option(Sub_Dimension), option(Vocabulary), option(Math_Operation), option(Sub_Math_Operation), option(Equation), option(Constant), option(Concept), option(Folder)):${title}#Type]`; break; case "parent": case "related": @@ -261,27 +403,35 @@ async function renderTable() { inputFieldsArr.push(titleInputs); } - // Create table structure - const table = container.createEl('table'); + // Create table structure inside the content wrapper + const table = contentWrapper.createEl('table', { cls: 'data-table' }); + table.style.borderCollapse = 'collapse'; + table.style.width = 'max-content'; + table.style.minWidth = '100%'; + const tableHead = table.createEl('thead'); const headerRow = tableHead.createEl('tr'); columns.forEach(column => { const th = headerRow.createEl('th'); th.textContent = column; + th.style.padding = '8px'; + th.style.borderBottom = '1px solid #ddd'; + th.style.whiteSpace = 'nowrap'; + th.style.backgroundColor = '#f2f2f2'; + th.style.position = 'sticky'; + th.style.top = '0'; + th.style.zIndex = '1'; }); const tableBody = table.createEl('tbody'); - // Populate table with input fields and views + // Populate table with views first and then input fields inputFieldsArr.forEach((titleInputs, index) => { - const inputRow = tableBody.createEl('tr'); - titleInputs.forEach((inputDiv, colIndex) => { - const td = inputRow.createEl('td'); - td.appendChild(inputDiv); - }); - + // Create and append view row first const viewRow = tableBody.createEl('tr'); lines.forEach((line, colIndex) => { const td = viewRow.createEl('td'); + td.style.padding = '8px'; + td.style.borderBottom = '1px solid #ddd'; const title = query[index].file.name; const viewString = `VIEW[{${title}#${line}}][text(renderMarkdown)]`; const viewDiv = container.createDiv(); @@ -294,10 +444,19 @@ async function renderTable() { td.textContent = `Error: ${error.message}`; } }); + + // Create and append input row after view row + const inputRow = tableBody.createEl('tr'); + titleInputs.forEach((inputDiv, colIndex) => { + const td = inputRow.createEl('td'); + td.style.padding = '8px'; + td.style.borderBottom = '1px solid #ddd'; + td.appendChild(inputDiv); + }); }); new Notice("Table generated successfully"); - return table; + return contentWrapper; } // Create a reactive component that listens to the locked toggle @@ -313,5 +472,48 @@ mb.subscribeToMetadata(bindTargetLocked, component, () => reactive.refresh()); // Initial render renderTable(); +// Add global CSS to the document +const style = document.createElement('style'); +style.textContent = ` + .content-wrapper { + overflow-x: scroll; + overflow-y: auto; + width: 100%; + max-height: 80vh; + border: 1px solid #ddd; + } + .content-wrapper table { + border-collapse: collapse; + width: max-content; + min-width: 100%; + } + .content-wrapper th, .content-wrapper td { + padding: 8px; + border: 1px solid #ddd; + white-space: nowrap; + } + .content-wrapper .data-table th { + background-color: #f2f2f2; + position: sticky; + top: 0; + z-index: 1; + } + .content-wrapper::-webkit-scrollbar { + width: 10px; + height: 10px; + } + .content-wrapper::-webkit-scrollbar-thumb { + background: #888; + border-radius: 5px; + } + .content-wrapper::-webkit-scrollbar-thumb:hover { + background: #555; + } + .content-wrapper::-webkit-scrollbar-track { + background: #f1f1f1; + } +`; +document.head.appendChild(style); + ``` From ef61562796d4f9c5487fd5a7fec511b533a95413 Mon Sep 17 00:00:00 2001 From: LynetteCullens <45722611+LynetteCullens@users.noreply.github.com> Date: Sat, 25 Jan 2025 15:17:32 -0600 Subject: [PATCH 9/9] Update In Note Navigation.md Just corrected mispelled `Secion` to `Section` --- exampleVault/Buttons/In Note Navigation.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/exampleVault/Buttons/In Note Navigation.md b/exampleVault/Buttons/In Note Navigation.md index c90cf498..9012fd86 100644 --- a/exampleVault/Buttons/In Note Navigation.md +++ b/exampleVault/Buttons/In Note Navigation.md @@ -83,5 +83,5 @@ text ## This is a Heading at the Bottom -Some Secion -^section-1 \ No newline at end of file +Some Section +^section-1