So I am trying to create a ordering system for someone and basically the user wants it so when you type part of the username in it will in gray say like the “suggested” username.
I was just wondering if anyone know how I could do this? I am unsure how to both make the end part gray and also make it so that it will auto fill in.
So Get the number of characters then minus it by the max you want then just choose any integer you want and put it in via script this is a example this would give you the idea on how to make it
I guess one method would be to make an identically scaled and identical properties TextLabel under/below (so 1 less ZIndex) the TextBox you type into, with a greyed out color. You can make it match the string the user inputs until a match is found.
…and to find user matches, you can compare the Levenshtein distance between all usernames or display names in the game, and use the lowest distance.
Here’s a function I found by “Badgerati” on GitHub for comparing the Levenshtein distance between two strings:
local function lev(str1, str2)
local len1 = string.len(str1)
local len2 = string.len(str2)
local matrix = {}
local cost = 0
if (len1 == 0) then
return len2
elseif (len2 == 0) then
return len1
elseif (str1 == str2) then
return 0
end
for i = 0, len1, 1 do
matrix[i] = {}
matrix[i][0] = i
end
for j = 0, len2, 1 do
matrix[0][j] = j
end
for i = 1, len1, 1 do
for j = 1, len2, 1 do
if (str1:byte(i) == str2:byte(j)) then
cost = 0
else
cost = 1
end
matrix[i][j] = math.min(matrix[i-1][j] + 1, matrix[i][j-1] + 1, matrix[i-1][j-1] + cost)
end
end
return matrix[len1][len2]
end
function LevenshteinDistance(String1: string, String2: string)
local Sub1 = String1:sub(2, -1)
local Sub2 = String2:sub(2, -1)
if String1 == '' then
return string.len(String2)
end
if String2 == '' then
return string.len(String1)
end
if String1:sub(0, 1) == String2:sub(0, 1) then
return LevenshteinDistance(Sub1, Sub2)
end
return 1 + math.min(LevenshteinDistance(Sub1, Sub2), LevenshteinDistance(String1, Sub2), LevenshteinDistance(Sub1, String2))
end
you can also do this with recursion, looks a lot cleaner this way
I won’t give you the solution directly, this is about learning.
You have your ‘H_us’ string that you can to iterate on all players in game.Players with the use of string.find, like the one underneath. (Assuming your usecase for this is iterating through game.Players? Ether way it works with all other usecases.)
Actually first I’d just make a collection table with all game.Players so it can find pop out the ones it didn’t match. And then basically have a variable acting as a count of how many string.find matches you found with the current string your player typed, adding +1 to it each time it finds a match in that specific iteration. If you get more than 2, just pick either one of the players.
So something like this (also use string.lowercase):
str = "BobTheGamerKid."
if string.find(str, "BobT") then
print("The match was found, suggested username: ".. str)
-- Then add + one to a value in case there are multiple matches.
else
print("Not found")
end
Here! I’ve kinda done this before! Put another text value behind, and run through all the players, with and use a string.find or something to check if it matches! If it does change it to that one!
I suppose I just nerded out about using Levenshtein a bitt too much lol.
This is definitely a simpler solution, but using Levenshtein would mean if the user mis-spelled the name slightly, perhaps by a developer-decided 2 characters or so, you could still autocomplete the correct user.
Just makes it a bit faster, but I’d definitely use string.find if you don’t wanna deal with this silly Lev business haha
EDIT: I mean faster in the sense of using the interface… string.find would definitely be actually literally faster. lol
local autofillist={"HelloPlayer","HelperBot","ExampleList"}
local autofills={}
local str=TextBox.Text
for _i,autofill in pairs(autofillist) do
local i,j=autofill:find(str)
if i then
table.insert(autofills,{['i']=i,['j']=j,['fill']=autofill})
end
end
TextBox.Text=str..autofills[1].fill:sub(autofills[1].j+1)
Maybe add a hotkey to it so when you press the hotkey, it puts the auto fills the text