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.

Given a TabView panel like this one

TabView[{
  DynamicModule[{x = False}, {Checkbox[Dynamic[x]], Dynamic[x]}],
  "foo"}]

I would like to reset the value of x to its initial value (False) every time the first tab gets selected - that is, I basically want to "reset"/"reload" the tab on each selection.

Also, the variable(s) in question should remain local variables on a per-tab basis, if possible. This is, I hope to avoid a solution declaring x globally.

Any help very much appreciated (either on reloading the whole tab or on setting specific dynamic variables).

share|improve this question
add comment

2 Answers

I don't know how to deal with it when x is scoped to first tab, but I don't think it is the most important thing here.

TabView[{
  1 -> {Checkbox[Dynamic[x]], Dynamic[x]},
  2 -> "foo"}, Dynamic[k, If[# == 2, x = False; k = #;, k = #] &]]

This solution is using TabView in form TabView[{ }, i ] which is described in Help. Second argument in Dynamic is monitoring which tab is active and switching value of x.

share|improve this answer
    
But this way I'd replace the DynamicModule with Dynamic, so in each case I would need to make sure that the variable (x, in this case) is not used in some other instance? –  Bernd May 29 '13 at 10:09
    
unfortunately yes. –  Kuba May 29 '13 at 10:21
add comment

Here is a version which fully localizes the variables. Other than that it does the same as Kubas answer so I'd suggest to accept his answer:

With[{xDefault = False},
 DynamicModule[{x = xDefault, visibleTab = 1},
  TabView[{
    Row[{Checkbox[Dynamic[x]], " ", Dynamic[x]}],
    Dynamic[x]
    }, Dynamic[visibleTab, (visibleTab = #; If[visibleTab == 1, x = xDefault]) &]
   ]
  ]
 ]

Here is another solution which will regenerate the content completely, including initialization. It needs some hacky tricks to persuade Mathematica to really update the outermost Dynamic in the first tab, Mathematica seems to put quite some effort into not destroying the state of that Checkbox. Anyway, this seems to work for me:

DynamicModule[{visibleTab = 1, trigger = AbsoluteTime[]},
 TabView[{
   Dynamic[
    DynamicModule[{x = False}, 
     Row[{Pane[trigger, {0, 1}], Checkbox[Dynamic[x]], Dynamic[x]}]]
    ],
   "foo"
   }, Dynamic[
   visibleTab,
   (visibleTab = #; trigger = AbsoluteTime[]) &
   ]
  ]
 ]

You should note that in many cases it is good enough to e.g. do Row[{trigger;Checkbox[Dynamic[x]],Dynamic[x]}], but here it seems that you really have to trick Mathematica into believing that the value of dummy-variable triggeris actually seen on screen (which it actually is, but at a size of 0x1 pixels that shouldn't be too irritating :-)). The above technique can be used to create a wrapper which makes it somewhat simpler to use:

reinitializingTabView[{tabs___}, opts : OptionsPattern[TabView]] := 
 DynamicModule[{tabidx, trigger},
  TabView[
   Dynamic[Row[{Pane[trigger, {0, 1}], #}]] & /@ {tabs},
   Dynamic[tabidx, (tabidx = #; trigger = AbsoluteTime[]) &],
   opts
   ]
  ]

and then can be used e.g. like this:

reinitializingTabView[{
  DynamicModule[{x = False}, {Checkbox[Dynamic[x]], Dynamic[x]}],
  DynamicModule[{x = False}, {Checkbox[Dynamic[x]], Dynamic[x]}],
  "foo"
  }]

handling of the second argument and options could probably be improved, but whether that's worth the effort depends on how often you'll use it...

Here is yet another solution which will localize per tab but doesn't regenerate, also quite complicated and somewhat hacky:

DynamicModule[{visibleTab = 1, needsupdate = False},
 TabView[{
   DynamicModule[{x = False},
    DynamicWrapper[
     Row[{Checkbox[Dynamic[x]], " ", Dynamic[x]}]
     ,
     Hold@Print["called"];
     If[TrueQ[needsupdate],
      Hold@Print["doing something"];
      x = False;
      needsupdate = False
      ],
     UpdateInterval -> Dynamic[If[TrueQ[needsupdate], 1, Infinity]],
     TrackedSymbols -> {needsupdate}
     ]
    ],
   "foo"
   }, Dynamic[visibleTab, (visibleTab = #; needsupdate = True) &]
  ]
 ]

If you delete the Hold wrapper for the Prints you'll note that it's now updated 3 times but it only actually does something one time.

I'd really wish this would be possible somewhat simpler but couldn't find something. I consider solutions like that to just be workarounds and hope there is something cleaner to achieve the same thing.

share|improve this answer
    
But it does not localize them in each tab like Bernd wants. Or maybe I've missed something. –  Kuba May 29 '13 at 10:23
1  
@Kuba: that's true, but probably hard to avoid: if it would be local to the tab only, we can't access it, by definition. I see two possibilities to achieve that: either regenerate the tab content completely or create a "callback" to be accessable to the tab view selection-Dynamic. Both seem to not be simple to achieve. Maybe I'll get back when I have something working... –  Albert Retey May 29 '13 at 10:33
    
I Agree. So far I failed in in aproach to regenerate :) –  Kuba May 29 '13 at 10:35
    
Thanks for both proposals. If it's okay I'd wait if anyone comes up with a "regenerating" solution before I accept an answer? –  Bernd May 29 '13 at 10:44
    
@Bernd I would say You should wait :) –  Kuba May 29 '13 at 10:47
show 1 more comment

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.