TextBox Masks and Formats

On-the-fly Masks and Formats for TextBoxes

Did you know you can manipulate/restrict what a user types into a TextBox on the fly? This is commonly referred to as “masking.” I’ve seen a lot of games on here that could use it, and it’s actually quite easy to do.

How it works:
All you have to do is listen for the Text property to change using GetPropertyChangedSignal("Text"), then check the Text property and change it accordingly.

For instance, if we want to only allow the user to type in positive integer values, we can restrict this by removing any non-digit characters from the input:

function PositiveIntegerMask(text)
	return text:gsub("%D+", "")
end

textBox:GetPropertyChangedSignal("Text"):Connect(function()
	-- Replace the text with the formatted text:
	textBox.Text = PositiveIntegerMask(textbox.Text)
end)

What’s cool is that the user will not be able to type any non-digit characters into the textbox! Well, kinda… It’s more like a nifty trick. Technically they are typing in non-digit characters, but we’re quickly masking the input directly afterward. To the user, it appears as if typing non-digit characters doesn’t even work.

Note: In the case of some masks, the masking might need a “fail” option, thus you need to return the text to the last valid input. An easy way to do this is to keep a variable of the last valid text (defaulting to whatever starts out in the Text property). If the mask returns nil, then simply use the last valid input as the text. If the mask works, replace the last valid input with the mask before setting the Text property again.

See the last phone number mask snippet for an example of the above note.

Here’s a couple other nifty masks that you might want to use. At the end of the day, it’s really just string patterns being utilized on the fly:


Examples

Only allow alphanumeric, spaces, and underscores:

function AlphanumericAndUnderscoreAndSpace(text)
	return text:gsub("[^%w%s_]+", "")
end

textBox:GetPropertyChangedSignal("Text"):Connect(function()
	textBox.Text = AlphanumericAndUnderscoreAndSpace(textBox.Text)
end)

Turn the input into upper-case:

function MakeUppercase(text)
	return text:upper()
end

textBox:GetPropertyChangedSignal("Text"):Connect(function()
	textBox.Text = MakeUppercase(textBox.Text)
end)

Only allow upper-case (note that this only allows upper-case. The last example simply turns it into upper-case):

function OnlyUppercase(text)
	return text:gsub("%U+", "")
end


textBox:GetPropertyChangedSignal("Text"):Connect(function()
	textBox.Text = OnlyUppercase(textBox.Text)
end)

Don’t allow spaces:

function NoSpaces(text)
	return text:gsub("%s+", "")
end

textBox:GetPropertyChangedSignal("Text"):Connect(function()
	textBox.Text = NoSpaces(textBox.Text)
end)

Format 7-digit and 10-digit phone numbers. Obviously not applicable for ROBLOX, but still cool. It’s a little more complicated though. Perhaps there’s an easier way to do this:

function PhoneNumberMask(text)
	if (text == "") then return "" end
	local t = text:gsub("%D+", "")
	local n = tonumber(t)
	if (not n) then return nil end
	n = tostring(n)
	if (#n > 10) then return nil end
	if (#n > 7) then
		return "(" .. n:sub(1, 3) .. ") " .. n:sub(4, 6) .. "-" .. n:sub(7)
	elseif (#n > 3) then
		return n:sub(1, 3) .. "-" .. n:sub(4)
	else
		return n
	end
end

local lastValidText = ""
textBox:GetPropertyChangedSignal("Text"):Connect(function()
	if (textBox.Text == lastValidText) then return end
	local text = PhoneNumberMask(textBox.Text)
	if (text) then
		lastValidText = text
		textBox.Text = text
	else
		textBox.Text = lastValidText
	end
end)

Note: Masking doesn’t mean that the input will be valid! It simply tries to restrict the user from most invalid stuff. A good trick is to use masking to make the text as well-formatted as possible on-the-fly, and then use validation when the input loses focus.

Another Note: You can string together multiple masks in order to get more complicated things done. Just make sure the masks don’t conflict with each other.


Disclaimer: Always validate input on the client and the server!

59 Likes

Change textBox.Changed to textBox:GetPropertyChangedSignal( "Text" ) for the sake of correctness :slight_smile:

6 Likes

Thanks, made the change

5 Likes

any way to use this to only have numbers in textbox’s? i found this: %x and i dont know how to use this