Skip to main content
Commonmark migration
Source Link

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

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[ _NotebookObject, {{ID_String}}, FE`BoxOffset -> {FE`BoxChild[1]}, FE`SearchStart -> "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

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"] ) ] 

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[ _NotebookObject, {{ID_String}}, FE`BoxOffset -> {FE`BoxChild[1]}, FE`SearchStart -> "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

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"] ) ] 

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[ _NotebookObject, {{ID_String}}, FE`BoxOffset -> {FE`BoxChild[1]}, FE`SearchStart -> "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

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"] ) ] 
deleted 1302 characters in body
Source Link
Kuba
  • 138.9k
  • 13
  • 297
  • 803

###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.

example

ClearAllDynamicModule[{name @= setFocus; setFocus[nb_"", ID_]surname := MathLink`CallFrontEnd["", FrontEnd`BoxReferenceFind[setFocus}   FE`BoxReference[nb, {Column[{ID}},   FE`BoxOffset -> {FE`BoxChild[1]},    InputField[Dynamic@name, FE`SearchStartString, BoxID -> "StartFromBeginning"] ]]; Composition["name"] CellPrint,  Cell[# , "Output"InputField[Dynamic@surname, CellDynamicExpressionString, :>BoxID Refresh[-> "surname"]   , Button["setFocusToFirst", setFocus[EvaluationNotebook[], "name"]]  }]  setFocus[EvaluationNotebook[], "surname"],SynchronousInitialization None] -> False  ] /., DownValues[setFocus]Initialization &:> ,( BoxData ,  ToBoxes ][    DynamicModule[{name = ""setFocus[nb_, surnameID_] := "", setFocus}  ,MathLink`CallFrontEnd[ Column[{  InputField[Dynamic @ name, String, BoxID ->FrontEnd`BoxReferenceFind[ "name"],FE`BoxReference[ InputField[Dynamic @ surname, String, BoxID -> "surname"],  Button["setFocusToFirst", setFocus[EvaluationNotebook[], "name"]]}  ]nb ]/. 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"], {{ID}} InputField[Dynamic@surname, String, BoxID -> "surname"],    Button["setFocusToFirst", setFocus[EvaluationNotebook[], "name"]]}]  ,   SynchronousInitializationFE`BoxOffset -> False,{FE`BoxChild[1]} Initialization :> (  setFocus[nb_, ID_] :=    MathLink`CallFrontEnd[  , FE`SearchStart -> FrontEnd`BoxReferenceFind["StartFromBeginning" FE`BoxReference[nb, {{ID}}, FE`BoxOffset -> {FE`BoxChild[1]},  ]] FE`SearchStart -> "StartFromBeginning"]]];]     ; setFocus[EvaluationNotebook[], "surname"]   )  ] 

###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"] )] 

example

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"]   )  ] 
added 30 characters in body
Source Link
Kuba
  • 138.9k
  • 13
  • 297
  • 803

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"] )] 

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[_NotebookObject, {{_ID}}, FE`BoxOffset -> {FE`BoxChild[1]}, FE`SearchStart -> "StartFromBeginning"]]] 

This is 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"] )] 

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[ _NotebookObject, {{ID_String}},  FE`BoxOffset -> {FE`BoxChild[1]}, FE`SearchStart -> "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"] )] 
added 748 characters in body
Source Link
Kuba
  • 138.9k
  • 13
  • 297
  • 803
Loading
deleted 218 characters in body
Source Link
Kuba
  • 138.9k
  • 13
  • 297
  • 803
Loading
added 57 characters in body
Source Link
Kuba
  • 138.9k
  • 13
  • 297
  • 803
Loading
added 550 characters in body
Source Link
Kuba
  • 138.9k
  • 13
  • 297
  • 803
Loading
deleted 11 characters in body
Source Link
Kuba
  • 138.9k
  • 13
  • 297
  • 803
Loading
Source Link
Kuba
  • 138.9k
  • 13
  • 297
  • 803
Loading