After István Zachar's points, I was investigating Input definitions to learn more. It seams that 2 years later WRI changed approach from SelectionMove based to more automatic BoxReferenceFind.
###usage
So what we only have to do is to set BoxID option for fields of interest and find those references when we want, with:
MathLink`CallFrontEnd[ FrontEnd`BoxReferenceFind[ FE`BoxReference[_NotebookObjectFE`BoxReference[ _NotebookObject, {{_IDID_String}}, FE`BoxOffset -> {FE`BoxChild[1]}, FE`SearchStart -> "StartFromBeginning"]]]"StartFromBeginning" ] ] ]
This is a way more flexible approach, e.g. you can easily put InputField somewhere else and you don't have to change SelectionMove steps to get there.
###example 1
The following example sets initial focus on second InputField and you can use button to switch it to the first one, just for fun.
ClearAll @ setFocus; setFocus[nb_, ID_] := MathLink`CallFrontEnd[ FrontEnd`BoxReferenceFind[ FE`BoxReference[nb, {{ID}}, FE`BoxOffset -> {FE`BoxChild[1]}, FE`SearchStart -> "StartFromBeginning"] ]]; Composition[ CellPrint , Cell[#, "Output", CellDynamicExpression :> Refresh[ setFocus[EvaluationNotebook[], "surname"], None] ] /. DownValues[setFocus] & , BoxData , ToBoxes ][ DynamicModule[{name = "", surname = "", setFocus} , Column[{ InputField[Dynamic @ name, String, BoxID -> "name"], InputField[Dynamic @ surname, String, BoxID -> "surname"], Button["setFocusToFirst", setFocus[EvaluationNotebook[], "name"]]} ] ]/. DownValues[setFocus] ]
###notes
Notice that I'm using CellDynamicExression, it is because Initialization often fires before Dynamic cells or cell at all are even created so setting focus then would have no effect. CellDynamicExpression fires later, where the content is in place and everything works smoothly. (in this example it does not matter but may for more complicated ones).
example 2
The code can be shorter but we need to use queued initialization:
DynamicModule[{name = "", surname = "", setFocus}, Column[{InputField[Dynamic@name, String, BoxID -> "name"], InputField[Dynamic@surname, String, BoxID -> "surname"], Button["setFocusToFirst", setFocus[EvaluationNotebook[], "name"]]}] , SynchronousInitialization -> False, Initialization :> ( setFocus[nb_, ID_] := MathLink`CallFrontEnd[ FrontEnd`BoxReferenceFind[ FE`BoxReference[nb, {{ID}}, FE`BoxOffset -> {FE`BoxChild[1]}, FE`SearchStart -> "StartFromBeginning"]]]; setFocus[EvaluationNotebook[], "surname"] )]