Replacing a weekly email with perspective pages

I am also having issues getting the header to show the day of the week.

I made a binding, set to getDayOfWeek(now())
then I mapped a transform from Sunday - Saturday for 1-7
The object key would instead revert to a value, and instead of setting the object name which would be the header, it switched to a value, reading key:Friday with the binding

I don’t know how people an use this table component.

image

I am trying to get the headers to be:

Line and shift

Friday (dynamically the day of the week it is today)

Saturday (dynamically the next day of the week)

(other days of the week)

key_3 was moved to the bottom of the list against my wishes when I edited it
and now, the headers are out of sequence
I am not sure if there is a feature I don’t understand or if I am being plagued by a bug

having two main issues right now with the table

  1. If I set a binding on the object, the object transforms into a value, and my best workaround is to turn the headers off, then use style to bold the values I can place bindings on

  2. the order of the objects is switching around, and I don’t have a work around yet

list will maintain order they’re indexed… Dictionaries will not.

list = [thing,secondThing,thirdThing]
dict= {"thing":value,"secondThing":value2}

You are experiencing odd behavior from the table. Because you are using it oddly. It generally expects a data set. Then you can go in and name the columns and whatnot. When you do that. You have to use some methodology to define all the column names.

I can’t tell what you got going on. But, seems like you have to many bindings. Some of which are stepping on each other.

But, I promise the table has good performance. You can do a lot with it.

Show us your props.columns looks like


image

1 Like

If you’re going to be laying out a table like that. You’re going to have to write a script in the custom properties to build out your column names… that iterates through your dataset. Or maybe you can query it in such a way.

But, it seems you’re trying to do it the hard way…

Ill make a script showing you how to lay out your columns.

I would appreciate the help with a way to script the table.
Thanks @wking

in the above post, I showed the column section as requested for review

I got the order in the correct sequence for now.
I went through and added a number to end of each in the sequence I wanted them to appear.
I pressed save.
The dropdown retracted.
I expanded it, and they were in the right sequece.
I then removed the additional character to the key names.
Then I saved.
The dropdown retracted.
I expanded it.
They were in the right sequence again.

image

columns need to be an array of objects… I am working on a little quick script

1 Like

I see, I didn’t make them an array, so their order gets all mixed up probably. Not really sure.

I set a cell to editable by giving the editable property to one of the objects, then setting that true.

I edit the value on the page.
It reverts back to the value immediately.
Not sure what is required.

Ok here we go… There is a million different ways to do anything as you know… This isn’t the best or fastest or greatest. It just took ten mins tho lol and I’ve never done anything like this…

I think maybe you didn’t see that this column property “field” has to match an object on the props.data… so I start with a dataset like so…

image

This is handy because as you’ll see. IDK how you’re getting data. But you can supply the data and not have to worry about the order of the columns… that is what the columns property is for… They have to match tho…

So first I set up a custom prop to get the day of the week returned. I don’t want it to poll and keep rerunning my script… so I set it to now(0)… that way it only evaluates on page load…

So now i write a little script to get the names returned… in the correct order. i comment in the script to kind of tell you what i am doing… leave me some slack as im not the best programmer… I wouldn’t run this script in production

