2
$\begingroup$

How do you make enterpriseCDFs save the state of buttons sliders, listpickers etc? I manipulated a CDF and saved it on exit but all the buttons etc were reset when I started it again.

I've made a simplified example: If you execute the last line it produces a toggler bar and a button in a single output cell. I export that cell as a stand alone enterprise CDF. When I open it in cdf player, toggle a few buttons, save, close and reopen, the state is reset to the original first three buttons pressed. Is it possible to get the state of the buttons to be remembered across saves?

data[n_] := Range[n];
series = {1, 2, 3};
cdf = 
  DynamicModule[{}, 
    Grid[{
      {TogglerBar[Dynamic[series], Range[6]]},
      {Dynamic[
         PopupWindow[Tooltip[Button["Show data"], data[series]], data[series],
           WindowSize -> All,
           WindowTitle -> "data", 
           WindowElements -> {"VerticalScrollBar", "HorizontalScrollBar","StatusArea"},
           ScrollingOptions -> 
             {"HorizontalScrollRange" -> Automatic, "VerticalScrollRange" -> Automatic}], 
         TrackedSymbols :> Full]}},
      Alignment -> {Top, Top}],
      SaveDefinitions -> True];
cdf

I also tried exporting with the command:

CDFDeploy[NotebookDirectory[] <> "testCDF.cdf", cdf, 
  "Method" -> "Standalone", "Target" -> "PlayerPro"];

with same result (not sure if target needs to be playerpro though; the aim was for it to be an enterpriseCDF state-savable with the standard player.

$\endgroup$
  • $\begingroup$ Have you tried to use SaveDefinitions->True? $\endgroup$ – Murta Jul 21 '14 at 4:37
  • $\begingroup$ Is it all within a DynamicModule? $\endgroup$ – Mike Honeychurch Jul 21 '14 at 4:39
  • $\begingroup$ Yes, I have SaveDefinitions-> True and it is in a DynamicModule There were some functions defined outside the dynamic module that I brought inside it and got the same result. I should try and make a simplified version to see if it does the same. $\endgroup$ – DrBubbles Jul 21 '14 at 4:55
  • $\begingroup$ Without seeing your code it is impossible to answer this question $\endgroup$ – Mike Honeychurch Jul 21 '14 at 5:07
  • $\begingroup$ @MikeHoneychurch I added an example $\endgroup$ – DrBubbles Jul 22 '14 at 15:02
2
$\begingroup$

SaveDefinitions is messing this up because it creates an initialization that loads the original values for series. It is better to avoid SaveDefinitions and initialize functions using Initialization and to have all your variables localized within the DynamicModule. When you do that the values of series will be stored locally in the notebook and not be reset to the original values.

cdf = DynamicModule[{series = {1, 2, 3}}, 
  Grid[{{TogglerBar[Dynamic[series], 
      Range[6]]}, {Dynamic[
      PopupWindow[Tooltip[Button["Show data"], data[series]], 
       data[series], WindowSize -> All, WindowTitle -> "data", 
       WindowElements -> {"VerticalScrollBar", "HorizontalScrollBar", 
         "StatusArea"}, 
       ScrollingOptions -> {"HorizontalScrollRange" -> Automatic, 
         "VerticalScrollRange" -> Automatic}], 
      TrackedSymbols :> Full]}}, Alignment -> {Top, Top}],
  Initialization :> {data[n_] := Range[n]}]
$\endgroup$
  • $\begingroup$ Excellent! have quite a few functions and calculations related to the variables that can change across save sessions but presumably there's noting wrong with defining all the functions in the Initialization part and putting all the calculations between the variable definitions and the Grid expression. This is my first attempt at an enterpriseCDF and enabling saves is one of the things I've been looking forward to. $\endgroup$ – DrBubbles Jul 23 '14 at 1:20
  • $\begingroup$ Having tried this and finding my code was such a mess that I couldn't see how to untangle it to the form described by Mike Honeychurch (the way I should do future projects!), I found I could keep SaveDefinitions->True, then have a button to export a list of initialization variables as a .mx file then another button to re-import them to the same list of variables when needed, with the list as a TrackedSymbol to trigger an update. One caveat, the .mx files exported by mathematica (v10) and enterpriseCDF (v9) are different! Maybe v10 CDF will resolve that?) $\endgroup$ – DrBubbles Jul 23 '14 at 23:50
  • $\begingroup$ @DrBubbles No offense but rather than compound the mess wouldn't it be better to rewrite from scratch and make it all work ...and make it maintainable? $\endgroup$ – Mike Honeychurch Jul 23 '14 at 23:55
  • $\begingroup$ Yes I really should and I intend to wipe my white board and try and lay the problem out the way it should be using the method you described. The essential building blocks are sound but I had let it get out of control through sloppiness. It isn't a commercial environment, more a tool to help my colleagues and I wade through data, but I'd still rather it was extensible (and intelligible to others!). Thanks again for your solution; it is a good lesson to think ahead when at the beginning of a project. $\endgroup$ – DrBubbles Jul 24 '14 at 3:40
1
$\begingroup$

EnterpriseCDF documents allow you to save the state of dynamic module variables when using the Wolfram CDF Player, so simply defining series to be a dynamic module variable should fix your problem. Here is code that creates a simple CDF file where the TogglerBar selection is saved when you quit and save the CDF file:

cdf=DynamicModule[{lst = {1,2,3}},
  Framed@Column[{
    TogglerBar[Dynamic@lst, Range[1,6]],
    Dynamic@lst
  }], SaveDefinitions->True
  ]

CDFDeploy["test.cdf", cdf, Method->"Standalone", "Target"-> "PlayerPro"]
$\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.