I would like to update specific parts of a Grid
dynamically in different ways. Consider the following toy example: I have two rows: one must be updated one-by-one (a, b, c), as these symbols depend on different triggers; the second row depends on one single trigger (show) that allows displaying/hiding some data.
Now I know that I can wrap the whole Grid
structure into Dynamic
, and even specify which symbols to track, thus this example does what I want:
Checkbox[Dynamic[show]]
test = {0, 0};
Dynamic[Grid[{{Dynamic@a, Dynamic@b, Dynamic@c},
If[show, Prepend[test, "test:"], {}]}, Frame -> All],
TrackedSymbols :> {show}]
Though for certain reasons I would like to have a locally specified Dynamic
, that is only applied to the second row of the Grid
.
For those who are wondering what ungodly situation would it be, just imagine the followings: show
is used in any of a
, b
or c
, and these I do NOT want to update when show
is changing, their changes depend on other triggers. Why not remove then show
from the symbols of the first row? Imagine, I can't, as show
is present in a function that is used in a
, b
or c
, and this function I cannot access easily.
Of course wrapping the first argument of If
into Dynamic
won't help here, as the Grid
itself or any of its cells won't become dynamic:
Grid[{
{Dynamic@a, Dynamic@b, Dynamic@c},
If[Dynamic@show, Prepend[test, "test:"], {}]
}, Frame -> All]
Furthermore, wrapping a row into Dynamic
makes the given row invalid, as it does not have head List
anymore:
Grid[{
{Dynamic@a, Dynamic@b, Dynamic@c},
Dynamic@If[show, Prepend[test, "test:"], {}]
}, Frame -> All]
Mapping Dynamic
over the row does not work either because show
is not updated dynamically:
Grid[{
{Dynamic@a, Dynamic@b, Dynamic@c},
Dynamic /@ If[show, Prepend[test, "test:"], {}]
}, Frame -> All]
Also, wrapping Dynamic[If[...]]
around list members work, but now I have to evaluate If
3 times instead of just 1.
Grid[{
{Dynamic@a, Dynamic@b, Dynamic@c},
Dynamic[If[show, #, ""]] & /@ Prepend[test, "test:"]
}, Frame -> All]
Would like to know if there is any solution to overcome this particular problem by locally applying a Dynamic
wrapper on a row.
Here is a solution using the Experimental ValueFunction
show = True;
test = {0, 0};
Checkbox[Dynamic[show]]
Now write your own little Dynamic update function on the side
Needs["Experimental`"];
row = {};
updateRow[x_, v_] := row = If[v, Prepend[test, "test:"], {}];
ValueFunction[show] = updateRow;
Now make the Grid, and now can use Dynamic on EACH row, not around the whole Grid, which is what you wanted:
Grid[{
{Dynamic@a, Dynamic@b, Dynamic@c},
{Dynamic@row}
},
Frame -> All
]
ps. I just read a post here by telefunkenvf14 that mentions this package and this function, which I did not know about, and when I saw this function, I remembered this question, and I thought it should be possible to use that function to solve this problem.
ps. I need to work more on placing the grid row correctly....
update(1)
I can't figure how to splice the final row over the columns in the grid. Which is strange, as it has List head, yet it won't go across all the columns. It will only go in the first cell. Tried Sequence, SpanFromLeft, and such, but no luck. May be someone can figure this part out.
Here is my current trial:
Needs["Experimental`"];
row = {};
updateRow[x_, v_] := row = If[v, {"test:", 0, 0}, {}];
ValueFunction[show] = updateRow;
show = False;
Checkbox[Dynamic[show]]
f = Grid[{
{Dynamic@a, Dynamic@b, Dynamic@c},
List@Dynamic[row]
},
Frame -> All
]
It seems it should be doable. I do not see what is the problem now...
update(2)
As a temporary solution, I split the second row by force before hand. This made it possible to do what I want. Not sure if this meets the OP specifications or not (my guess is that it does not), but here it is:
Needs["Experimental`"];
ra = 0;
rb = 0;
rc = 0;
updateRow[x_, v_] :=
row = If[v, ra = "test:"; rb = 0; rc = 0, ra = ""; rb = ""; rc = ""]
ValueFunction[show] = updateRow;
show = False;
Checkbox[Dynamic[show]]
f = Grid[{
{Dynamic@a, Dynamic@b, Dynamic@c},
{Dynamic@ra, Dynamic@rb, Dynamic@rc}
},
Frame -> All]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With