Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature request] Variables in Forms #269

Open
zanodor opened this issue May 31, 2024 · 7 comments
Open

[Feature request] Variables in Forms #269

zanodor opened this issue May 31, 2024 · 7 comments
Assignees

Comments

@zanodor
Copy link

zanodor commented May 31, 2024

Is your feature request related to a problem? Please describe.

Specifically dates. I find it too fiddly to set today's date and there is no way to do plus THH:mm.

Describe the solution you'd like

Some in-form method I cannot describe.

Additional context

Additionally, if I have:

  tR += "---" + "\n"
  const modalForm = app.plugins.plugins.modalforms.api;
  const result = await modalForm.openForm("default_notes_form");
  tR += result.asFrontmatterString();
  tR += "dateCreated: " + tp.date.now("YYYY-MM-DDTHH:mm");
  tR += "\n" + "dateModified: " + tp.date.now("YYYY-MM-DDTHH:mm");
  tR += "\n" + "---" + "\n"

...would there be a different way, I wonder?

This works, so don't wreck your brain or spend too much time over an alternative, of course.

Awesome plugin, I would love to see you be rewarded by Obs. Team in some way.

Cheers,

Z.

@zanodor zanodor added the enhancement New feature or request label May 31, 2024
@danielo515
Copy link
Owner

At first I thought you were just asking about providing default values, but now I see what you mean, and I see why it is convenient.
Maybe I can accept an option of extra-values, that will be incorporated in the result, giving preference to the result, or add a new field option to mark a field as hidden, so you can "inject" those values when calling the form.
I'm open to suggestions of what you will consider more comfortable to use.
For example:

  const result = await modalForm.openForm("default_notes_form",{extraValues: {a: 55}} );

However, that requires an entire new section of the result to parse and handle it properly, while adding the option to hide a field will re-use all the existing machinery

@zanodor
Copy link
Author

zanodor commented Jun 17, 2024

My idea was about reducing the Templater lines and asking Modal Forms to do more. But I agree you don't want to write a new Templater inside Modal Forms.
I just feel users currently are shying away from using the plugin because they don't know how much Modal Forms can do and cannot do.
So users don't know the scope of the plugin and what to inject over what little they know to inject through Templater itself. It's like a woman and man dancing: the woman expects the man to lead but he cannot dance so the man (the average Obsidian user) sits on his chair not dancing.

Also, what I meant above is the need to add --- fences... if Modal Forms use processFrontmatter behind the scenes, will it not create the YAML fences if they don't exist (on new file creation, for instance)?

The main idea was to make it simpler for users as many people don't go for the plugin yet and they should. But I guess it's their loss... In any case, I leave it up to you what you find useful to implement over time.

Cheers

@danielo515
Copy link
Owner

My idea was about reducing the Templater lines and asking Modal Forms to do more. But I agree you don't want to write a new Templater inside Modal Forms.

Yeah, me too. Modal Forms is currently capable of doing this, its only requirement is that you provide the value for a field. That's why I thought about including a hidden field that will let you do that. But I'm not sure about the implications

Another alternative will be that the method asFrontmatterString accepts an option of 'extra-fields' that will be present in the output, so you can have everything in one single line.

<% "---" %>
<%*
  const modalForm = app.plugins.plugins.modalforms.api;
  const result = await modalForm.openForm("example-form");
  tR += result.asFrontmatterString({ extraValues: { created: new Date().toDateString() } });
-%>
<% "---" %>

Also, what I meant above is need to add --- fences... if Modal Forms use processFrontmatter behind the scenes, will it not create the YAML fences if they don't exist (on new file creation, for instance)?

This is intentional. Many times I want to include some manual parts in the template, and the fences should wrap the whole block, not only what the result will produce. This gives you greater flexibility of where and how you place the generated text. Also, no, by default obsidian does not generate the fences. I can add an option to include the fences though.
vx

@aaachen
Copy link

aaachen commented Jun 27, 2024

Not sure if my use case falls into this category, happy to open a separate issue to track otherwise

I have a form that I want to list dv values from the current file. It's intended to be wired up with quickadd. The idea of the dv query is something as follows:

${currentPage}.Milestone

I tried doing dv.current() but the plugin reports it's not a supported function, so I was wondering if I can pass the current file name as a variable and use dv.pages, letting modal form interpret the template string

