As a fre­quent user of Actions for Obsid­i­an, I check the Com­mu­ni­ty Forum often. A few days ago, a user asked the fol­low­ing ques­tion: How can I cre­ate an input form for mul­ti­ple inputs? to cre­ate an Obsid­i­an note.

Since I was look­ing for use cas­es for the new beta app from Car­lo Zottmann, Brows­er Actions, I thought this could be a good use case. My first idea was to cre­ate a web form for the ques­tion­naire, then fetch all the entries using “Brows­er Actions” with­in a short­cut, com­pose the mark­down with all the entries, and final­ly use “Actions for Obsid­i­an” to cre­ate the note in the Obsid­i­an Vault.

How­ev­er, I didn’t want to open a web­page first and then start the work­flow. For­tu­nate­ly, Car­lo also asked his fol­low­ers on Mastodon for ideas on how to cre­ate some­thing that can col­lect mul­ti­ple entries. @davidbures@mstdn.social pro­posed a flow that solved my prob­lem.

The Flow of the Example

David showed how the same short­cut can be used in dif­fer­ent ways depend­ing on how it’s called. When the short­cut is run with­out any argu­ments, it fol­lows the if branch of a con­di­tion­al state­ment, which opens an HTML form in Safari. This form allows the user to enter health para­me­ters.

Once the form is filled out, the user clicks the sub­mit but­ton. This trig­gers the short­cut again, but now with the input data passed as a string. Since the short­cut is now called with input, it fol­lows the else branch of the con­di­tion­al state­ment, where the input (field labels and val­ues) can be processed. It would also be pos­si­ble to respond to the type of input and cre­ate dif­fer­ent branch­es for dif­fer­ent inputs.

A flowchart illustrating a process involving two main sections: "Shortcut" and "Safari." It begins with a "Start" point, followed by a decision point asking if input arguments are provided. If yes, it proceeds to display arguments. If no, it creates an HTML form and calls Safari. In Safari, the user fills out the form and submits it. The collected data is then sent back to the Shortcut section via a shortcut URI.

Finding a Solution. for all Apple Platforms

Unfor­tu­nate­ly, David’s sug­ges­tion only worked on iOS devices because it calls the HTML with a “data con­struct” that is not sup­port­ed on macOS. So, I looked for anoth­er way with a slight­ly dif­fer­ent flow.

My ini­tial approach of using the new ‘Brows­er Actions’ app to read the data from the fields in the form worked well (it is pub­lished in the forum post), but only on the Mac. Since the ques­tion­er asked for an iOS/iPadOS solu­tion, I found a solu­tion that works on both macOS and iOS/iPadOS and could be a blue­print for sim­i­lar prob­lems.

On MacOS, the HTML file can be saved and opened local­ly, but on iOS and iPa­dOS, it is not pos­si­ble to open a local HTML file with any brows­er. There­fore, a web serv­er is required to store and access the HTML file. Anoth­er lim­i­ta­tion is that the “Open URL” action only works with Safari. If you want to use this approach on MacOS only, I rec­om­mend using “Brows­er Actions” with the “Open URL” action. This action sup­ports most oth­er browsers on the Mac.

To cre­ate an Obsid­i­an note, I rely on “Actions for Obsid­i­an”. There may be oth­er ways, but for me, work­ing with­in short­cuts and Obsid­i­an’s Actions for Brows­er is just the eas­i­est way.

A flowchart depicting a process that includes four sections: "Webserver," "Safari," "Shortcut," and "Obsidian." It starts at a "Start" point, followed by a decision on whether input arguments are provided. If yes, the process moves to "Process Argument" and create note content. If no, it opens the URL of an HTML form page. In the Safari section, the user fills out the form and submits it, which collects data and sends it back to the Shortcut via a shortcut URI. Finally, the Obsidian section indicates that the process finishes by opening Obsidian with a new note.

The HTML-Form

Because the cus­tomer of Car­lo asked for a form to make entries with health data, I cre­at­ed this small form with dif­fer­ent UI ele­ments for data entry. To be hon­est, in this case, I asked “Per­plex­i­ty” to cre­ate an exam­ple form.

A digital form titled "Vital Signs Recording" with fields for inputting health metrics. It includes a slider for Heart Rate (BPM) set to 70, a text box for Blood Pressure (systolic/diastolic) reading "120/80," a text box for Body Temperature (°C) reading "36.5," and a slider for the Respiration Rate (per minute) set to 15. There is also a dropdown menu for selecting mood, currently set to "Euphoric." At the bottom, there is a green button labeled "Submit Data."