Def transform(self, value, quality, timestamp):
	"""
	Transform the incoming value and return a result.

	Arguments:
		self: A reference to the component this binding is configured on.
		value: The incoming value from the binding or the previous transform.
		quality: The quality code of the incoming value.
		timestamp: The timestamp of the incoming value as a java.util.Date
	"""
	#	return   
        ##for debug
	
	## if the bound value changes. Script re-runs and builds proper array of column objects
	## Sunday is day 1, Saturday is day 7... there might be a python way to do this cleaner.. 
	days = {'Sunday':1,
			'Monday':2,
			'Tuesday':3,
			'Wednesday':4,
			'Thursday':5,
			'Friday':6,
			'Saturday':7}
	## dictonaries aren't really meant to be used like this. But this is how you search for a value... we don't need to find first day. But this is how you could..
	##firstDay = days.keys()[days.values().index(value)]
	
	## lets make a little thing to give it a start date that is an int 6=friday. so we want the column that is today
	## to be the second column so this will make us a list like [5,6,7,1,2,3,4] that we will then use to find the day name later...
	
	daySort = [1,2,3,4,5,6,7]
	start = value
	
	tableOrder = []
	
	for i in daySort[int(start-1):]:
		tableOrder.append(i)
	for i in daySort[:int(start-1)]:
		tableOrder.append(i)
	
	## lets make a list of day names...Starting with today and finshing with yesterday...
	
	columnNames = []
	
	for i in tableOrder:
		columnNames.append(days.keys()[days.values().index(i)])
		
	
		
	## i went to props.columns added a new element and copied it here. this is our base element... im to lazy to change the true & falses to bool(0)
	
	true = bool(1)
	false = bool(0)
	
	base = { 
	  "field": "",
	  "visible": true,
	  "editable": false,
	  "render": "auto",
	  "justify": "auto",
	  "align": "center",
	  "resizable": true,
	  "sortable": true,
	  "sort": "none",
	  "viewPath": "",
	  "viewParams": {},
	  "boolean": "checkbox",
	  "number": "value",
	  "progressBar": {
	    "max": 100,
	    "min": 0,
	    "bar": {
	      "color": "",
	      "style": {
	        "classes": ""
	      }
	    },
	    "track": {
	      "color": "",
	      "style": {
	        "classes": ""
	      }
	    },
	    "value": {
	      "enabled": true,
	      "format": "0,0.##",
	      "justify": "center",
	      "style": {
	        "classes": ""
	      }
	    }
	  },
	  "toggleSwitch": {
	    "color": {
	      "selected": "",
	      "unselected": ""
	    }
	  },
	  "numberFormat": "0,0.##",
	  "dateFormat": "MM/DD/YYYY",
	  "width": "",
	  "strictWidth": false,
	  "header": {
	    "title": "",
	    "justify": "left",
	    "align": "center",
	    "style": {
	      "classes": ""
	    }
	  },
	  "footer": {
	    "title": "",
	    "justify": "left",
	    "align": "center",
	    "style": {"classes": ""}},"style": {"classes": ""}}
	
	
	##Ok lets build it out... we know we need to always start with "Line and Shift" so when we build this array of objects( [{obj},{obj}]) 
	##we will always start with this column in the 0th index of the list...
	
	firstCol = base
	firstCol['field'] = "Line"
	firstCol['header'] = {"title": "Line and Shift","justify": "left","align": "center","style": {"classes": ""}}
	
	
	columns = []
	
	columns.append(firstCol)
	
	## not that it is in the 0th spot.. lets build the rest of this list..
	
	for i in columnNames:
		firstCol = base.copy()
		firstCol['field'] = i
		firstCol['header'] = {"title": i,"justify": "left","align": "center","style": {"classes": ""}}
		columns.append(firstCol)
	
	return columns

So now we have a nice copy of this built columns… I bind props.columns to custom.columnNames…

and viola!

Lets test it by changing my day of the week expression value…So i disable the binding on it… just for a min… then i put in 4… and hey it works… I almost wasn’t expecting it tool lol…

testTable.json (5.4 KB)

here is the exported json of that view

why does now(0) run only on page load and now() runs more?

Is that detail depicted in the manual somewhere? I would like to read the section, and maybe bookmark.

it does. yes.

also it would run on page load because that property is set to NOT be persistent

I tend to add like a refresh button on tables. When i lay out complex tables like this… in that button i would make sure to call custom.columnNames.refreshbinding()

https://docs.inductiveautomation.com/display/DOC81/now

1 Like

I am still working on understanding the script.
I get that the why is to save time setting up the columns.
I am not sure why we set up the columns set though even if we can do it fast.

The other thing is that when I have my page open, and I tried to edit a cell, the cell reverts fast.
I will take a couple screenshots to show this.

image

changed it

image

hit enter
it reverted

image

There is a lot that goes into editing cells. You’ll have to show code…

I’ve never had a need for it… But I know you have to use the column and row indexs and call like a comit after editing method. But, idk where your data comes from?

If its a db table…you’re going to have a rough time of it… I am sure its working out there… But, i havent seen on the forums that working with a DB in a bi-directional approach.

I use… single row selection… then ill make a button visible if they select a row… if the selection == None the button is invisible…

The button is an edit button… That will call a pop up that is a form… populate the pop-up with the data passed in from the selection.data.[0]

much easier…

If your data isn’t coming from a db but tags or something maybe cell editing would be easier… but idk i don’t do that…

https://docs.inductiveautomation.com/display/DOC81/Perspective+-+Table

1 Like

1 Like

Thanks, I am going to get back to this on Monday.

I was reading that and didn’t know where it was configured. Thanks for anticipating.

I think I can follow that.

Thanks very much.

You did :slight_smile:, sorry I didn't mean to discourage you, just a little friendly advice. I was more referring to lots of posts where a question is asked and answered shortly after. It makes the thread unconcise, and may turn helpers away before they get to the bottom of the issue :slight_smile:

Anyway, sorry for not getting back to you sooner, busy weekend :sweat_smile:. It looks like @wking has done a lot of good leg work getting you on track :smiley:

It sounds like you've come across them, but I would recommend watching all of the Inductive University videos. There are also some Elective Studies to help with getting started (I believe more are in the works, so keep an eye out here). They won't help you with your specific issues, but may help with getting the correct mindset to solve the issues you have had.

Please don't be discouraged from using the forum and let us know if you need some more help with these specific issues :slight_smile:

6 Likes

Here is an example of the table I am trying to replace

maybe after I watch the elective studies videos linked to me, I will have a couple of good ideas

I think there will be a bunch of database work for me to do to get this to work.

@matthew.ayre
No worries, was just sick after I got the vaccine. I am not discouraged.

I programmed many machines and HMIs in many languages in the past.
None of that work was like this scada software though.

I watched every Inductive University video last December.
I will watch these elective studies videos.

1 Like