Trouble with 'if' statement, button event

For some reason the code will not run past line 37.

First step: assign values to variables.
image

Second step: assign those values to labels to make sure I'm getting them:
image

Third step: check for missing data:
image

All that works fine.

Next, check for a value of zero:

And this is where the code seems to stop, it won't execute this line or the else: later on.
EDIT: It does execute the else: statement.

For some reason item_id does not equal 0.

I have commented out the other IF statements, no change. No errors show on the side of the code window, no errors in the gateway log.

Any ideas on what would cause code to just stop without any indications? The zero (0, not O) value is a zero, triple checked that.

Thanks

Can you just post your entire code? With Python's sensitivity to whitespace, there's a whole class of errors we can't rule out. Also, we're taking your word for the line numbers.

Are you sure the type lines up with what you expect? A string "0" would not equal 0 the int/float.

	item_id = self.view.params.p_itemID
	
	desc = self.parent.parent.getChild("TabContainer").getChild("flx_General").getChild("coord_Left").getChild("txtA_Description").props.text
	notes = self.parent.parent.getChild("TabContainer").getChild("flx_General").getChild("coord_Left").getChild("txtA_Notes").props.text
	classification = self.parent.parent.getChild("TabContainer").getChild("flx_General").getChild("coord_Left").getChild("cbo_Classification").props.value
	category = self.parent.parent.getChild("TabContainer").getChild("flx_General").getChild("coord_Left").getChild("cbo_Category").props.value
	stocked = self.parent.parent.getChild("TabContainer").getChild("flx_General").getChild("coord_Left").getChild("chk_Stocked").props.selected
	review = self.parent.parent.getChild("TabContainer").getChild("flx_General").getChild("coord_Left").getChild("chk_Review").props.selected
	shortDesc = self.parent.parent.getChild("TabContainer").getChild("flx_General").getChild("coord_Left").getChild("txt_ShortDescription").props.text
	
	self.parent.parent.getChild("TabContainer").getChild("flx_General").getChild("coord_Right").getChild("Label_0").props.text = "Item ID: " + item_id
	self.parent.parent.getChild("TabContainer").getChild("flx_General").getChild("coord_Right").getChild("Label_1").props.text = "Category: " + str(category)
	self.parent.parent.getChild("TabContainer").getChild("flx_General").getChild("coord_Right").getChild("Label_2").props.text = "Class: " + str(classification)
	self.parent.parent.getChild("TabContainer").getChild("flx_General").getChild("coord_Right").getChild("Label_3").props.text = "Desc: " + desc
	self.parent.parent.getChild("TabContainer").getChild("flx_General").getChild("coord_Right").getChild("Label_4").props.text = "Short: " + shortDesc
	self.parent.parent.getChild("TabContainer").getChild("flx_General").getChild("coord_Right").getChild("Label_5").props.text = "Stocked: " + str(stocked)
	
#	msg = "step one"
#	self.parent.parent.getChild("TabContainer").getChild("flx_General").getChild("coord_Right").getChild("Label").props.text = msg
	
	if category == 0:
		param2 = {"p_Msg":"Please select a Category."}
		system.perspective.openPopup("popup102", "Page/Message_PU", param2)
		return
	if classification == 0:
		param2 = {"p_Msg":"Please select a Class."}
		system.perspective.openPopup("popup102", "Page/Message_PU", param2)
		return
	if len(desc) == 0:
		param2 = {"p_Msg":"Please enter a description."}
		system.perspective.openPopup("popup102", "Page/Message_PU", param2)
		return
	if len(shortDesc) == 0:
		param2 = {"p_Msg":"Please enter a short description."}
		system.perspective.openPopup("popup102", "Page/Message_PU", param2)
		return
		
	if item_id == 0:
		param2 = {"p_Msg":"IF."}
		system.perspective.openPopup("popup102", "Page/Message_PU", param2)
