Close, you should do a script trigger based on object keystroke. The test on length is ok. No loop required.
Thanks for the help, I have set the trigger to onKeyStroke and the script "If [Length (Get ( ScriptParameter )) = 3] Go to Next Field End If ( I set the parameter to "Set1" "Set2" ect....
But still doesn't tab to next field when more than 3 characters are typed, am I mising something?
OnObjectKeystroke is one possibility, but your original idea of using OnObjectModify is fine, too.
You've got the right idea, but if you implement it the way you've written it, you'll have to use a separate script for each field. If you can write the script so that it will work with whatever field you happen to be in, you can use the same script with all 6 of your registration key fields. The Get ( ActiveFieldContents ) function is great for this:
If [not TriggersAreActive]
Exit Script [True]
If [Length ( Get ( ActiveFieldContents ) ) ≥ 3]
Go to Next Field
Exit Script 
You could pass the contents of the current field via script parameter, too; then that's one more thing you have to remember to set-up for each field using the script, one more thing for someone to potentially get wrong.
You'll notice that the first three lines of this example have nothing to do with the purpose of the trigger. As a best practice, it's a good idea to write triggered scripts so that you can programmatically disable them; the FileMakerStandards.org link includes a few custom functions that make that easier.
All working now, just need to be able to clear fields if wrong characters are entered. Got to love FileMaker fix one problem and create another
Thanks for the link to best practice, and the alternative solution to my problem. I was using Get ( ScriptParameter ) which was working, but your solution is more portable.
For this case, I prefer OnObjectModify to OnObjectKeystroke, for the following reason: timing is everything.
I just did something similar. I have a global search field that searches our JobNumber. Rather than making the user hit enter, tab, etc to commit the record and run the search, I used OnObjectModify to auto-fire it when the Length (zg_Search_JobNumber) = 6. (Our business logic dictates that all job numbers are 6 digits.)
OnObjectKeystroke runs the script before the event (the keystroke) has been processed. For this reason, when the user enters the 6th digit (or 3rd in your case), OnObjectKeystroke won't actaully do anything, since it runs the script before that keystroke has been processed… and before the keystroke has been processed, there are 1 less characters in that field.
You can work around it by using the above method of saying > instead of =, but then you might get stuck not being able to modify the field. Each time you do a keystroke, the trigger will fire before that key is processed, and run the search in my file, or go to the next field in your file.
A better wrok-around would be using = and your target number +1, but I can see that getting confusing when you (or someone else) goes to look at what you did 6 months from now.
OnObjectModify, on the other hand, fires after the event (the keystroke) has been processed. To me, this just makes more sense in both of our scenarios.
I use OnObjectKeystroke when I want to capture the user's typing and alter/prevent/etc what they are doing.
Just my $.02, for what it's worth.
After playing around wih several options, in this case I would agree. I found I had to change script to >2 not 3 to move into next field, which I found strange.