## equivalent checkboxes

Super User

Joined:

Mar 17, 2015

So I have some checkboxes that are equivalent.  Meaning (in this case) that 1=2=3.  I'm trying to make it when you check/uncheck any of 1 2 or 3, it will check/uncheck the others.  I can get it to set them, but once I set them.  There's not an obvious way to check which one was unchecked.  Because of the constraint I have where everything has to be local in the funciton box.  So I can't have a Last_selected variable or anythign like that.

Here's what I've tried so far.

``````new window("Test",
cb = checkbox({"1", "2", "3", "4", "5"});
);
eq = Associative Array({{1, {2, 3}}, {2, {1, 3}}, {3, {1, 2}}});
cb <<Set Function(
Function({self = cb},
items = self << Get Items;
sel = self << Get Selected;
for(i=1, i<=nitems(sel), i++,
id = Num(sel[i]);
if(eq << Contains(id),
equivalencies = eq[id];
for(k=1, k<=nitems(equivalencies), k++,
remove from(sel, Contains(sel, char(equivalencies[k])) );
);
for(k=1, k<=nitems(items), k++,
if(Contains(equivalencies, Num(items[k])) ,
self << Set(k, 1)
);
)
)
);
)
)``````
1 ACCEPTED SOLUTION

Accepted Solutions

Super User

Joined:

Mar 17, 2015

Solution

Thanks @Craige_Hales.  That's exactly what I needed.

For posterity, this does what I'm trying to do.

``````Names Default to here(1);
new window("Test",
cb = checkbox({"1", "2", "3", "4", "5"});
);
eq = Associative Array({{1, {2, 3}}, {2, {1, 3}}, {3, {1, 2}}});
cb <<Set Function(
Function({self, which},
items = self << Get Items;
sel = self << Get Selected;
id = Num(items[which]);
checked = self << Get(which);

if(Contains(eq, id),
For(i=1, i<=nitems(eq[id]), i++,
self << Set(Contains(items, char(eq[id][i])), checked);
)
);

)
);``````
5 REPLIES

Super User

Joined:

Jun 23, 2011

From a user interface standpoint, since 1, 2 and 3 are the same, why don't you modify your screen to show them combined with one checkbox?  I.e.

[  ] 1, 2, 3

[  ] 4

[  ] 5

Super User

Joined:

Mar 17, 2015

Because in reality, it would be more like

1 - description of 1, 2-description of 2, 3-description of 3

4-description of 4

5-description of 5

and there a lot of these boxes on the page and it gets VERY cluttered very quickly.

and sometimes there are 7 things that are equivalent

That as well as the fact as the customer said do it this way.  :P

Staff

Joined:

Mar 21, 2013

``````f = Function( {this, which},
{default local},
n = N Items( this << getitems );
For( i = 1, i <= n, i++,
this << set( i, i != which )
);
(this << sib) << color( which );
);

New Window( "checkbox callback",
H List Box(
V List Box(
Check Box( Words( "1 2 3 4 5 6 7 8 9" ), <<setfunction( f ) ),
Spacer Box( size( 20, 20 ) )
),
Spacer Box( size( 40, 1 ) ),
V List Box(
Check Box( Words( "1 2 3 4 5 6 7 8 9" ), <<setfunction( f ) ),
Spacer Box( size( 20, 20 ) )
)
)
);

``````

Checking a box makes all the others checked

Craige

Super User

Joined:

Mar 17, 2015

Solution

Thanks @Craige_Hales.  That's exactly what I needed.

For posterity, this does what I'm trying to do.

``````Names Default to here(1);
new window("Test",
cb = checkbox({"1", "2", "3", "4", "5"});
);
eq = Associative Array({{1, {2, 3}}, {2, {1, 3}}, {3, {1, 2}}});
cb <<Set Function(
Function({self, which},
items = self << Get Items;
sel = self << Get Selected;
id = Num(items[which]);
checked = self << Get(which);

if(Contains(eq, id),
For(i=1, i<=nitems(eq[id]), i++,
self << Set(Contains(items, char(eq[id][i])), checked);
)
);

)
);``````

Super User

Joined:

Jun 23, 2011

Still chasing my original idea.  Simplifies some things but adds to the complexity of the checkbox handlers, if you have a lot of them.

``````Names Default to here(1);
new window("Test",
lineup box(ncol(2),
cb1 = checkbox(""),
tb1 = textbox("First Line\!NSecond Line\!NThird Line"),
cb4 = checkbox(""),
tb4 = textbox("Four"),
cb5 = checkbox(""),
tb5 = textbox("Five"),
)
);
``` ```