Here is the HTML Code:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Vital Data Recording</title>
    <style>
        body { font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto; padding: 20px; }
        label { display: block; margin-top: 10px; }
        input, select { width: 100%; padding: 5px; margin-top: 5px; }
        button { margin-top: 20px; background-color: #4CAF50; color: white; border: none; padding: 10px; cursor: pointer; width: 100%; }
    </style>
</head>
<body>
    <h1>Vital Data Recording</h1>
    <form id="vitalSignsForm">
        <label for="heartRate">Heart Rate (BPM):</label>
        <input type="range" id="heartRate" name="heartRate" min="40" max="180" value="70">
        <output for="heartRate"></output>

        <label for="bloodPressure">Blood Pressure (systolic/diastolic):</label>
        <input type="text" id="bloodPressure" name="bloodPressure" placeholder="120/80">

        <label for="temperature">Body Temperature (°C):</label>
        <input type="number" id="temperature" name="temperature" min="35" max="42" step="0.1" value="36.5">

        <label for="respiration">Respiration Rate (per minute):</label>
        <input type="range" id="respiration" name="respiration" min="10" max="30" value="15">
        <output for="respiration"></output>

        <label for="Mood">Mood:</label>
        <select id="Mood" name="mood">
            <option value="euphoric">Euphoric</option>
            <option value="neutral">Neutral</option>
            <option value="frustrated">Frustrated</option>
        </select>

        <button type="button" onclick="sendData()">Submit Data</button>
    </form>

    <script>

        // Updates the display of the slider values
        document.querySelectorAll('input[type="range"]').forEach(function(slider) {
            slider.nextElementSibling.value = slider.value;
            slider.oninput = function() {
                this.nextElementSibling.value = this.value;
            }
        });

    function sendData() {
        var form = document.getElementById('vitalSignsForm');
        var formData = new FormData(form);
        var jsonObject = {};

        for (var pair of formData.entries()) {
            jsonObject[pair[0]] = pair[1];
        }

        var jsonString = JSON.stringify(jsonObject);
        var shortcutURL = "shortcuts://run-shortcut?name=vital&input=" + encodeURIComponent(jsonString);
        window.location.href = shortcutURL;
}
    </script>
</body>
</html>

The shortcut

For the short­cut, there is no need to click any­thing in the details pane of the short­cut app. The “Pro­vide Out­put” option became, at least in my test, auto­mat­i­cal­ly checked when the short­cut runs for the first time.

It took me some time to under­stand that the “Receive No input from Nowhere If there’s no input: con­tin­ue” couldn’t be cho­sen from any detail option. Then I fifure out, that it will also be cre­at­ed dur­ing the first run. Just put the if action into the pane and press the run but­ton.

It is impor­tant to name the short­cut the same as the call in the HTML form.

The if con­di­tion­al checks if the short­cut is called with input para­me­ters; if not, it skips to the oth­er­wise branch, where it opens the HTML form from a web serv­er.

When the web form is filled out and the user press­es the “Sub­mit Data” but­ton, the if branch will be processed. To work with the input from the form, the eas­i­est way is to trans­form the JSON string into a dic­tio­nary with the action “Get dic­tio­nary from Short­cut Input.”

It’s pos­si­ble to add some addi­tion­al data that are not part of the form; here I added, as an exam­ple, the cur­rent weath­er con­di­tions. If you are only on iOS and part­ly on iPa­dOS, you can also fetch some health data from the Apple Health app or some oth­er health app from the App Store.

Next, the mark­down for the note is cre­at­ed in a “Text” con­tain­er. You can access the data direct­ly from the dic­tio­nary by typ­ing the key into the field with the red bor­der in the image. It’s the same as the id in the HTML form.

A screenshot of a user interface labeled "Dictionary," featuring options for managing a dictionary variable. The section includes fields for "Variable Name" set to "Dictionary" and "Type" indicating it is a Dictionary. Below, a dropdown menu allows selection of options like "Keys," "Values," and more. Highlighted prominently is a field labeled "Get Value for Key," currently showing "heartRate." The prompt at the bottom instructs the user to enter a key to extract its value from the dictionary or leave it blank to retrieve the entire dictionary.

The last action is to cre­ate a note from that text box con­tent. I save the note in my Obsid­i­an fold­er “00 New”; with a name, where I use the cur­rent date and the string “vital.” The note will be saved in my Vault “Obsid­i­an­Notes,” and the text will be insert­ed into the note body.

A screenshot of the Apple Shortcuts editor titled "vital." On the left side, there are various actions outlined. The workflow starts with a condition to receive no input and continues if the Shortcut input has any value. It includes steps to get a dictionary from the Shortcut input, retrieve the current weather, and define a text block that incorporates health metrics such as heart rate, blood pressure, body temperature, respiration rate, mood, and current weather conditions. Below, the workflow creates a note in an Obsidian vault using the collected data. The right side displays options and settings for the shortcut, including features for menu bar pinning, privacy settings, and Apple Watch configuration.

How to Run This Shortcut

You can start the short­cut with the run but­ton in the short­cut app. My pre­ferred way is to save it in the dock (File –> Add to Dock). When you do this, the short­cut will be saved in your user’s appli­ca­tion fold­er (~/Application or /Users/UserName/Application). In my case, it’s part of the search for apps, so Spot­light, Siri, Alfred Launch­er, or Ray­cast all will find it. If you don’t want it in the Dock, you can just move it out; the app will stay where it is.

Conclusion

If you want a nice form-based input with a great UI and user expe­ri­ence, an HTML form seems to be the best way to go. This works well for Obsid­i­an but may also be suit­able for oth­er appli­ca­tions. The exam­ple I used here is very sim­ple, and in terms of health data, it might make more sense to use the data direct­ly from the apps on the iPhone. How­ev­er, I like the idea of start­ing a short­cut and using an HTML page for form-based data entry.

Cur­rent­ly, I’m think­ing about my next project to enhance my snip­pets short­cut exam­ple by adding more user-cre­at­ed infor­ma­tion, like tags or notes, before sav­ing it in Obsid­i­an.

If you have any ideas, please share them in the com­ments. Ques­tions, feed­back, and sug­ges­tions are also wel­come.

Leave a Reply

Your email address will not be published. Required fields are marked *