Perspective Enter Key Action

Hi all,

I’ve got a button that sends a message to a handler on the root container. The results of the message handler is a query that searches for a part and sets a custom property, to which a table is bound.

This works fine.

I used this same message for pressing the Enter key. But, I do not get any query results. So, I bound a label to a custom property, and set this property via the root message handler, and it works both with the button click and Enter key events.

Any ideas why this might happen?

Thanks,

mike

On what component did you configure the keyboard event?

(Share more details, or export an example view.)

Right, I did forget that.
The keyboard event is configured on a parent flex container of the button.

Root → flex → tab container→ flex → flex with keyboard event → coord → button that sends message.

Button and key event code?

Edit - specific key event code:

	if event.key =='Enter':
		message = "inv_parts_query"
		payload = {}
		system.perspective.sendMessage(message, payload)

Button event code:

	message = "inv_parts_query"
	payload = {}
	system.perspective.sendMessage(message, payload)

And the message handler:

	self.custom.lbl_msg = "message test"
	catalog = self.custom.stock_data_filter.catalog
	master = self.custom.stock_data_filter.master
	partNum = self.custom.stock_data_filter.partNum
	desc = self.custom.stock_data_filter.desc
	category = self.custom.stock_data_filter.category
	area = self.custom.stock_data_filter.area
	classification = self.custom.stock_data_filter.classification
	bin = self.custom.stock_data_filter.bin
	stock = self.custom.stock_data_filter.stock_level
	stocked = self.custom.stock_data_filter.active
	
	if stock != 3:
		if area != 0:
			namedQuery = "INV/CurrentLessThan"
			params = {"p_Stock":stock, "p_Area":area}
			system.perspective.print(params)
			self.custom.stock_tbl_data = system.db.runNamedQuery(namedQuery,params)
		else:
			# if no area is selected...
			self.custom.lbl_msg = "You must select an Area first."
			self.custom.lbl_vis = True
	else:
		params = {"p_Bin":bin, "p_Class":classification, "p_Category":category, "p_Desc":desc, 
			"p_PartNum":partNum, "p_Master":master, "p_Cat":catalog, "p_Area":area, "p_Stocked":stocked}
		namedQuery = "INV/Item_Details_Filter"
		self.custom.stock_tbl_data = system.db.runNamedQuery(namedQuery,params)	

I don’t see any key event code…

Edited for clarification. Thanks.

What is the key event handler attached to? Are you sure it’s firing? I would put a system.perspective.print() in there to verify it. If it’s firing but the message handler isn’t hearing the message, then perhaps it’s a scope issue. You aren’t providing one, and the default is page.

In the OP:

This label confirmed that the message handler fired with the key event and button event.

This is where the key event is attached:

The message handler is on the root container.

So the key event is attached to the button? That will only work when the button has focus. That will be true of whatever you attach it to. I would say to invoke self.focus() on the button in an onStartup event handler, but that is not guaranteed to work, since other parts of the view may steal focus when they get rendered. Perspective doesn’t have an onLoad handler that would fire after everything in the view is done rendering, something I have requested:

Ok, I tested a few more things, and it appears that there are two (2) components out of 8 or 9 that do not work with the query when I press the Enter key.

The two components are numeric text fields. I seem to recall asking this question a long time ago, now that I have come back to this project and have narrowed it down again...

No, the key event is held on a flex container, two levels up from the button.

Edit: So the issue is the numeric text fields. I will go back and look for my old thread on this and see what the end result was.

If the numeric text fields have focus when you press Enter, then they could be preventing the flex that has the key event handler from hearing it.

You could add the same handler to the inputs themselves, or you might want to try a Session Event Keystroke handler. I’ve never used it, but I would guess it isn’t tied to the focus of any particular page element.

Ah, I think I see what is happening. After entering a value, I must move the focus to another component first, then press Enter.

It will not work if I click somewhere in the container, i.e. not on an interactive component, but some other component must get the focus for the numeric field to, I assume, accept the input value and "transmit" to the bound property...

Perhaps this could be resolved in an update?

Not sure I follow completely, but that sounds like this issue:

1 Like

Right. So, moving the focus to another component before sending the message is what needs to happen. I put a short sleep statement in, but I seem to remember someone more knowledgeable stating that is not good practice. All I need is a short delay so the input value gets captured before running the rest of the script.

Yeah, sleep is never a good idea. I always try to avoid using a delayed reaction, but sometimes it seems necessary, in which case I use a Timer:

from threading import Timer

def doSomething(self):
	...

Timer(0.5, doSomething, [self]).start()

I tried this, and I think the Timer does not actually wait to call the function. Seems like it happens right away.

def runAction(self, event):
	from threading import Timer

	def udf_partsQuery():
		message = "inv_parts_query"
		payload = {}
		system.perspective.sendMessage(message, payload)
		
	if event.key == 'Enter':
		self.getSibling("btn_Search").focus()
		
		Timer(0.1, udf_partsQuery()).start()
	#	Timer(0.1, udf_partsQuery, [self]).start()

Edit: Never mind, don't include the parens on the function!

Edit 2: No dice on the query running. I added a line to change the background color of a button just below the message call, and I got nothing to happen.

Did you try forcing page scope and ensure that the handler is listening to page scope?

def runAction(self, event):
	from threading import Timer

	def udf_partsQuery():
		message = "inv_parts_query"
		payload = {}
		system.perspective.sendMessage(messageType=message, payload=payload, scope='page')
		self.parent.parent.parent.getChild("flx_InputArea").custom.bg01 = '#FFFF00'
		
		pu_id = 'partsQuery'
		view = 'Page/misc/Message_PU'
		msg = e
		params = {'pu_id': pu_id, 'msg':msg}
		system.perspective.openPopup(pu_id, view, params)
	
		
	if event.key == 'Enter':
		self.getSibling("btn_Search").focus()
		
		Timer(1.0, udf_partsQuery).start()

So, this code is running on a numeric text field, I don't think I made that clear. The button gets the focus, good. IF I move the backgound color line to the top of the function, the color will change, but not in it's current position in the code.
I changed the message handler to display a message, as I did earlier, and it is not firing. For some reason, the sendMessage is not working in this context.

We're going in circles. Boil it down to a stand-alone reproducer and share it.