TextBox Cursor Position when Text Changed Behavior has Changed

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:

TextBoxBehaviorChangeRepro.rbxl (20.8 KB)

3 Likes

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.

6 Likes

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.

1 Like

Bumping this.

Has this been fixed?

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
}
1 Like