// modal form replaces pathToCurrentFile from options
dv.pages('"${pathToCurrentFile}"').Milestone

In the quickadd macro script I'd pass the ${pathToCurrentFile} with = dv.current().file.name
If there pointer to existing alternative that'd great too! (Inline form seems to be the way)

@aaachen
Copy link

aaachen commented Jun 27, 2024

I think my use case can be generalized further as "variables that may be used by the form renderer", with this you can build a form like, say, static options for multiselect that is specified by a variable provided at runtime (caveat would be type checking I suppose)

This is definitely a more niche feature so just throwing it out there. Since I just found out about inline form it doesn't block me, it'd just make modal form even more op :)

@Z4rko963
Copy link

Recently, I found a way to filter and obtain options from my current note using file.inlinks and filtering by properties. This approach has been very helpful, and I believe expanding the plugin to natively support such functionalities would be beneficial for many users.Thank you for considering this suggestion, and for all your hard work on the plugin!

const modalForm = app.plugins.plugins.modalforms.api;

// Función para obtener la fecha actual en formato YYYY-MM-DD
const getCurrentDate = () => {
  const date = new Date();
  return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}`;
};

// Obtener la fecha actual
const currentDate = getCurrentDate();

// Obtener el nombre y la ruta del archivo actual usando QuickAdd
const currentFile = app.workspace.getActiveFile();
const currentNoteTitle = currentFile.basename;
const currentFilePath = currentFile.path;
const currentFolder = currentFile.parent.path;

// Determinar el valor de pet_identification basado en la carpeta
let petIdentificationValue = '';

if (currentFolder.includes('20 Owners')) {
  // Obtener los file.inlinks y filtrarlos si su propiedad del YAML deathdate es nula o vacía
  const inlinks = app.metadataCache.resolvedLinks[currentFilePath];
  let filteredInlinks = [];
  for (const link in inlinks) {
    const linkCache = app.metadataCache.getFileCache(app.vault.getAbstractFileByPath(link));
    if (linkCache && linkCache.frontmatter && (!linkCache.frontmatter.deathdate || linkCache.frontmatter.deathdate === '')) {
      filteredInlinks.push(`[[${link}]]`);
    }
  }
  petIdentificationValue = filteredInlinks.join(', '); // Unimos los enlaces con comas
} else if (currentFolder.includes('10 Pets')) {
  petIdentificationValue = currentNoteTitle;
}

// Valores iniciales predefinidos con la fecha actual para los campos especificados
const initialValues = {
  'date_vaccine': currentDate,
  'check_in': currentDate,
  'surgery_date': currentDate,
  'visit_date': currentDate,
  'pet_identification': petIdentificationValue
};

// Función para abrir el formulario con los valores iniciales y obtener los datos
const openFormWithInitialValues = async (initialValues) => {
  const result = await modalForm.openForm('Pets Services', { values: initialValues });
  return result.getData();
};

// Ejecutar la función para abrir el formulario y obtener los datos
const data = await openFormWithInitialValues(initialValues);

// Lista de campos a excluir
const excludeFields = new Set(["vaccine", "comments", "pet_care_services", "surgery", "clinical"]);

// Generar propiedades en formato de corchetes dinámicamente, incluyendo pet_identification
let bracketedProperties = Object.entries(data)
  .reduce((acc, [key, value]) => {
    if (!excludeFields.has(key) && value) {
      acc.push(`[${key}::${value}]`);
    }
    return acc;
  }, [])
  .join(' ');

// Insertar si hay propiedades además de la fecha y hora
if (bracketedProperties) {
  const formattedResultBrackets = `- [date::${currentDate}] ${bracketedProperties}`;
  return formattedResultBrackets;
} else {
  return '';
}

\n

this is my script, thanks!!!

@danielo515
Copy link
Owner

@zanodor thanks for sharing your solution. However, the context where your code is being executed is not the same as the code the plugin is being called from. I may be wrong, because I don't have that much experience with Obsidian API, so I will give some of the APIs you use a try.

By the way, not sure if you know about it alreaady, but modal forms already provides a way to format things as dataview properties (what you call bracketedProperties) it is called asDataviewProperties or asDv for short. Check here: https://danielorodriguez.com/obsidian-modal-form/managing-results/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants