What I’m trying to do:
I have a target_value that’s a number. I also have to textboxes next to each other.
I want to tie the two textboxes together so that typing in one of them causes the other one to automatically fill with the difference between the target_value and what was typed.
For example, the target_value is 10. I type 3 into the left textbox, and then the right textbox is populated with a 7 on lost_focus.
What I’ve tried and what’s not working:
I read the documentation on the two-way data-binding:
you can create 12 Labels and bind each of their text properties to 1 * self.item['N'] (for the first one) through 12 * self.item['N'] (for the last one).
However, I was a bit confused since when I had a go I was met with SyntaxError: Can't assign to data binding expression for right.text, but writeback is enabled for this data binding...
Code Sample:
I’ve named the left and left textbox self.left and self.right
If I just bind text to self.left.text then it properly just mirrors what I type instead of type, but is there a way to do the math in the binding similar to how it was done in the documentation when it said:
Enabling the Write back option causes the form to write the value back into the source of the data binding.
For example, if you bind self.textbox_1.text to self.something, then:
when self.something changes it does self.textbox_1.text = self.something
if Write back is enabled, when self.textbox_1.text changes it does self.something = self.textbox_1.text
In your case you can’t write the value back to an expression, otherwise it would try to do this: self.target - self.left.text = self.right.text
Even without the Write back option, I wouldn’t use data binding in this case. Data binding is great for simple cases, but for cases where you need more control over what happens when, it’s better to use the change event as suggested by @stefaan1o.
self.left.text is a text, so self.target - self.left.text tries to subtract a text from self.target.
Maybe you need to convert it to a number to do the subtraction and convert it back to string when you assign it: self.right.text = str(self.target - float(self.left.text))
You said you tried to follow the code in the documentation. Can you provide a code snippet of how you tried to accomplish this for your use case?
Also, you shouldn’t need to convert anything to int or float. The TextBox component has a type property that you can set to number, which will prevent users from entering anything other than a number. If you do that, then the type of the self.textbox_1.text will be int (or float if a decimal is entered).
With “write back” turned on, when you type into self.right, or change it in other ways, “write back” is instructing Anvil to use the following assignment statement: self.target - self.left.text = whatever value you typed into self.right
Of course, what’s on the left of the = sign does not name any actual variable, and as a result, the Anvil-generated assignment statement is not valid Python syntax.
If you want Anvil to not attempt that assignment statement, you can simply turn writeback off for self.right.