HashTag Macro KM 7.0

Very cool macro!

I couldn't duplicate this so I don't really know what you mean. But Keyboard Maestro is going to try to go through your fields and configure them itself, but exactly when that happens compared to when your code is executing is hard to know.

It calls a function KMInit() before filling in the fields, so that may be the place you want to do your work. I have added for the next version calls to KMWillShowWindow() and KMDidShowWindow() which may be useful in the future.

1 Like

Peter, I'm not sure I fully understand your suggestion.

@iNik's current HTML code:

window.onload = function() {

	window.setTimeout(appendCheckboxes,0);
	
}

So, are you suggesting that it should be:

function KMInit() {
	appendCheckboxes();
}

Yeah… I can’t duplicate it either anymore.

KMInit and window.onload seem to run at about the same time. I was testing them both out to see if they changed the buggy behavior (it had no affect). Very odd.

And yes, JMichaelTX, that would be how you’d want to write up the JS.

Thanks iNik.

Just tested using the KMInit(), and it worked fine.
The checkboxes were NOT checked.

I'm working on some enhancements for the Custom HTML Prompt action, and I've thought about this but I don't think I'll do it. HTML is far too complex to safely parse, so I can't just run the text token expansion over it. At most I could perhaps special case %Variable%Whatever%, but even that is pretty ugly. What happens when your variable has quotes in it, or HTML, should it just be inserted verbatim? That could lead to some very weird behaviour.

It's easy enough to use boilerplate code in the KMInit to extract a variable (or any tokenised text) and put it as the value of an element, and then you know exactly what is going to happen.

Keep in mind too that Keyboard Maestro will fill in fields with the matching variable values when you create the Custom HTML Prompt window (as shown in the example in the Macro Library).

Peter, I'm not sure I understand your concern.

iNik's current process does exactly that: Inserts HTML code directly in the HTML code.

So, I don't see the functional difference (in terms of issues) between:

<div id="checkboxes">
   %Variable%cbArray%
</div>

and this:

<div id="checkboxes">
</div>

function appendCheckboxes() {
var cbTxt = window.KeyboardMaestro.GetVariable( 'cbArray' );
document.getElementById('checkboxes').innerHTML = cbTxt;
}

The biggest different is that the first approach of using the KM variable directly is simpler and much less prone to error.

I admit to not being an expert, but what happens if cbArray contains “</div>”? Do they actually behave the same in that case? I don’t think so - the structure of the document remains the same.

The main point remains the same though, I can’t safely parse for any text tokens - at most I could parse for variables, or I’d have to do something to make the text tokens stand out more since % characters are quite common in HTML.

It seems like to me in all cases it is incumbent on the user to provide valid HTML code. If he/she does not, then all bets are off.

I don't see insertion of HTML by JavaScript as any safer than by direct KM variable.

I don't think we were asking for anything other than just KM variables. If the user needs to use text tokens, he/she can do so in creating the KM var in the macro prior to the HTML prompt.

Use whatever syntax you like that would work. How about the shell script notation? That would make it easy to remember.

Or have a simple js function to insert a km variable or token within a script block. Save a lot of code and weirdness with a very explicit call to km.

E. G. </script>Kmtoken("%variable%whatever%") </script>

This would then evaluate the statement and insert it in-place.

You can do that already:

<script>document.write(window.KeyboardMaestro.GetVariable('Initial'))</script>
or
<script>document.write(window.KeyboardMaestro.Calculate('NOW()'))</script>
or
<script>document.write(window.KeyboardMaestro.ProcessTokens('%Variable%Initial%'))</script>
1 Like

OK, this looks interesting.

So, Peter, are you saying that

instead of this:

<div id="checkboxes">
   %Variable%cbArray%
</div>

use this:

<div id="checkboxes">
<script>document.write(window.KeyboardMaestro.ProcessTokens('%Variable%cbArray%'))</script>
</div>

Ha ha. Awesome. I forgot about the document.write function. Thanks.

Correct. Although for just reading the value, you probably want to use the GetVariable function instead of the ProcessTokens as it is simpler, but either works.

1 Like

OK, for the best and final version:

<div id="checkboxes">
   <script>document.write(window.KeyboardMaestro.GetVariable('cbArray'))</script>
</div>

I just tested this, and it displays fine.
But it does NOT remember the user's previous selection.

@iNik, @peternlewis, @ComplexPoint:

I fixed this my making a minor change to Rob's JavaScript:

// --- ALTERNATE JAVASCRIPT BY ROB TREW ---
//  Modified by:  JMichaelTX    Ver 1.1    2016-04-04  16:06 CT
//      • Add unique KM Var names for each checkbox
//      • This will allow the form to remember previous choices

function run() {
    var kme = Application('Keyboard Maestro Engine');

    var iCB = 0;
    
    return kme.variables['hashtags'].value()
        .split(',')
        .map(function (x) {
            var cbVal = x.trim();
            
    //--- ADD CODE TO CREATE UNIQUE NAME FOR EACH CHECKBOX ---
    //      (the HTML name tag is the KM Variable Name)
    
            iCB = iCB + 1
            var nameCB = "HT_CB_" + iCB

            var htmlStr =  '<label><input type="checkbox" name="' + nameCB + '" value="' +
                cbVal + '" data-ignore></input>' + cbVal +
                '</label>\n<br />';
                
            return htmlStr;
        })
        .join('\n');
}

I followed your advise and it works great for me as it supports my preferred way of entering data by keeping my fingers on the keyboard. Typing two or three letters is faster for me than selecting options with a mouse.

However, there is a problem of different apps behaving differently when you enter several hashtags as they use different delimiters (space, comma, tab...). Therefore I wonder what would the most efficient way to enter this delimiters. Please advise.

Thanks
Andrej

Is it possible to make macro aware where am I (in which application) and act accordingly?

Thanks
Andrej

If you are saying that different apps need to use different delimiters, then you can simply add a Switch/Case Action based on app name:

Here is an example Action (actually stored in my KMFAM).
Note that I have renamed the Switch/Case Action.
Replace the app names with the ones that you want to use.

1 Like

It works, thank you very much!

Andrej