Dynamic window possible?

I don't know if the term "dynamic" is the proper one, but I think it is...
I have this HTML file that I created that contains some simple JavaScript that does some calculations for music purposes such as calculating loop lengths, BPM, etc.

So there are 2 things I would like to do:
1 - Convert that tool from HTML+JS to a KM macro
2 - I would like to have a field that updates automatically when the calculation fields have numbers. This is the calculator I created:

image

So my goal is to have a macro that when I type numbers in those 2 fields (Loop Length and Number of Beats), the field below Final BPM, Final BPM (Half) and Final BPM (Double) show the value automatically, without me having to click the Calculate button.

Is this possible with KM?
I would guess that the HTML Form would be the way to achieve this along with an Execute Javascript action or something like that?

Any tips?

I created this a while ago, when I was learning some basic JavaScript and since I don't work with it on a regular basis, I can't really understand what's here 100%, but here's the script:

/* eslint-disable strict */
/* eslint-disable no-implicit-globals */
// BPM Calculator Variables and HTML grab
const bpmSecondsInput = document.getElementById('bpmLoopLength');
const bpmBeatsInput = document.getElementById('bpmNumberOfBeats');
const halfDouble = 2;
const standardBPM = 60;

document.getElementById('resultBPM');
document.getElementById('resultBPMHalf');
document.getElementById('resultBPMDouble');
document.getElementById('bpmCalculate').addEventListener('click', bpmCalculateFunc);

// BPM Calculator Function
function bpmCalculateFunc () {
    const bpmSeconds = bpmSecondsInput.value;
    const bpmBeats = bpmBeatsInput.value;
    const bpm = standardBPM * (bpmBeats / bpmSeconds);
    const bpmHalf = bpm / halfDouble;
    const bpmDouble = bpm * halfDouble;

    document.getElementById('resultBPM').innerHTML = `${bpm} bpm`;
    document.getElementById('resultBPMHalf').innerHTML = `${bpmHalf} bpm`;
    document.getElementById('resultBPMDouble').innerHTML = `${bpmDouble} bpm`;
}

// Loop Calculator Variables and HTML grab
const loopBPMInput = document.getElementById('loopBPM');
const loopBeatsInput = document.getElementById('loopNumberOfBeats');

document.getElementById('loopCalculate').addEventListener('click', loopCalculateFunc);

// Loop Calculator Function
function loopCalculateFunc () {
    const loopBPM = loopBPMInput.value;
    const loopBeats = loopBeatsInput.value;
    const loopLengthResult = standardBPM / (loopBPM / loopBeats);
    const loopLengthResultMS = loopLengthResult * 1000;

    document.getElementById('resultLoopLength').innerHTML = `${loopLengthResult} sec <br> ${loopLengthResultMS} ms`;
}

If this is too complex I can always create a simple macro with a Prompt User Input action that then does the calculation and it can always run the same macro in case I want to calculate something else without having to look for the macro again, eventually cancelling the macro once I'm done, but if this can be done in real time (showing the result while I'm typing) and without running the macro in a loop until cancelling it, even better :slight_smile:

Sure, I have a tip. It's entirely possible to have KM grab every keyboard key as a hotkey. I've done this, and I've previously uploaded macros that do that. This is the first half of your problem - i.e., finding a way to input data without the user having to press an ENTER key or a SUBMIT button or anything like that. There's no need for Javascript in this portion of the problem. Simply using digits as hotkeys, you can get KM to instantly take action when the user presses a key.

The second half of your problem is finding an output mechanism that can be modified dynamically by KM. Technically, KM can send its dynamically created data to any app, such as a Numbers spreadsheet. That would likely require some Applescript (for the best, clean solution) and I'm not too adept at that. KM does have a Custom HTML action which also might be able to handle your output need, but I'm not sure about how to use that to solve your problem, yet.

Since the output you are generating is simply three groups of numbers, it would actually be very, very easy (no Javascript required) to use the KM action "Display Progress Bar" to display your output. I do this trick every day. So for example you could create a Progress Bar that looks like this: (variables would replace the constants in this example.)

I do this a lot. I probably have >100 macros that display variables in this manner. It lets me show data to myself very easily, as long as it's only one line of data. I really wish KM had more powerful options for displaying data without having to revert to HTML and Javascript (although I do appreciate that it has that option.)

I know it's not pretty, so I suspect you will reject this idea, but it's entirely possible to use the Display Progress Bar to show all the data that you want, and to have KM macros grabbing digits as hotkeys to let the user update this window. It could even be done with a very short macro.

1 Like

Keyboard Maestro’s Custom HTML Prompt action can display HTML/JS in a window, so if you already have it in that form, it's possible that would be your simplest solution.

1 Like

Thank you for the tip. I can see how the first half of your solution could help with the typing "issue".
The second half, though, I don't seem to understand how that would be different from, for example, showing a notification? It seems that the progress bar is only showing some data that a notification could also show...

You mentioned Numbers, but I'm avoiding external sources, otherwise I would keep the HTML file as is, since it's already working as expected.

Yes, that's what I thought, but now I have 2 issues:
1 - The JavaScript is an external .js file and I'm not familiar with JS enough to make that be included in the HTML (if that's the only route when using that KM action)?
2 - How would I be able to have the results display in real time as I type, without relying on the Calculate button?

  1. The Display Progress window can be placed anywhere on the screen by the user.
  2. Notifications are animated, and slow.
  3. The Display Progress window can be turned invisible at will by either the user or the KM action.

