3
$\begingroup$

I'm trying to create a user interface in Mathematica; the user will enter specified information, it will be processed, and then data will be inserted into a MySQL database. The pieces work independently but when I put them together, odd things happen.

So for example, this works:

Module[{ss, flist},
 flist = {"f1", "f2", "f3"};
 ss = First[flist];
 CreateWindow[DialogNotebook[{
    PopupMenu[Dynamic[ss], flist],
    ChoiceButtons[{"Enter", "Cancel"}, {DialogReturn[{Print["ss: ", ss]}]}]}]];
];

But the following, which seems to be substantially identical, does not. Specifically, if the user doesn't select something new from the popup menus, the variables never get initialized.

Module[{ss, flist, ci, clist},
 flist = {"f1", "f2", "f3"};
 clist = {"c1", "c2", "c3"};
 ss = First[flist];
 ci = First[clist];
 CreateWindow[DialogNotebook[{
    PopupMenu[Dynamic[ss], flist],
    PopupMenu[Dynamic[ci], clist],
    ChoiceButtons[{"Enter", "Cancel"}, {DialogReturn[{Print["ss: ", ss, ". ci: ", ci]}]}]}]];
 ];

What am I missing?

$\endgroup$
4
$\begingroup$

I suppose the it is expected and it happens because after prompting a DialogNotebook the evaluation of Module is finished and a Temporary attribute of its variables is kicking in.

Why the first example works the second doesn't? I don't know but how a Temporary attribute works is not documented well.


  • One way to make it work is to use kernel blocking dialog (Input, DialogInput, ChoiceDialog) to not finish Module before DialogReturn[]:

    Module[{ss, flist, ci, clist}, 
      flist = {"f1", "f2", "f3"};   clist = {"c1", "c2", "c3"};
      ss = First[flist];   ci = First[clist];
    
      DialogInput[
         Column@{
           PopupMenu[Dynamic[ss], flist], 
           PopupMenu[Dynamic[ci], clist], 
           ChoiceButtons[
               {"Enter", "Cancel"}, 
               {DialogReturn[{Print["ssd: ", ss, ". cid: ", ci]}]}
           ]
         }
      ];
    ]
    

    Notice the red syntax highlighting over Dynamic[ss] and Dynamic[c1]. It's because it's good habit to not to use Module's variables inside Dynamics inner to them [1]. Here it should not harm but I'd use the second approach anyway:

  • Pass Module's variables to the Dialog and forget about old Module.

    Module[{ss, flist, ci, clist}, 
       flist = {"f1", "f2", "f3"}; clist = {"c1", "c2", "c3"};
       ss = First[flist]; ci = First[clist];
    
       CreateWindow[ DialogNotebook[ DynamicModule[
         {ssd = ss, cid = ci}
         ,
         Column@{
            PopupMenu[Dynamic[ssd], flist], 
            PopupMenu[Dynamic[cid], clist], 
            ChoiceButtons[
              {"Enter", "Cancel"}, 
              {DialogReturn[{Print["ssd: ", ssd, ". cid: ", cid]}]}
            ]
         }
        ]]];
       ]
    

[1] "Module variables should never appear inside Dynamics ... internal to that Module." - John Fultz

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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