# Self-referential list or table of buttons

How could one create a table or list of buttons, such that clicking on a button removes the button itself from the list?

• like a self destruct mode? :-) – chris Nov 7 '12 at 17:29
• Kind of, what I'm actually building is an array of arrays (of buttons) - each line of buttons has a 'delete this line' button, but I thought an answer to the simplest case would suffice for me. – Cuboid Nov 7 '12 at 17:33
• This is a bit Slaughterhouse-Five-ish :-) – Yves Klett Nov 7 '12 at 17:47
• Take a look at this related question if you need more complicated applications: mathematica.stackexchange.com/questions/6211/… – Szabolcs Nov 7 '12 at 18:53
• Thanks for all the helpful answers. – Cuboid Nov 8 '12 at 22:55

The crux of the problem is defining an identity for the buttons. As such a nice way is to keep them unevaluated in the list and define a structure to display them as buttons, this makes identifying them and deleting them simple:

 list = Table[button[i], {i, 5}];

SetAttributes[display, HoldAll]
display[list_] := list /. button[id_] :>
Button["#" <> ToString[id] <> " Press me!", list = DeleteCases[list, button[id]]]

Dynamic[display[list]]


The above images shows the state after #4 was clicked and deleted. Using this method, the list is quite simply the line:

{button[1], button[2], button[3], button[4], button[5]}


Which is easy to handle and manipulate, and the buttons are just a visual representation of it. And it makes it very easy to put new buttons back, just run AppendTo[list,button[42]] and you get a new button, without having to retype all the code related to how it works in the dynamic display.

Of course!

button := Button["Press me!",
list = Drop[list, 1]];
list = Table[button, {5}];
Dynamic[list]

• May be Dynamic[Row@list] is even better for cosmetic beauty. When the list is empty it does not show the sad empty list {}! – PlatoManiac Nov 7 '12 at 17:49
• This is not actually an answer to the question. This is a list of buttons that when pressed will delete the first button in the list.The question was for a button capable of deleting itself. – jVincent Nov 8 '12 at 14:25
• @MarkMcClure I never called your answer trash. I raised what I believe is a quite objective critique, that your answer will visually appear to solve the question, but in fact does not do what was asked for. I stand by that post, but feel forced to delete responses to any you delete. I would urge you not to urge users to delete their comments critiquing your solutions. And if ever you feel the need to state in a comment that you will delete it, I urge you to not post it all. – jVincent Nov 8 '12 at 15:31
• @MarkMcClure This point has been raised in cases where comments suggesting improvements lead to the improvement being implemented and therefore becoming moot. Not in cases where flaws are pointed out and the author argues back that since he's answer was accepted the flaw should be ignored. If you where to improve you answer based on the comment, then it would be moot and deletion would be natural. And again urging other users to delete comments because they don't suit you is in bad tasted in any case, as is posting comments with immediate deletion in mind. In such cases you should use the chat – jVincent Nov 8 '12 at 15:45

If you only want to remove one button, the solution is easy:

list = {Button[1], Button[2, list = Delete[list, 2]], Button[3]};
Dynamic@list


If you want to remove multiple unique buttons, you have to use some kind of identification for each button other than the actual position in the list, as that is changed when one of them is removed. Here I use a $$position \rightarrow button$$ identifier:

list2 = (# -> Button[#, list2 = DeleteCases[list2, _[#, _], 1]]) & /@ Range@4;
Dynamic@(Last /@ list2)


After v10, it is even simpler with associations:

a = AssociationMap[Button[#, a = KeyDrop[a, #]] &, Range@4];
Dynamic@Values@a