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.