Specify a local dynamic grid

I would like to dynamically update individual parts of the Grid in different ways. Consider the following toy example: I have two lines: you need to update one after another (a, b, c), since these characters depend on different triggers; the second line depends on one trigger (show), which allows you to display / hide some data.

Now I know that I can wrap the entire Grid structure in Dynamic and even indicate which characters to track, so 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}] 

Mathematica graphics

Although for certain reasons, I would like to have a locally specified Dynamic that applies only to the second row of the Grid .

For those who are wondering if this is an illogical situation, just imagine the following: show used in any of a , b or c , and this I DO NOT want to update when show changes, their changes depend on other triggers. Why not remove show from the characters of the first line? Imagine, I can’t, because show present in a function that is used in a , b or c , and this function cannot be easily accessed.

Of course, moving the first If argument to Dynamic will not help here, because the Grid itself or any of its cells will not become dynamic:

 Grid[{ { Dynamic@a , Dynamic@b , Dynamic@c }, If[ Dynamic@show , Prepend[test, "test:"], {}] }, Frame -> All] 

In addition, wrapping a string in Dynamic makes the specified string invalid because it no longer has a head List :

 Grid[{ { Dynamic@a , Dynamic@b , Dynamic@c }, Dynamic@If [show, Prepend[test, "test:"], {}] }, Frame -> All] 

Dynamic by line does not work either because show not updating dynamically:

 Grid[{ { Dynamic@a , Dynamic@b , Dynamic@c }, Dynamic /@ If[show, Prepend[test, "test:"], {}] }, Frame -> All] 

Also, wrapping Dynamic[If[...]] around list members works, but now I have to evaluate If 3 times instead of 1.

 Grid[{ { Dynamic@a , Dynamic@b , Dynamic@c }, Dynamic[If[show, #, ""]] & /@ Prepend[test, "test:"] }, Frame -> All] 

I would like to know if there is any solution to overcome this specific problem by applying the Dynamic shell locally in a string.

+7
source share
2 answers

Here is a solution using an experimental ValueFunction

 show = True; test = {0, 0}; Checkbox[Dynamic[show]] 

Now create 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 create a Grid and now you can use Dynamic in each row, and not around the entire grid, what you need:

 Grid[{ { Dynamic@a , Dynamic@b , Dynamic@c }, { Dynamic@row } }, Frame -> All ] 

enter image description here

ps. I just read the post here telefunkenvf14, which mentions this package and this function that I did not know about, and when I saw this function, I remembered this question and I thought that this function could be used to solve this problem.

ps. I need to work harder on properly setting the grid line ....

update (1)

I cannot figure out how to concatenate the final row by columns in the grid. Which is strange, since it has a List header, but it will not go through all the columns. It will only be in the first cell. Tried Sequence, SpanFromLeft etc., but no luck. Maybe someone can understand this part.

Here is my current version:

 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 to be feasible. I don’t understand what the problem is now ...

update (2)

As a temporary solution, I share the second line with the force in front of the hand. This allowed me to do what I want. Not sure if this meets the OP specs or not (I assume it isn't), 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] 

enter image description here

+3
source

This is actually a comment on the @Nasser solution and suggested a fix to avoid manually splitting the second line, but due to space limitations in the comment area, I am sending it as an answer. We will be happy to remove it as soon as Nasser confirms that it is working, and included it in his answer.

The key to the solution is in the Possible Issues Item section of the documentation:

If the item is not the topmost item in the child of the function that supports the item, this will not work.

I use this to change @Nasser solution as follows. First, I need to change the definition of row so that for both show values, the length of the row same.

 Needs["Experimental`"]; row = {"", "", ""}; updateRow[x_, v_] := row = If[v, Prepend[test, "test:"], {"", "", ""}]; Experimental`ValueFunction[show] = updateRow; 

The second change is necessary to wrap each element of Dynamic@row with Item :

 Grid[{{ Dynamic@a , Dynamic@b , Dynamic@c }, {Item[ Dynamic@row [[1]]], Item[ Dynamic@row [[2]]], Item[ Dynamic@row [[3]]]}}, Frame -> All] 

Edit: Item wrapper is not needed; it works just as well without it:

  Grid[{{ Dynamic@a , Dynamic@b , Dynamic@c }, { Dynamic@row [[1]], Dynamic@row [[2]], Dynamic@row [[3]]}}, Frame -> All] 
+1
source

All Articles