But sure, Notifications could potentially be acceptable.

Have a look at How to Create a Job Calculator? for a Custom HTML Prompt with JavaScript that updates itself when fields in the table change.

1 Like

Thank you for sharing this.
I downloaded, imported and played with it. It seems like it does something that could be adapted to what I'm trying to do.
I just need to spend some time checking how it's working and how it can be modified.

I noticed a few things:
1 - Changing the values in the Words column, never updates the Amount column. I always have to click Update. Is this by design? If so, would it be possible to change that behavior? My idea is to update the "total" whenever I type.
2 - The 75-84% cell doesn't auto-update the amount, but that's the only cell behaving like that. Maybe a "glitch"? I only need 2 fields anyway for this macro, but I have another tool I would like to build, similar to this one, and for that one I can see that having these many fields or even a few more, could be necessary.

I think for now those are the 2 major things I noticed, before I dive deep into trying to adjust it to the macro I would like to create.
But yes, this seems to be a great starting point.

My "calculator" has 2 sections though, I don't know if it's easy to adapt your macro to this? Basically it's like 2 calculators in a single macro like this:

So I need 2 "calculation" fields on the left that update 3 different results also on the left, and then the 2 fields on the right that update a single result on the right.
Hope it makes sense?

Thanks! :raised_hands:

Yes, by design (as explained in the post) for the total (not individual amounts). Some fields might be blank so Update is manual.

The post also explains how to make an automatic total.

I'd have to look. Sounds like I missed updating that code.

What actually happens depends on what JavaScript function is called after which event. So, yes, it can be adapted. Start small, get one going, build the other, then combine.

This doesn't work but it does provide you with a comparable HTML form for your macro. It should trigger automatic calculation whe Number of Beats is changed on either side. But I really don't know what I'm chasing here, so it doesn't.

BPM.kmmacros (4.4 KB)

1 Like

I'm in the middle of some important work so I haven't explored the original script, because I know that it will require me to spend a few hours playing with it, modifying it, etc.

My goal with this macro is that

  1. I can type whatever value I want, so in your recent macro, those up/down buttons wouldn't be needed/useful for my goal, because the values are not "fixed". What I mean is that the milliseconds could be something like 478 and so it's easier to just type that number. There's also no need to adjust that value by increments of 1, because you need to know the exact value before you even run the macro. The Number of Beats, it's even "worse" than that, because you can have 1.5 beats, or even 1.25 beats, etc.
  2. I need the results to be updated when any of the top values are updated, not just the Number of Beats. So basically the script is updated the moment there are 2 values (Loop Length and Number of Beats; or BPM and Numbers of Beats on the right).
    Once there are 2 fields with values, the results at the bottom get updated. From there, if I change one of the values, it automatically updates the results.
    This is the only way to make the macro do something that I currently can't with the HTML/JS version I have

I was just checking all the "features" I wanted to have (including errors, etc) and I think that trying to modify your macro would most definitely give me a lot of headaches and I would spend hours on it, because of my hyper basic knowledge when it comes to JS, so I decided to create a simpler version that does what I need it to do. It doesn't update the values in real time, but at least I'm no longer dependent on opening an HTML file and I can just hit ENTER to calculate (with the HTML version I would have to actually click the CALCULATE button).

Thank you for trying to help me with this though. I just wish I was more familiar with JS to make the modifications I wanted to make.

BPM & Loop Calculator.kmmacros (22 KB)

Keyboard Maestro Export

Although it is not possible for a Keyboard Maestro Prompt to execute a calculation as soon as a number is entered it is possible to make this kind of Macro more user friendly by having it remember values each time it loops so you can see at a glance what you entered and while the dialog is open you don't have to keep entering all the numbers for each run. I find myself doing this a lot and the Prompt can be left floating while you are using it.

Easier to show than to explain:

Dynamic Prompt-Animated GIFF 640 12fps

Dynamic Prompt.kmmacros (6.2 KB)

Click to Show Image of Macro

1 Like

You don't have to use the arrows. Just type in the box as you're used to doing.

The issue for me is that I have no idea what your HTML/JS script is doing or what the values mean so I can only guess at it. Can you upload your current HTML/JS?

And yes, the output values can be updated when either field is changed.

Never say something is impossible with KM, or I may take up the challenge. Here's a small group of macros that can multiply two integers and display the results instantly. You can use digit keys to enter your digits, or Backspace to erase a digit, or Delete to clear a field, or Tab to switch between the two numbers. You can also press Q to quit.

You should minimize all windows when you start this macro, otherwise the keys you press, including Del, will be passed on to your active window. So if KM is active when you run this macro then when you press Del the KM Editor may delete something. The reason I left this behaviour in my program is that this is just a proof of concept.

I realize that this solution won't satisfy the person who started this thread. It's merely here to show some techniques that can be used to display some data instantly.

Calculator (A*B) Macro (v11.0.2)

Calculator (A*B).kmmacros (5.7 KB)

This version updates on each keystroke. And it formats the results. The screen shot is nonsense because I don't now what legal values might be, but you get the idea.

BPM.kmmacros (4.7 KB)

You're right, the JavaScript is tricky but I think this does everything you want.