WebTextField.SoManyPropertiesAndEvents not working

I’m trying to highlight fields that need a users attention (maybe they put some bad data or are missing data).

I set out to use WebTextField.Indicator but the fields don’t seem to react to changes to that property. So then I tried simply changing the style of the background to something like this…

txt_password_login.Style.BackgroundColor = Color.FromString("&hFFFF00")

…that works great. However, I wanted to use the .GotFocus event of the field to restore the .BackgroundColor… but, that event doesn’t seem to fire.

I can manage to get the .TextChanged event to react, so I thought I’ll just use that to reset the background, which appears to work, but then after testing I see that as a user types into that field that an occasional backspacing happens and arbitrarily backspaces over one of the entered characters!

Is this known behavioral issues with WebTextField’s?

There is a bug that the GotFocus doesn’t fire if you click a WebTextField (TABbing in/out works). The bug is marked fixed so next Xojo release should have that fixed.

Haven’t seen that reported, can you create a sample application and/or video about this?

Here is the login window I’m working on now and it exhibits the issues. If you 'submit bad credentials the fields turn yellow - if you try backspacing over your bad password and start retyping it you’ll see how the input gets hijacked and backspaces over your ongoing entry.

I have one line in the .TextChanged event:

Me.Style.BackgroundColor = Color.FromString("&hFFFFFF")

…if I remove that line then the weird backspacing goes away too.

I guess that code is making round trips to the server and creating problems when you are typing, executing more times than expected.

I remember a bug report about TextChanged timing but I can’t find it.

From the docs:
https://documentation.xojo.com/api/user_interface/web/webtextcontrol.html#webtextcontrol-textChanged

The event fires only when the user has stopped typing for a short period.

For me, it looks like the TextChanged may be firing even if the user still writing.
typing

I’m trying to type “thisisatest” but I can’t.

Edit: testing locally this helps by not trying to change the BackgroundColor if it is already white:

If Me.Style.BackgroundColor <> Color.White Then
  Me.Style.BackgroundColor = Color.White
End If

TextChanged event is firing more times than I expected.

When rendering, some Xojo Web controls will set their properties whether they need it or not. I haven’t investigated this particular scenario, but this is the kind of thing I expect when the following is happening:

  1. User is typing
  2. Changed event fires
  3. BackgroundColor is set
  4. User is still typing…
  5. Control is re-rendered client-side, overwriting the current field value
  6. User is still typing…

If that’s the case, there will be lost information. As I said, haven’t checked this specifically but from what I’ve seen of the framework this seems likely. I wouldn’t change the BackgroundColor or, really, any other property from TextChanged.

1 Like

Thanks for all your assistance vetting this! I’m going to leave a reminder in the TextChanged event that says “don’t use!”.

I’d really like to find a simple solution to showing a user what field(s) aren’t good - and then removing the error as they ‘fix’ their work.

Since none of the Focus events work (in a way conducive to users inputting data) then I think I’ll just have to find some sort of work-around :frowning:

Well, you could do something like this in TextChanged:

if me.Text.Length > 0 then
  ExecuteJavaScript( "$('#" + me.ControlID + "_field').addClass('is-valid').removeClass('is-invalid');" )
else
  ExecuteJavaScript( "$('#" + me.ControlID + "_field').addClass('is-invalid').removeClass('is-valid');" )
end if

This wouldn’t trigger the re-render and would give validation information directly in the component using the built-in Bootstrap classes. I’d probably create a subclass of WebTextField and store state so that you only update it when needed.

An alternative would be to grab GraffitiSuite. I have a ton of extra functions, properties, and abilities built in to my components for things like this.

…it sure would make it more simple if the actual (documented) behavior of the controls worked :wink: I appreciate the scripting suggestions - look forward to getting onto the next task - I always get stuck going down the rabbit hole on these things.

I’m going to check out GraffitiSuite - if it solves problems and doesn’t have a large learning curve then Yes Please!

You could also do something like this, if you’re into JavaScript, using the TextField’s Shown event. This will work as-is if your control’s Shown event only fires once, but if it’s hidden and shown multiple times then it could bog things down a bit as you’ll be firing the event multiple times on each input.

Sub Shown() Handles Shown
  var exec() as String
  exec.Add( "var $this = $('#" + me.ControlID + "_field');" )
  exec.Add( "$this.on('input', function (e) {" )
  exec.Add( "  if (this.value.length == 0) {" )
  exec.Add( "    $(this).addClass('is-invalid').removeClass('is-valid');" )
  exec.Add( "  } else {" )
  exec.Add( "    $(this).addClass('is-valid').removeClass('is-invalid');" )
  exec.Add( "  }" )
  exec.Add( "});" )
  ExecuteJavaScript( String.FromArray( exec, "" ) )
End Sub

This has the added benefit of not relying on two-way communication to validate the field contents.

There’s always a learning curve with anything you do, but I do offer excellent support…not to pat myself on the back too hard.

1 Like

I can vouch to the quick support from Anthony.
Between Graffitisuite and @Tim_Parnell 's TP_Webkit (which fixes some of the missing functionality of the webtextfield like gotfocus and lostfocus among others) web 2.0 has been a lot more manageable.

3 Likes