#		#Add New Item
#		msg = "step two"
#		self.parent.parent.getChild("TabContainer").getChild("flx_General").getChild("coord_Right").getChild("Label").props.text = msg
#		if self.view.custom.currentTabIndex == 0:
#			# General Tab
#			param1 = {"p_Category":category, "p_Classification":classification, "p_Description":desc, "p_ShortDesc":shortDesc, "p_Stock":stocked, "p_Review":review, "p_Notes":notes}
#			namedQuery = "INV/Item_NewInsert_SP"
#			returnNQ = system.dataset.toPyDataSet(system.db.runNamedQuery(namedQuery, param1))
#			self.parent.parent.getChild("flx_Title").getChild("lbl_ItemID2").props.text = returnNQ[0][0]
#			self.parent.parent.getChild("flx_Title").getChild("lbl_Desc").props.text = shortDesc
#			self.parent.parent.getChild("TabContainer").getChild("flx_General").getChild("coord_Left").getChild("num_Catalog").props.value = returnNQ[0][1]
##			self.parent.parent.getChild("TabContainer").props.currentTabIndex = 1
#		elif self.view.custom.currentTabIndex == 1:
#			# Stocking data
#			item_id2 = self.view.params.p_itemID
#			low = self.parent.parent.getChild("TabContainer").getChild("flx_Stock").getChild("coord_Left").getChild("num_LowStock").props.value
#			high = self.parent.parent.getChild("TabContainer").getChild("flx_Stock").getChild("coord_Left").getChild("num_HighStock").props.value
#			current = self.parent.parent.getChild("TabContainer").getChild("flx_Stock").getChild("coord_Left").getChild("num_CurrentStock").props.value
#			safety = self.parent.parent.getChild("TabContainer").getChild("flx_Stock").getChild("coord_Left").getChild("num_SafetyStock").props.value
#			over = self.parent.parent.getChild("TabContainer").getChild("flx_Stock").getChild("coord_Left").getChild("num_OverStock").props.value
#			bin = self.parent.parent.getChild("TabContainer").getChild("flx_Stock").getChild("coord_Left").getChild("cbo_Bin").props.value
#			param2 = {"p_ItemID":item_id2, "p_BinID":bin, "p_Low":low, "p_High":high, "p_Current":current, "p_Safety":safety, "p_Over":over}
#			namedQuery2 = "INV/Bin_Item_Insert_SP"
#			system.db.runNamedQuery(namedQuery2, param2)
#			message = "inv_Bin_Tbl_Refresh"
#			system.perspective.sendMessage(message)
##			self.parent.parent.getChild("TabContainer").props.currentTabIndex = 3
#		elif self.view.custom.currentTabIndex == 3:
#			# Vendor data
#			item_id2 = self.view.params.p_itemID
#			vendor = self.parent.parent.getChild("TabContainer").getChild("flx_Vendors").getChild("coord_Left").getChild("cbo_Vendor").props.value
#			container = self.parent.parent.getChild("TabContainer").getChild("flx_Vendors").getChild("coord_Left").getChild("cbo_Container").props.value
#			partNum = self.parent.parent.getChild("TabContainer").getChild("flx_Vendors").getChild("coord_Left").getChild("txt_PartNumber").props.text
#			price = self.parent.parent.getChild("TabContainer").getChild("flx_Vendors").getChild("coord_Left").getChild("num_Price").props.value
#			lead = self.parent.parent.getChild("TabContainer").getChild("flx_Vendors").getChild("coord_Left").getChild("num_LeadTime").props.value
#			param3 = {"p_ItemID":item_id2, "p_Vendor":vendor, "p_PartNum":partNum, "p_Price":price, "p_ContainerID":container, "p_Lead":lead}
#			namedQuery3 = "INV/Item_Supplier_Insert_SP"
#			system.db.runNamedQuery(namedQuery3)
#			message = "inv_Pn_Tbl_Refresh"
#			system.perspective.sendMessage(message)
	else:
		param2 = {"p_Msg":"ELSE."}
		system.perspective.openPopup("popup102", "Page/Message_PU", param2)
#		# Edit/Update existing Item
##		desc = self.parent.parent.getChild("TabContainer").getChild("flx_General").getChild("coord_Left").getChild("txtA_Description").props.text
##		notes = self.parent.parent.getChild("TabContainer").getChild("flx_General").getChild("coord_Left").getChild("txtA_Notes").props.text
##		classification = self.parent.parent.getChild("TabContainer").getChild("flx_General").getChild("coord_Left").getChild("cbo_Classification").props.value
##		category = self.parent.parent.getChild("TabContainer").getChild("flx_General").getChild("coord_Left").getChild("cbo_Category").props.value
##		stocked = self.parent.parent.getChild("TabContainer").getChild("flx_General").getChild("coord_Left").getChild("chk_Stocked").props.selected
##		review = self.parent.parent.getChild("TabContainer").getChild("flx_General").getChild("coord_Left").getChild("chk_Review").props.selected
#		disc = self.parent.parent.getChild("TabContainer").getChild("flx_General").getChild("coord_Left").getChild("chk_Obsolete").props.selected
#		replaced_by = self.parent.parent.getChild("TabContainer").getChild("flx_General").getChild("coord_Left").getChild("num_ReplacedBy").props.value
##		shortDesc = self.parent.parent.getChild("TabContainer").getChild("flx_General").getChild("coord_Left").getChild("txt_ShortDescription").props.text
#		query1 = "INV/Item_Details_Update"
#		params = {"p_ItemID":item_id, "p_Class":classification, "p_Category":category, "p_Desc":desc, "p_Short":shortDesc, "p_Stocked":stocked, "p_Review":review, "p_Disc":disc, "p_Notes":notes, "p_ReplacedBy":replaced_by}
#		system.db.runNamedQuery(query1, params)
#		message = "inv_tbl_Refresh"
#		system.perspective.sendMessage(message)

