Hi
I’m using a mask ###,### on a textfield - but when enter digits the result is only the left 3 digits - other digits are ignored. I didn’t expect this behaviour…
Simple code is:
[code]Sub Open() Handles Open
me.validationmask = “###,###”
End Sub
Sub TextChange() Handles TextChange
Dim v As Double = Val(Me.value)
TextField2.value = Str(v)
End Sub
[/code]
that is to be expected… you type in 123456 and the mask makes it 123,456
the “,” is not a numeric digit so VAL stops at that point… same as if it were 123X456
Good advice about cdbl here, but I just want to point out that it’s not odd that Val has stopped on the non-numeric character. This behavior is documented. You should use cdbl for user input values! (also documented)
[quote]It is important to note that Val’ does not take separator characters into consideration. For example:
Dim d As Double
d = Val(“10,000.95”) // The “,” causes the string to stop being converted[/quote]
Good advice is to read the manual!
So I see that CDbl is deprecated - use string.toDouble instead.
But now how do I get a textField to show data input with thousands separators, and with +/- with user input?
All the options seem to format the numbers in the wrong direction - left to right rather than right to left - so you end up with strange looking numbers (unless you are German) like 123,66
I’ve tried the manual but it doesn’t seem to give me what I want.
Oh, my mistake. However, setting the Mask value as you have is working as expected here, where the comma is being added automatically. I’ve just tested and confirmed this in API 1 and 2019r1.1. I would hope it’s not related to API 2.0
Sub Open() Handles Open
me.validationmask = "###,###"
End Sub
Sub TextChange() Handles TextChange
Dim v As Double = Me.value.ToDouble
TextField2.value = Str(v)
End Sub
Gives me output that looks like this (in 2019r.2.1) for entry of 5 8’s.
888,88
Ah, yes, that’s because it’s simple string validation. It’s working as expected. I think I get what you’re trying to do now.
The general idea of what you’ll want to do is write a method that takes the text field’s value, uses cdbl to get a double, use Format to get the correctly formatted string you’re looking for, then compare the string value to the original text field string value. Check that the value is different before setting text field value. If you always set the value you’ll get an event overflow.
That’ll take numbers and format them, but I’m thinking there might be issues with text entry carat positioning, so you may need to experiment with changing SelStart so the field functions as expected while typing. I may be able to try my hand at an implementation later today.
Technically, Cdbl is deprecated, so assuming you’re working in 2019R2 or later you might want to use its direct replacement String.ToDouble or you could use Double.FromString. I would go with Double.FromString since you could manage the locale of the conversion.
Then use Double.ToString where you again control the locale to update your second text field.
[quote=464658:@James Pitchford]Sub TextChange() Handles TextChange
me.value = Me.value.ToDouble.ToString(locale.Current, ",")
End Sub
[/quote]
What is it that you’re trying to do here? I’m confused because it looks like you’re trying to format the text input, which is what TextField.Mask does.
He’s trying to format the input so that the separator is how a person would write it. The string based Mask function is working as expected, but doesn’t parse numbers on the fly the way a human might.
I was simply trying to recreate a calculator style input of numbers, formatted with 000’s commas, +/- and decimal places, allowing for any type of number to be input by the user. I was somewhat surprised that it wasn’t a standard format for textEdit.
TextField mask unfortunately seems to work on text input, rather than numeric input.
E.g. entering -1001000.876 should should show -1,001,000.876 and build correctly from right to left.
I create a string property called StringFormat in a subclassed textfield. StringFormat contains the mask I wish to apply on the LostFocus event. I’ve added StringFormat to control’s inspector.
Sub LostFocus() Handles LostFocus
// apply the format, if any, when we leave the field
If StringFormat <> "" and me.Text.IsNotEmpty then
me.Format = StringFormat
else
me.Format = ""
End If
RaiseEvent LostFocus
End Sub
I was asking because I noticed the subject of his TextChanged event changed from updating the value in a new textfield to the current one.
Maybe something along the lines of this:
Try
Dim Input As String = Me.Value
Dim arrInput() As String = Input.Split( "." )
If arrInput.LastRowIndex > 1 Then
//You have an error
Return
End If
Dim d As Double = Double.FromString( arrInput( 0 ), Locale.Current )
Dim s As String = d.ToString( Locale.Current, "," )
arrInput( 0 ) = s
Dim output As String = Join( arrInput, "." )
If output <> Input Then
Me.Value = output
End If
Catch e As InvalidArgumentException
//Handle nonnumerics or other input problems here
End Try
You’d have to control for the user entering commas and decimals in the wrong place, but this would format appropriately entered numbers. I’m sure this could be optimized and you could use RegEx if you have MBS’s plugins but I’m not sure it would be faster with Xojo’s built in RegEx engine.