Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

I have a dialog, which, when pops up, requests input from the user. How can I set the window up that the focus is on the InputField of the new window (i.e. the caret stands in the InputField), so that when the user starts typing, it is immediately registered by the field? At the moment, I have to click inside the field first to make it the active control on screen.

DialogInput[{InputField["", String], Button["Ok", DialogReturn[]]}]
share|improve this question
    
I look forward to seeing the answer to this one. –  Mr.Wizard Feb 7 '12 at 22:42

3 Answers 3

up vote 14 down vote accepted

Since Input is a DialogInput, it seemed reasonable to peek into Input's structure to understand how the focus is set. After removing the ReadProtected attribute I've realized that there is no neat way to do it, as WRI itself has done the reposition of the focus via successive SelectionMove calls.

This example below is not the original but a modified version, as the original Input definition only includes one InputField but no other expressions (like a Button). Note that it is not documented that you can use Initialization in dialogs, moreover it is colored red by the syntax highlighter to suggest an invalid option.

DialogInput[{InputField["", String], Button["Ok", DialogReturn[]]},
 Initialization :> (FrontEndExecute[{
      FrontEnd`SelectionMove[#1, Before, Notebook, 
       AutoScroll -> False],
      FrontEnd`SelectionMove[#1, Next, Cell, 2, AutoScroll -> False],
      FrontEnd`SelectionMove[#1, Previous, CellContents, 
       AutoScroll -> False],
      FrontEnd`FrontEndToken[#1, "MovePreviousPlaceHolder"]
      }] &), ShowCellBracket -> True, Selectable -> True]
share|improve this answer
    
+1 for low level digging –  Mr.Wizard Feb 8 '12 at 0:01
    
+1. I used similar code for my syntax highlighter generator, but wasn't succesful in trying to adopt it here. Good that you managed - another good example of how this is done. –  Leonid Shifrin Feb 8 '12 at 9:22
2  
@Mr.Wizard Leonid and Istvan, you all may be interested in fact that WRI changed approach and use now FrontEnd`ReferenceBoxFind which is quite handy and more general. –  Kuba Apr 2 at 7:38
    
@Kuba This seems interesting, but do you possess any further information about where, how, and who uses ReferenceBox* and BoxReference* functions? It is hard to experiment with them without any pointer on what they do. –  István Zachar Apr 10 at 16:23
    
Only from my own tests, and not much. E.g you can put BoxID almost everythere and it can be simple string. –  Kuba Apr 10 at 18:36

What's wrong with Input[""]?

share|improve this answer
    
I must assume it is not general enough, that he is building an entire dialog and that example given is quite reduced. –  Mr.Wizard Feb 7 '12 at 22:51
    
Nothing is wrong with Input but as Spartacus has pointed out, it is not general enough. Nevertheless, this pointed me to the right direction, so thanks David! –  István Zachar Feb 7 '12 at 23:29
    
Spartacus is right. My suggestion was really aimed at quick fix. By the way, István, how did you manage to peek into Input's structure? –  David Carraher Feb 8 '12 at 0:04
3  
@David: The usual way: by removing all attributes (Attributes[Input] = {}) and then querying the definition as ??Input. This trick could give useful insight only if the symbol is ReadProtected (meaning that most of its definition is written in Mathematica instead of C or whatnot), or not even then. –  István Zachar Feb 8 '12 at 0:13
    
Thanks, István. –  David Carraher Feb 8 '12 at 0:25

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

The following example sets initial focus on second InputField and you can use button to switch it to the first one, just for fun.

DynamicModule[{name = "", surname = ""},
 Column[{
   InputField[Dynamic@name, String, BoxID -> "name"],
   InputField[Dynamic@surname, String, BoxID -> "surname"],
   Button["setFocusToFirst", setFocus[EvaluationNotebook[], "name"]]
   }]
 ,
 Initialization :> (
   setFocus[nb_, ID_] := 
    MathLink`CallFrontEnd[
     FrontEnd`BoxReferenceFind[
      FE`BoxReference[nb, {{ID}}, FE`BoxOffset -> {FE`BoxChild[1]}, 
       FE`SearchStart -> "StartFromBeginning"]]];

   SetOptions[EvaluationCell[],
    CellDynamicExpression :> 
     Refresh[setFocus[EvaluationNotebook[], "surname"], None]]
   )]

minor 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). Setting this CellDynamicExression at each Initialization is not needed. You can do this once when you save/deploy DynamicModule and this cell behaviour will be preserved. I'm doing it there to not obscure the idea by additional parts of code.

share|improve this answer
2  
It is great that this can be done. It is a travesty that users have to poke around in the internals of Mathematica to accomplish a simple task like this. –  John McGee May 1 at 10:21
    
Now it's only missing the tab key jump order control ! –  P. Fonseca May 4 at 11:48
    
@P.Fonseca On Windows it switches InputFields with Tab quite well. –  Kuba May 4 at 11:55
    
Right. But through which order? Can you change the default order? In most visual languages, you can easily change the order of these jumps... –  P. Fonseca May 4 at 12:33
    
@P.Fonseca what do you mean by order in case of nonregular layout full of InputFields? You want to be able to provide list of tags (here BoxID) to go through when pressing Tab? –  Kuba May 4 at 12:39

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.