Hello everyone! I’m making a textbox where you enter a color. I need to restrict the text the user enters so that it doesn’t break anything down the line. It turned out harder than I expected, but I got it to work in the end.
The behavior is exactly as I want. Now it just needs to be shortened and simplified, if possible of course. Half of this was written by myself, a quarter with ChatGPT, and a quarter with Gemini. I’m just glad it works
local ColorTextBox = script.Parent
local previous = ""
local textChangedConnection = nil
-- -- -- -- --
local function clamp(n)
n = tonumber(n)
if not n then return 0 end
return math.clamp(n, 0, 255)
end
local function matchRGBformat(str)
-- Single consolidated pattern: matches 1-3 groups of 1-3 digits separated by comma+optional space
-- Allows partial entry: "255" or "255," or "255, 128" or "255, 128," or "255, 128, 64"
return str:match("^%d%d?%d?$") -- Just first number
or str:match("^%d%d?%d?,%s?$") -- First number + comma
or str:match("^%d%d?%d?,%s?%d%d?%d?$") -- Two numbers
or str:match("^%d%d?%d?,%s?%d%d?%d?,%s?$") -- Two numbers + comma
or str:match("^%d%d?%d?,%s?%d%d?%d?,%s?%d%d?%d?$") -- Complete RGB
end
local function isPartialHex(text)
if text:sub(1,1) ~= "#" then return false end
local hex = text:sub(2)
-- More specific: hex must be only valid hex chars and 1-6 characters long
return hex:match("^[A-Fa-f0-9]+$") and #hex >= 1 and #hex <= 6
end
-- -- -- -- --
ColorTextBox.Focused:Connect(function()
ColorTextBox.Name = ColorTextBox.Text
previous = ColorTextBox.Text
if textChangedConnection then
textChangedConnection:Disconnect()
end
textChangedConnection = ColorTextBox:GetPropertyChangedSignal("Text"):Connect(function()
local text = ColorTextBox.Text
if text == "" then
previous = ""
return
end
local first = text:sub(1,1)
if first:match("%d") then
-- More efficient: only remove invalid characters once
text = text:gsub("[^%d,%s]", "")
if matchRGBformat(text) then
previous = text
end
elseif first == "#" then
-- Keep only one # at the start, remove everything else invalid
local hex = text:sub(2):gsub("[^A-Fa-f0-9]", "")
text = "#" .. hex
if isPartialHex(text) then
previous = text
end
end
ColorTextBox.Text = previous
end)
end)
ColorTextBox.FocusLost:Connect(function(EnterPressed)
if textChangedConnection then
textChangedConnection:Disconnect()
textChangedConnection = nil
end
if EnterPressed then
local text = ColorTextBox.Text
local first = text:sub(1,1)
if first == "#" then
repeat
text = text .. "0"
until #text == 7
ColorTextBox.Text = text
else
local components = {}
for match in string.gmatch(text, "%d+") do -- Simpler pattern
table.insert(components, clamp(tonumber(match)))
end
-- Ensure we have exactly 3 components, pad with 0 if needed
while #components < 3 do
table.insert(components, 0)
end
ColorTextBox.Text = table.concat(components, ", ")
end
else
ColorTextBox.Text = ColorTextBox.Name
end
ColorTextBox.Name = "TextBox"
end)
I apologize if I insult you, but I can tell this was done with an AI chatbot because the comments are way too detailed in their punctuation and capitalization, and it replaced all my (spaces) with %s (whitespaces)
I had to manually keep changing them every time back to spaces.
Also the line breaks (if that’s what they’re called) they’re in the same style, no line breaks after if’s or else’s.
I will however look into the changes and see if I agree with them, and add them accordingly. Thank you, but I’ll wait for an actual experienced human to review my code before I move on, sorry…
When you write code I would use OPUS 4.5 thinking if you’re going to vibe code.
Also, the AI didn’t make all of those changes, I put the code I wrote into the model to add comments. You wanted an experienced developer to review your code, I did that. I just simply don’t have time to comment my code after I write it. There are tools that speed the process up.
As for your regex, decimal regex is messy by nature, I’m not sure if you can clean it up. You may be able to write a regex combining your or logic, but at what point is that over complicated the implementation. I think the code you had was fine and isn’t worth modifying in accordance to your original question.
Now, there were tons of memory leak and objects not being cleaned up. I fixed those issues.
Good to know :D
Are you sure the AI didn’t mess anything up when it added those comments?
Also, what were the memory leaks? I’d love to know about them, to look out for the in the future.
Thanks!
Edit: it appears to be a textChangedConnection. I think I agree with your change there, you’re disconnecting the function if the focus gets lost. good change
It doesn’t say textChangedConnection = nil here. Is that intentional?
Edit: I looked over everything else, and it’s exactly what I was hoping for, simplification. Thank you!
I initially dismissed your message because I thought it was made by AI, and I’ve already ran it by an AI and it’s given me the final result seen in my initial post.
Could you test out trying to enter a hex value? It doesn’t work for me.
I think the issue is the match, since after inputting the #, it matches "", which returns nil.