Checkboxbar with maximum choices limitation [duplicate]

I am a novice to interactive interface with Dynamic and other stuff. So don't blame on me if I ask idiot questions.

What I want is to set a checkbox and set a limitation for the maximal number that choices can be checked. For example, say I have a checkboxbar like:

CheckboxBar[Dynamic[x],{1,2,3,4}]


Now I am able to check as many choices as I like. But what if I only want to check at most two box? Is there a way to let me check the first two boxes and then the remaining unchecked one will automatically become gray(not clickable, just like the option:Enabled->False)

My naive idea was:

CheckboxBar[Dynamic[x],{1,2,3,4},Enabled->If[Length@x<2,True,False]]


But it doesn't work.

Thanks for your time! Any comments and suggestions are very welcome.

• You have to add Dynamic to the argument of Enabled, i.e. CheckboxBar[Dynamic[x], {1, 2, 3, 4}, Enabled :> Dynamic[Length@x < 3]] Jul 26, 2017 at 8:01
• Maybe this would work for you? CheckboxBar[ Dynamic[x, (x = Reverse[Take[Reverse[#], UpTo[2]]]) &], {1, 2, 3, 4}]
– Kuba
Jul 26, 2017 at 8:39
• @Kuba♦ , Thanks! This is a quite clever way! Jul 26, 2017 at 8:59
• Is this a duplicate or do you need something more? Selection Limit on CheckboxBar
– Kuba
Jul 26, 2017 at 9:37
• @Kuba I think it could be a duplicate of that one. Jul 26, 2017 at 10:52

You almost got it right. This should do what you want:

CheckboxBar[Dynamic[x], {1, 2, 3, 4}, Enabled -> Dynamic[Length[x] < 3]]


Besides the Dynamic after Enabled, which is the thing that makes everything work, I also shortened your If statement, using that Length[x] < 3 already returns either True or False (unless you do something strange with x -- if that can happen, you may want to wrap Length[x] < 3 into TrueQ). To re-enable the bar once it was disabled, you could add a Button to your notebook, such as

Button["Reset", x = {}]


Following up on your comment. A CheckboxBar where only the checkboxes get disabled that would, when clicked, exceed the limit, can be built from individual Checkboxes, e.g.:

With[{labels = {"a", "b", "c", "d"}},
DynamicModule[{x, arr, bar, n = Length[labels]},
x = Array[arr, n];
bar = (
Checkbox[Dynamic[#],
Enabled -> Dynamic[
Count[Table[arr[i], {i, n}], True] < 2 || TrueQ[#]
]
] & /@ x
);
(* initialize *)
Do[arr[i] = False, {i, n}];
(* return the bar *)
Row[Riffle[bar, labels], Spacer[10]]
]
]


• Thanks for your prompt answer! It does work. But I am sorry, I forgot to say one thing, that is once it is disabled, all the choices are disabled, which is not my intention. I expect it to only disable the remaining unchecked one, so that I can change my choices later if I check the wrong box by clicking again to un-check. Would it be possible? I tried something like Enable->{True,True,False,False} but it seems there is no such grammar to assign the checkability separately. Jul 26, 2017 at 8:17
• You should add this to your question. Jul 26, 2017 at 9:17