How can I make an auto fill in text box like this
You could use string.find()
to filter through the playerlist.
This is similar to what you might need:
function autofill(text)
for i,v in pairs(game.Players:GetPlayers()) do
if string.find(v.Name, text) then
return v.Name
end
end
end
Make sure to use ipairs because it’s faster than pairs.
This is funny, because I’ve actually been learning about finding string similarity fairly recently. Here’s two functions:
local function LevenshteinDistance(original: string, target: string) : number
if original == target then return 0 end
if original:len() < target:len() then return self:LevenshteinDistance(target, original) end
if target:len() == 0 then return original:len() end -- original:len() >= target:len()
local previous_row = generateRange(target:len()+1)
for i, c1 in ipairs(original:split("")) do
local current_row = {i}
for j, c2 in ipairs(target:split("")) do
local insertions = previous_row[j+1] + 1 -- j+1 instead of j since previous_row and current_row are one character longer
local deletions = current_row[j] + 1 -- than target
local substitutions = previous_row[j] + if c1~=c2 then 1 else 0
insert(current_row, min(insertions, deletions, substitutions))
end
previous_row = current_row
end
return previous_row[#previous_row]
end
local function LevenshteinSimilarity(original: string, target: string) : number
return (max(original:len(), target:len())-self:LevenshteinDistance(original, target))/max(original:len(), target:len())
end
The LevenshtienDistance
function returns the amount of single-character edits that need to be made to the target string to transform it into the original string. The LevenshteinSimilarity
function will return a number from 0
to 1
that will be a percentage of how much the two strings match.
Given this, you can loop through each player and compare their name the the current entered-in text in the textbox.
Edit:
You can also use these two functions for getting Jaro Distance. This is most likely preffered over levenshtien distance.
local function JaroSimilarity(original: string, target: string): number
local original_len = original:len()
local target_len = target:len()
if (original_len == 0 and target_len == 0) or (original == target) then return 1 end
local match_distance = (math.floor(math.max(original_len, target_len) / 2)) - 1
local original_matches = table.create(original_len, false)
local target_matches = table.create(target_len, false)
local matches = 0
local transpositions = 0
local min = math.min
local max = math.max
for i = 1, original_len do
local _start = max(1, i - match_distance)
local _end = min(i + match_distance + 1, target_len)
for j = _start, _end do
if target_matches[j] then
continue end
if original:sub(i, i) ~= target:sub(j, j) then
continue end
original_matches[i] = true
target_matches[j] = true
matches += 1
break
end
end
if matches == 0 then
return 0
end
local k = 1
for i = 1, original_len do
if not original_matches[i] then continue end
while target_matches[k] == false do
k += 1
end
if original:sub(i, i) ~= target:sub(k, k) then
transpositions += 1
end
k += 1
end
local similarity = ((matches / original_len) + (matches / target_len) + ((matches - transpositions / 2) / matches)) / 3
return similarity
end
local function JaroDistance(original: string, target: string): number
return 1 - JaroSimilarity(original, target)
end
I’d be willing to bet that unless you’re working with tables with thousands of entries the difference is negligible but it’s still a good habit to get into, yes.
local textbox = script.Parent
function autofill(text)
local matches = {}
local players = game.Players:GetPlayers()
for i, player in ipairs(players) do
if string.match(player.Name, "^"..textbox.Text) then
table.insert(matches, string.match(player.Name, "^"..textbox.Text))
end
if i == #players then
if #matches == 1 then
return matches[1]
end
end
end
end
Slight extension with string.match() & only providing 1 match, if multiple players are found then nothing is returned.
Thank you, how can I add like the gray text behind? like this
Also I noticed that when I press Enter it doesn’t auto fill it
This happened because you had 12 matches as opposed to the expected 1 so nil was returned which you then attempted to assign to the “Text” property of the “InviteToParty” instance.
local textbox = script.Parent
function autofill(text)
local matches = {}
local players = game.Players:GetPlayers()
for i, player in ipairs(players) do
if string.match(player.Name, "^"..textbox.Text) then
table.insert(matches, string.match(player.Name, "^"..textbox.Text))
end
end
return matches[1]
end
This will return the first match found.
local textbox = script.Parent
function autofill(text)
local matches = {}
local players = game.Players:GetPlayers()
for i, player in ipairs(players) do
if string.match(player.Name, "^"..textbox.Text) then
table.insert(matches, string.match(player.Name, "^"..textbox.Text))
end
end
return table.concat(matches, ", ")
end
This will return all matches found concatenated into a single string separated by a comma followed by a whitespace.
Thank you, which method would be better to use? especially if a scenario appears where there’s two players with similar names e.g. “Player32132” and "Player3552