How to edit in a script a table component props.columns

Hi folks i’m new ignition perspective user (last vers).
I need to write a script that edit a table component property (props.columns[0] that is an array of object with sub property) with a script and create a certain number of it, something like: props.columns[5].
I’m able to write this creating a json object in the script with the first level of object inside of the props.columns array but i can’t insert everything over it:
props.columns[1].field but (first level) not props.columns[1].field.header[1].title.
In my script:
[{‘field’:True, ???}]

I gave this a try with an example using the default Table component, how does your full JSON look when trying to assign a header title?

The property paths for those two props are:

self.props.columns[n].field
self.props.columns[n].header.title

And here is my “custom” JSON object that can be plugged into an array for n columns:

json_columns = []
fields = ['city','country','population']
for n in range(len(fields)):
	col_object = {"field" : fields[n],
		          "header" : {"title" : "title_" + str(n)} 
	}
	json_columns.append(col_object)
self.props.columns = json_columns

Sorry if this test example is too basic to be helpful, but this method created 3 basic column objects for me.

End Result :

Thanks, i’ve tested with my var and it’s ok.
If i want to translate the field title when the session.props.locale what can i do?
Normally i use a binding expression like ‘translate(<mytextVar)’ but here the props is created in a script?

Hi, with your help i’ve found an interest way to solve the problem building all the structure in 2 steps, so if someone in future need it this the code.

def myJsonObj():
res=
res.apoend({ “align”:“center”,
“boolean”:“checkbox”,
“dateFormat”:“MM/DD/YYYY”,
“editable”:False,
“field”:"",
“footer”:{“justify”:“left”,“style”:{“classes”:""},“align”:“center”,“title”:""},
“header”:{“justify”:“left”,“style”:{“classes”:""},“align”:“center”,“title”:""},
“justify”:“auto”,
“number”:“value”,
“numberFormat”:“0,0.##”,
“progressBar”:{“bar”:{“color”:"",“style”:{“classes”:""}},
“min”:0,
“max”:100,
“track”:{“color”:"",“style”:{“classes”:""}},
“value”:{“justify”:“center”,“format”:“0,0.##”,“style”:{“classes”:""},“enabled”:True}},
“render”:“auto”,
“resizable”:True,
“sort”:“none”,
“sortable”:True,
“strictWidth”:False,
“style”:{“classes”:""},
“toggleSwitch”:{“color”:{“unselected”:"",“selected”:""}},
“viewPath”:"",
“viewParams”:{},
“visible”:True,
“width”:""})
return res

NOTE- I’ve appended the dictionary not a listo of dictionary. In first case i can loop and modify a singol element of the dictionary using the notation: res[idx].[‘my_props’] = <my_value> in the second case not!!!

Calling this function in your loop, it`s possible to create the array needed and then pass them
to the table props.columns.

PS this exact json structure is what i`ve found passing the props.columns[1] (manually created) to a textArea object.

1 Like

Excellent! I agree that this is a better approach, if you are customizing the columns, might as well initialize the entire object. After that you can easily assign new values via the property paths.

Regarding the locale, I am not sure. There are some system.util functions that work with locales, but I’m not well versed in them.

I’ve tried the system.util.translate() but not run at all at runtime, i’m investigating why.
At the moment I’ve solve using an expression binding like:

translate(props.columns[idx].field)

on props.columns[idx].header.title but this is a static solution implemented manually. I’d like to write the translation dinamically in the script.

Thx for your support.

i had no problem translating the header inside a dict declaration

image

In my test i’ve not specified your second parametr that is supposed to be session.props.locale and mabe is this the point. I’ll try asap, thx.

Why are you creating an empty list then appending one thing in it, just to return it immediately afterward ?
I’ve seen this several times, when it seems to me you could just be returning a one element list directly:

def foo():
  return [
    {
      'a': 1,
      'b': 2,
    }
  ]

Is there a reason I’m missing to add those steps ?

you can do that yes.
Its (in my oppinion) easier to read if its first a variable tho, and easier to add something to it or add in a log in between ect.
But python has many ways to even put loops and ifs in oneliners, which you could immediatly put in the return.

I hear the make var -> return var point that allows logging before returning. I do that myself sometimes.
I don’t agree that it’s more readable though, or that it makes adding things easier.

But what’s the point of making an empty list just to append one thing ? You’re not gonna log an empty list.

This looks like an example and probably will append more lines through a loop
Which i think he says a bit lower.

Hi, the empty list is a sort of declaration that i use in my implemented style and then is what permit to me to call the method ‘.append()’ on it.
Then i use ‘.append()’ because in my test this is the right way to modify any other element separatly after have create it.
The point of this method is to create an exact copy of the table ‘props.column[idx]’ to manage this component when the number of column can change at runtime.
In general this is a good way to see how to manage any array props of a component when you need this prop can be managed dinamically at runtime!

I think I just don’t get what you’re doing and what you’re trying to solve.

The way I see it, you want to populate the columns prop dynamically.
But I have no idea based on what you want to populate it, or why you’re making an exact copy of it with loops to then modify it…

@victordcq: I guess I just don’t like seeing empty variables declared…
I’ll nest comprehensions 12 levels deep just to avoid having to append things to an empty list ! :nauseated_face:

I think I have answered you and if I have not been clear I’m sorry but I don’t understand how I can “help you understand what you are asking me”.
I’m not a philosopher but an engineer: I solve problems, I don’t create them … if I can!

I guess the main thing is: What are your columns bound to ? How are they computed ? Do you have a list of the columns you need, or is it just based on the table’s data prop ? In this case, are you making columns just to translate the title, or is there something else ?

Why not? i guess its not really needed in python but in other languages this is often needed to give it a type.

I studied code at 42 and they made us declare all our variables at the top of their scope, but we weren’t allowed to initialize them there (except for statics or const, because, well… )

so we had functions that looked like

void foo(){
  int a;
  int b;
  char *s;
  whatever_t foo_bar;

  a = 0;
  b = 0;
  s = malloc(size(char) * x + 1);
  foo_bar = bar_foo;
  ...
}

Considering we had to limit functions to 25 lines maximum… Didn’t take me long to start hating empty initializations.

Haha jup had to do that too

protip: int a,b; a = b = 0;

i too hate max lines… but i did not blame it on the variable declaration xd