The View Param:
image

Changed second line to this:

item_id = int(self.view.params.p_itemID)

And it works. I don't get it. If I type an "O" in for the view param, I get errors on the components bound to it, but the code somehow interprets it as a zero string "0".

I don't know what's going on with the parameter problem but I offer the following to reduce your code and the brittleness of your project.

  1. On the view create a custom property object with structure something like this:
dataLeft
    desc :
    notes :
    classification :
    category :
    stocked :
    review :
    shortDesc :
  1. Bind each of the respective coord_Left components to the custom object and make the bindings bi-directional.
  2. Now the first block of seven lines of your code becomes,
dataLeft = self.view.custom.dataLeft
  1. Create a second custom property object, dataRight.
  2. Generate the coord_Right components using:
dataRight = {}
dataRight["Item ID"] = item_id
dataRight["Category"] = str(dataLeft["category"])
dataRight["Class"] = str(dataLeft["classification"])
dataRight["Desc"] = desc[quote="mdemaris, post:3, topic:76892"] # What's going on here?
dataRight["Short"] = dataLeft["shortDesc"]
dataRight["Stocked"] = str(dataLeft["stocked"])
self.view.custom.dataRight = dataRight
  1. Bind all the coord_Right components to the custom parameter object members.

I suspect that most of this routine could be eliminated by disabling the button that calls this event until all the relevant fields have been filled out. Show a red * or icon beside each field until it's got a legitimate value and provide a tooltip on the icon to indicate what the problem is.

1 Like

How would I show a red symbol or icon?

Why would I want to make these bindings bi-directional?

  • Add a label or an icon component after each form field.
  • Add an expression binding to the icon's visibility property.
  • Have the expression check that there is enough information in the field.
  • Then you could create an expression binding on the button's enabled property to check that all the fields are filled out. Something like,
!{../txtA_DescIcon.visible} && 
!{../txtA_ClassIcon.visible} && 
!{etc., etc.}

If none of the error icons are visible then your form is ready and the submit button can be enabled.

So that they update when you edit your view.
If the bindings are not bidirectional then they are read-only as far as the bound component is concerned.

Found something interesting on this parameter issue:
in the designer, if I use an expression binding and say if param = 0, numeric zero, it comes back true. But, when I launch a perspective session, I have to use if (toint(param) = 0) for it to come back true.

When you enter a property value in the text field in the designer, it automatically checks to see if it looks numeric (i.e. is just 0) and sets it into the property as a number.

In the actual browser session, that's not happening automatically, so if you're e.g. setting a custom property to the output of a text field, you're getting a string "0" instead of the number 0.

1 Like

You can simplify that to
if(!toInt(param), true, false)

You can simplify that to !toInt(param) :slight_smile:

1 Like

Time for bed!

This checks to see if it is an integer, no?

toInt(param) will return true for any non-zero value of param.
!toInt(param) will return false for any non-zero value of param.

That is - expressions must always return a value.
If you're in a context where the output of an expression is required to be a boolean, type coercion will be performed. A non-zero integer -> true; anything else -> false.

If view.param.p1 (for instance) is equal to numeric 0, then several things happen, if it is larger than 0, other things happen. The value for p1 is passed from a calling event on another view.

In each script so far, I have had to use toint() or int(), depending on the type of script/language used, except in the Designer.

I don't think I have any code that changes p1 to 0, only code that changes it to a larger value.

What initially sets view.param.p1?

Call from a table row click:

system.perspective.openPopup(popId, popView1, params={"p_itemID":self.props.selection.data[0].ItemID, "pu_id":popId, "p_newItem":0}, showCloseIcon = True, resizable = True)

Where the data is pulled from a named query, from SQL SVR, where this ItemID is an auto-increment primary key integer. BUT, the zero is not from the query... but is hard coded as you see for the p_newItem.

I agree with Transistor, I need a nap! Three edits to make this reply sensible...