How to have an input text field and render part of the doc based in the input value?

What I’m trying to do

Basically, I want to have a text input field like input file name, output file name, and then I can have a code block render a text (command) based on the input.

For instance, given two fields with the input and output file name, we can generate a command based on the input. Having this, everytime you are trying to get a command to execute, you can just type variables into the input fields and you can get a command.

Would expect sth like

[INPUT:input_file]
[OUTPUT:output_file]

command --arg1 value1 --arg2 value2 --arg3 value3 -if {{input_file}} -of {{output_file}}

Things I have tried

The following thread seems related while few updates over it. Also tried Obsidian Meta Bind Plugin and DataViewJS while cannot figure out a way to do it. Any suggestion will be helpful, thanks!

1 Like

The intuitive (not working) solution

Here is a partial solution, which in theory should work all the way:

Input-file: `INPUT[text:input_file]`
Output-file: `INPUT[text:output_file]`

My command: `= "<code>command -i " + this.input_file + " -o " + this.output_file +"</code>"`

It utilises the Meta-bind plugin to produce the input field, and the Dataview plugin to produce the output. Sadly, the output is not refreshed due to the query not actually changing (only the date it relies on is changing). So that’s a bummer. In order for it to refresh you need to either close and re-open this file, or go back (and forward again) in file history.

Using Templater and Buttons as well

One way to counter this non-refreshing query thing is to use a combination of Templater and Buttons. This can be done in two ways, where either option requires that the button must be pressed.

In one version the button will replace a given line in the end note, so proper care needs to be taken that this line number doesn’t change (or the button will happily change whatever text is on that particular line. The other version just keeps on appending a new command line into your note, resulting in multiple commands, if you change the input often. The advantage of this latter variant is that it wont (accidentally) remove lines due to you shifting line numbers, which might happen with the first variant…

Here is a screendump with both options covered:

Notice how the line(37) and replace [37, 37] refers to the line number of the resulting line where the “input33123” file name is used. If you add lines in front of this button definitions, you’ll need to change 37 to whatever number it ends up on. Also see how in the latter variant, I’ve pressed the button a few times, so multiple lines are appended.

Both of these rely on a template which I’ve called forum/f57426_command which resides in the forum sub-folder of my templates folder, which contains this text:

<code>command -i  <% tp.frontmatter.input_file %> -o <% tp.frontmatter.output_file %></code>
Code to generate the buttons

Here is the text version of the buttons. NB! Make sure to match 37 to the line number where you want your command to appear.

```button
name Replace command
type line(37) template
action forum/f57426_command
replace [37,37]
```



```button
name Append command
type append template
action forum/f57426_command
```

Using the Minimal theme this look like this in my setup:
image

You can of course change all text and formatting related to the various command outputs and template output as per your liking.

Hope this illustrates some of the possibilities and caveats related to input fields, and using that value within the same file.

1 Like

I’ve been wondering about this for a while.The simplest way would be to have the text fields be metadata fields, either as YAML front-matter or simply just inline at the top of the page.

This (new?) Obsidian Meta Bind Plugin provides for nice access to the manipulate the field values, so you don’t need to switch back and forth between editor and preview mode.

Thanks for your suggestion, I will give it a try!

Yeah I have tried this plugin, while I think the dataviewjs is not updating the value in the preview mode so it does not reflect the latest value (the one from the meta bind input.)

Hey folks, I got some workaround and it works for me now pretty well!

GitHub - elias-sundqvist/obsidian-react-components: Write and use React (Jsx) components in your Obsidian notes. This plugin is really helpful for my case!

To achive the goal, I wrote a component that takes arbitrary variables and a command template:

const [variables, setVariables] = useState(new Map(props.variables.map((obj) => [obj, obj])))

const handleChange = function (variable, event) {
	setVariables(variables => new Map(variables.set(variable, event.target.value)))
}

return <div>
{(() => {
const arr = [];
for (let variable of props.variables) {
arr.push(<div><label><code>{variable}: </code></label><input onChange={(e) => handleChange(variable, e)}/><br/></div>)
}
return arr
})()}
<code>
{(() => {
  let command = props.command
  for (const [variable, value] of variables) {
    command = command.replace("{" + variable + "}", value)
  }
  return command
})()}
</code>
</div>

And then in my notes, I can use it by

<TemplateCommand 
  variables={["InputFileName", "OutputFileName", "Arg1"]}
  command={"./script.sh --arg1 {Arg1} {InputFileName} {OutputFileName}"}
  />

Which gives a UI like this and perfectly solve my case!

image

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