I have a template with a text input field that I'm using in a template repeater.
I want to display a confirmation dialog box, warning the user that they've "cleared" the text in the box before writing to the tag that it's bound to.
The text property is unidirectionally bound to a (indirect) tag. I have a custom "tag" property that is bidirectionally bound to that same (indirect) tag.
The idea is to check the text property before writing the tag, like so:
if event.propertyName == 'text':
if event.newValue == '' and event.oldValue:
if system.gui.confirm('<html>Removing name from list will revert any tanks with this name to the default value', 'Warning', True):
event.source.tag = event.source.text
else:
event.source.tag = event.source.text
However, when the window with the template repeater starts up I immediately get one popup for each instance in the repeater.
What's the correct way to do this so that the popup only appears when the text is changed by the user?
Bind the input field's text to the custom property, not indirectly to the same tag. Then, in your change event, compare the new text value to the custom property. When those are different, it is a user entry.
Ok, so I put the script in the wrong place...
I also forgot to mention that the indirect tag is actually bound to a root container custom prop first. Not sure if that matters.
So tag
<-> nameC
<-> Text Field.tag
and -> Text Field.tag
Instead I should use tag
<-> nameC
<-> Text Field.tag
-> Text Field.text
?
That's the way I have it and I still get a popup right when the window opens.
Show your code. (I suspect you are still checking against oldValue. Don't do that.)
Root Container custom prop (nameC
)

Text Field custom prop (tag
):

Text Field text prop:
def Table_Row.Text Field.text.propertyChange()
if event.propertyName == 'text':
if event.newValue == '' and event.oldValue:
if system.gui.confirm('<html>Removing commodity from list will revert any bins with this commondity to the default value.', 'Warning', True):
event.source.tag = event.source.text
else:
event.source.tag = event.source.text
Why not check old value? I added that in there in case the oldValue
was null or '', then we can ignore the change.
edit: it's my else isn't it? The else is catching it at startup and setting it to none and then back to ''
Even without checking against the oldValue I still get the same behavior.
if event.propertyName == 'text':
if event.newValue == '':
if system.gui.confirm('<html>Removing commodity from list will revert any bins with this commondity to the default value.', 'Warning', True):
event.source.tag = event.source.text
else:
event.source.tag = event.source.text
The binding flow from a tag updates your .tag
prop before the .text
prop's unidirectional binding delivers there. So, when coming from the tag, the text prop's new value is equal to the .tag
prop's value. Only when .text
comes from user input can it be different from .tag
.
No other check is necessary or sufficient.. Your code doesn't even perform this minimum comparison.
As stated in my first suggestion:
Emphasis added.
Ok, so I need to also compare against the tag's value?
if event.propertyName == 'text':
if event.newValue == '' and not ( event.newValue == event.source.tag ):
if system.gui.confirm('<html>Removing commodity from list will revert any bins with this commondity to the default value.', 'Warning', True):
event.source.tag = event.source.text
else:
event.source.tag = event.source.text
no change
Something like this:
if event.propertyName == 'text':
if event.newValue != event.source.tag:
if not event.newValue:
if system.gui.confirm('<html>Removing commodity from list will revert any bins with this commondity to the default value.', 'Warning', True):
event.source.tag = event.source.text
else:
event.source.tag = event.source.text
Also, since tags often startup with a null, you may need an extra custom property that coalesces nulls to empty strings. Then bind .text
to that intermediate custom prop and compare to it instead of .tag
.
Ok, so the popup doesn't open right away, but now when I change the text from ''
to "test" (and press enter) the tag doesn't get updated
if event.propertyName == 'text':
if event.newValue != event.source.tag and event.source.tag:
if event.newValue == '':
if system.gui.confirm('<html>Removing commodity from list will revert any bins with this commondity to the default value.', 'Warning', True):
event.source.tag = event.source.text
else:
event.source.tag = event.source.text
Why would I need to coalesce to an empty string? event.source.tag
results in false if it's empty string or null
It's pretty similar.
I changed not event.newValue
to event.newValue == ''
and added and event.source.tag
I've used your code directly, and added the coalesce as well.
if event.propertyName == 'text':
if event.newValue != event.source.tag:
if not event.newValue :
if system.gui.confirm('<html>Removing commodity from list will revert any bins with this commondity to the default value.', 'Warning', True):
event.source.tag = event.source.text
else:
event.source.tag = event.source.text
Text Field.text
is now bound to Text Field.tagNN
which is an expression binding to nameC
coalesce({Table_Row.nameC},'')
Same result
edit: need to compare against the coalesced value, not the tag
if event.propertyName == 'text':
if event.newValue != event.source.tagNN:
if not event.newValue :
if system.gui.confirm('<html>Removing commodity from list will revert any bins with this commondity to the default value.', 'Warning', True):
event.source.tag = event.source.text
else:
event.source.text = event.source.tag
else:
event.source.tag = event.source.text
this works now