Previously, changing the Text property of a TextBox while the user was focused in it would move the cursor to the end of the text.
As of a recent update, upon changing the Text, the cursor position remains in the same relative position.
For example, consider you had a script where pressing Tab auto-completed text based on suggestions. Previously, pressing Tab to accept a suggestion would move your cursor to the end. Now, pressing Tab keeps your cursor in the same place, so you must manually move your cursor to the end.
I would generally consider this desired behavior now that we have the CursorPosition property, however, this change has broken the auto-complete feature in existing systems of mine, notably Cmdr. I think that it would be better to preserve the old behavior in this case for compatibility reasons.
I’ve attached a place file demonstrating a case where this behavior change makes a difference:
Hi @evaera - thank you for the detailed bug report! We recently (7/15) deployed improvements to the text positioning pipeline. It’s possible that this may have inadvertently caused the cursor positioning issue described here. I created a ticket to investigate this.
Hi, not sure if I should reply here again but I am still having this issue with my script (I can’t open a new bug report I think due to how long I spent on the dev forums)
I’m having a similar issue when you press tab to auto-complete the text it keeps the cursor in the same position.
Unfortunately not. This is an ongoing issue as part of TextChatService too, I’ve been writing a client-side replacement for the default TextChatService to try address many of the issues ROBLOX Engineers have failed to address, and this is on the pile of issues that need to be addressed.
The lack of fixes for what are pretty core systems for UI/UX Design and Programming is heartbreaking, especially for a platform that has otherwise made the profession extremely accessible.
EDIT: The best way I found to get around this is to brute-force this. This is the function I’m using to convert the string in bytes in my own implementation, however I do not have any knowledge of if it will work with Unicode symbols longer than one byte (as mentioned by TextBox.CursorPosition).
-- [GetStringInBytes] - Gets the length of str in bytes.
--[[
Gets the length of str in bytes.<br>
<strong>str</strong> : The string to get the length of in bytes.
]]
function GetStringInBytes(str : string) : number
local byteArray = {}
for i = 1, #str do
table.insert(byteArray, string.byte(str, i))
end
return #byteArray
end
I’m using this function to determine where to position the TextBox.CursorPosition. As this function isn’t accounting for empty spaces, I add 1 afterwards.
-- Create a binding for each autocomplete result being clicked, which alters the contents, focus and cursor position of the TextField (TextBox).
PrimaryAlias.OnAutocompleteClickedConnection = PrimaryAlias.AutocompleteResult.MouseButton1Click:Connect(function()
if (PrimaryAlias.fullOrPartialMatch == false) then return end -- Prevent results that aren't matched from doing anything.
TextField:CaptureFocus()
TextField.Text = PrimaryAlias.alias:lower().." "
TextField.CursorPosition = GetStringInBytes(TextField.Text) + 1
Click:Play()
end)
And the type definition for PrimaryAlias, for reference:
type ChatCommandInfo = {
alias : string,
command : TextChatCommand,
AutocompleteResult : TextButton,
fullOrPartialMatch : boolean,
OnAutocompleteClickedConnection : RBXScriptConnection
}
I forgot to edit this all again, so I’m making a new post to revive the topic and bring attention to an eloquent solution provided by @Tomi1231 which has since been put to use in internal builds of WinryChat 1.6!
They found the function utf8.len(...) in the utf8 library to count characters. I put it in place of a slightly older method for a UTF8 function I was using (see below), but it should just be used on it’s own.
-- [GetUTF8StringLength] - Gets the length of the string via UTF8 Codepoints.
--[[
Gets the length of str in bytes.<br>
<strong>str</strong> : The string to get the length of in bytes.
]]
function GetUTF8StringLength(str : string) : number
print(utf8.len(str))
return utf8.len(str)
end
So the best solution is UTF8 string library. Not what I was doing. By miiiiles.