7
$\begingroup$

I want to make a simple demonstration using Manipulate in which I have one or two input fields show depending on whether or not another control is True or False. How can I achieve such functionality?

Manipulate["DoSomethig", {ShowMore, {True, False}}, WhatShouldBeHere?]

ShowMore is unchecked ShowMore is checked

$\endgroup$
8
$\begingroup$

You can achieve this functionality by

Manipulate[{a, b, c}, Dynamic@Column@{
    Control[{a, 0}],
    Control[{ShowMore, {False, True}}],
    Sequence @@ If[ShowMore,
      {Control[{b, 0}],
       Control[{c, 0}]},
      {}]
    }]

enter image description here

enter image description here

This is similar to the link provided by m_goldberg, but it has a more compact form more suitable for this question.

$\endgroup$
  • $\begingroup$ Very embarassing, but would you know where to place your Sequence @@ in my answer ? I couldn't manage. $\endgroup$ – b.gates.you.know.what Oct 13 '13 at 11:24
  • $\begingroup$ @b.gatessucks In your case it is much simpler to change Dynamic@If to Dynamic@Column@If. $\endgroup$ – ybeltukov Oct 13 '13 at 11:52
3
$\begingroup$

b.gatessucks was faster than I, so he already wrote about DynamicModule, but I will publish this anyway as a complement. The answer you're really looking for might very well be found in this thread, and you can use ybeltukov's excellent answer.

This code can serve as a boilerplate for mimicking Manipulate.

Deploy@DynamicModule[{showMore = False, a = 1, b = 1},
  Panel[
   Column[{
     Dynamic@Grid[{
        {"Show more", Checkbox[Dynamic[showMore]]},
        {"a =", 
         InputField[Dynamic[a], Number, ContinuousAction -> True]},
        If[showMore,
         {"b =", 
          InputField[Dynamic[b], Number, ContinuousAction -> True]}, {}
         ]
        }, Alignment -> Left],
     Dynamic@Pane[
       Plot[a Sin[b x], {x, 0, 2 Pi}], 
       BaseStyle -> {Background -> White}
       ]
     }]]]

screenshot

$\endgroup$
2
$\begingroup$

You can find good suggestions using Manipulate in the link provided by @m_goldberg. An alternative, also mentioned there, is to use DynamicModule; below is a starting point.

    DynamicModule[{showMore, a, b , c},
     Panel@With[{controlGenerate = Function[{var, initialValue, str, range, controlType}, 
                 Control[{{var, initialValue, str}, range, ControlType -> controlType}], HoldAll]},
      Column[{controlGenerate[showMore, False, "Show more", {False, True}, Checkbox], 
        Dynamic@If[showMore, 
                   {controlGenerate[b, Pi, "b", {}, InputField], 
                    controlGenerate[c, E, "c", {}, InputField]},  
                   {controlGenerate[a, Sqrt[2], "a", {}, InputField]}], 
        Dynamic@Sin[a], 
        Dynamic@Cos[b + c]}]
   ]
 ]

screenshot

$\endgroup$
2
$\begingroup$

This is more of a comment on some of the other answers.

The problem with using If[test, display, (* else *) {}] type usage is that on its own it can lead to a lot of empty rows -- which we can see in other answers if a frame is added. e.g

enter image description here

So the way to fix this in your "openers" is to use Join since

Join[{{1, 2, 3}}, {}]
(* {{1, 2, 3}} *)

In other words Join removes the empty row giving you better design control of your layout.

enter image description here

enter image description here

$\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.