dunbarx wrote: ↑Tue Aug 26, 2025 2:14 pm
Code: Select all
on keyDown pKeyName
  if the number of chars of me = 17 then exit keydown
  if pKeyName is not in "0123456789ABCDEF" then exit keyDown
  
   put toUpper(pKeyName) after me
   if (the number of chars of me - 2) mod 3 = 0 then put ":" after me
   if the number of chars of me = 18 then delete the last char of me
end keyDown
 
yeah that works... 
unless you delete mid-string.
If you have the text 
AB:CD:EF and delete "E" and re-type it, you end up with 
AB:CD:F:E
Controlling the delete/backspace keys means you have to use rawKeyDown.
It's a bit more of a pain to allow that, but it's more natural for the user to go and delete something mid-string.
My version of the solution uses a script-local flag to track if forward-delete or backspace is pressed (to track where selection/caret should go), a function to insert a ":" every 2 chars triggered by he textChanged handler which also repositions the selection/caret where text input should go, and uses the rawKeyDown handler to allow only the permitted chars to be entered into the field up to total of 17 chars. 
textChanged (note: this uses a script local flag which is set in rawKeyDown and used in textChanged)
Code: Select all
local sDeleteFlag = false
on textChanged
    local tSelection
    if sDeleteFlag then
        put word 4 of the selectedChunk of me into tSelection
    else
        put word 2 of the selectedChunk of me into tSelection
    end if
    put getTextAsMAC(the text of me) into me
    select after char tSelection of me
end textChanged
function for ":" insertion and convert to upper case
Code: Select all
function getTextAsMAC pText
    local tResult
    replace ":" with empty in pText
    set the itemDelimiter to ":"
    repeat with x = 2 to the number of chars of pText step 2
        put char x-1 of pText & char x of pText into item (the number of items of tResult + 1) of tResult
    end repeat
    return  toUpper(tResult) 
end getTextAsMAC
rawKeyDown handler - only allows permitted chars and up to a max length of 17 chars including the ":"s
Code: Select all
on rawKeyDown pKeyCode
    switch 
        case pKeyCode > 64 and pKeyCode < 71 and length(the text of me) < 17 # upper case
        case pKeyCode > 96 and pKeyCode < 103  and length(the text of me) < 17 # lower case
        case pkeyCode > 47 and pKeyCode < 58 and length(the text of me) < 17 # numbers
        case pKeyCode > 65360 and pKeyCode < 65365 # arrow keys
            put false into sDeleteFlag
            pass rawKeyDown
            break
        case pKeyCode = 65535 or pkeyCode = 65288 # delete/backspace
            put true into sDeleteFlag
            pass rawKeyDown
            break
    end switch
end rawKeyDown
If you want to allow deletion mid-string this is a more verbose way of letting it happen.