Modify text output based on input

I’m trying to make a text input that appends to the pre-existing text on the output. Instead, it clears the entirety of the text already on the output.
Additionally, when the player presses backspace, it’s meant to delete only the text written by the player on the output while still retaining accuracy to the input.
GIF
Fig. 1, “Hello World” being cleared upon player input.

InputHandler (localscript)

local UserInputService = game:GetService("UserInputService")
local Players = game:GetService("Players")
local player = Players.LocalPlayer
local outputText = script.Parent.Frame.TextLabel
local inputText = script.Parent.Frame.TextBox

-- For this demo, put some text into the output
outputText.Text = "Hello world!"

-- Function to print user input
local function printInput(input)
	outputText.Text = outputText.Text .. "\n" .. input
end

repeat
	wait()
until player.Character and player.Character:FindFirstChild("HumanoidRootPart")

inputText.FocusLost:Connect(function() -- Refocus after pressing enter
	inputText:CaptureFocus()
end)

inputText:GetPropertyChangedSignal("Text"):Connect(function()
	local inputTextString = inputText.Text
	outputText.Text = inputTextString
end)

UserInputService.InputBegan:Connect(function(input, isProcessed)
	if isProcessed then
		return
	end

	if input.KeyCode == Enum.KeyCode.Backspace then
		local inputTextString = inputText.Text
		local inputLength = #inputTextString

		if inputLength > 0 then
			local truncatedText = string.sub(inputTextString, 1, inputLength - 1)
			inputText.Text = truncatedText
		end
	end
end)

Any solutions are greatly appreciated. Thank you!

2 Likes
local UserInputService = game:GetService("UserInputService")
local Players = game:GetService("Players")
local player = Players.LocalPlayer
local outputText = script.Parent.Frame.TextLabel
local inputText = script.Parent.Frame.TextBox

-- For this demo, put some text into the output
outputText.Text = "Hello world!"

-- Function to print user input
local function printInput(input)
	outputText.Text = outputText.Text .. "\n" .. input
end

repeat
	wait()
until player.Character and player.Character:FindFirstChild("HumanoidRootPart")

inputText.FocusLost:Connect(function() -- Refocus after pressing enter
	inputText:CaptureFocus()
end)

inputText:GetPropertyChangedSignal("Text"):Connect(function()
	local inputTextString = inputText.Text
	if string.sub(outputText.Text, -1) == "\n" then -- Remove trailing newline
		outputText.Text = string.sub(outputText.Text, 1, -2)
	end
	outputText.Text = outputText.Text .. inputTextString
end)

UserInputService.InputBegan:Connect(function(input, isProcessed)
	if isProcessed then
		return
	end

	if input.KeyCode == Enum.KeyCode.Backspace then
		local inputTextString = inputText.Text
		local inputLength = #inputTextString

		if inputLength > 0 then
			local truncatedText = string.sub(inputTextString, 1, inputLength - 1)
			inputText.Text = truncatedText
			outputText.Text = string.sub(outputText.Text, 1, -inputLength-1) -- Remove deleted text from output
		end
	end
end)

It seems to be appending the output with multiple instances of the input. Additionally, backspace doesn’t work, rather it inverts what the player typed to the output as well.

local UserInputService = game:GetService("UserInputService")
local Players = game:GetService("Players")
local player = Players.LocalPlayer
local outputText = script.Parent.Frame.TextLabel
local inputText = script.Parent.Frame.TextBox

-- For this demo, put some text into the output
outputText.Text = "Hello world!"

-- Function to print user input
local function printInput(input)
	if input ~= "" then
		outputText.Text = outputText.Text .. "\n" .. input
	end
end

repeat
	wait()
until player.Character and player.Character:FindFirstChild("HumanoidRootPart")

inputText.FocusLost:Connect(function() -- Refocus after pressing enter
	inputText:CaptureFocus()
end)

inputText:GetPropertyChangedSignal("Text"):Connect(function()
	local inputTextString = inputText.Text
	if string.sub(outputText.Text, -1) == "\n" then -- Remove trailing newline
		outputText.Text = string.sub(outputText.Text, 1, -2)
	end
	if inputTextString ~= "" and not string.find(outputText.Text, inputTextString) then
		outputText.Text = outputText.Text .. "\n" .. inputTextString
	end
end)

UserInputService.InputBegan:Connect(function(input, isProcessed)
	if isProcessed then
		return
	end

	if input.KeyCode == Enum.KeyCode.Backspace then
		local inputTextString = inputText.Text
		local inputLength = #inputTextString

		if inputLength > 0 then
			local truncatedText = string.sub(inputTextString, 1, inputLength - 1)
			inputText.Text = truncatedText
			outputText.Text = string.sub(outputText.Text, 1, -inputLength-1) -- Remove deleted text from output
		end
	end
end)

Same issue as before, only now with newlines.

Bro

local UserInputService = game:GetService("UserInputService")
local Players = game:GetService("Players")
local player = Players.LocalPlayer
local outputText = script.Parent.Frame.TextLabel
local inputText = script.Parent.Frame.TextBox

-- For this demo, put some text into the output
outputText.Text = "Hello world!"

-- Function to print user input
local function printInput(input)
	if input ~= "" then
		outputText.Text = outputText.Text .. "\n" .. input
	end
end

repeat
	wait()
until player.Character and player.Character:FindFirstChild("HumanoidRootPart")

inputText.FocusLost:Connect(function() -- Refocus after pressing enter
	inputText:CaptureFocus()
end)

inputText:GetPropertyChangedSignal("Text"):Connect(function()
	local inputTextString = inputText.Text
	local outputTextString = outputText.Text

	-- Remove trailing newline from output text
	if string.sub(outputTextString, -1) == "\n" then
		outputTextString = string.sub(outputTextString, 1, -2)
	end

	-- Append input if not empty and not already present in output
	if inputTextString ~= "" and not string.find(outputTextString, inputTextString, 1, true) then
		outputText.Text = outputTextString .. "\n" .. inputTextString
	end
end)

UserInputService.InputBegan:Connect(function(input, isProcessed)
	if isProcessed then
		return
	end

	if input.KeyCode == Enum.KeyCode.Backspace then
		local inputTextString = inputText.Text
		local inputLength = #inputTextString

		if inputLength > 0 then
			local truncatedText = string.sub(inputTextString, 1, inputLength - 1)
			inputText.Text = truncatedText
			outputText.Text = string.sub(outputText.Text, 1, -inputLength-1) -- Remove deleted text from output
		end
	end
end)

Yet again the same issue as stated in my previous reply.

Please fully read the post.

To fix the issue with the input clearing the entirety of the text already on the output, you can modify the inputText:GetPropertyChangedSignal("Text") function to append the input to the pre-existing text on the output rather than replacing it.

mb to delete only the text written by the player on the output, you can modify the UserInputService.InputBegan function to remove the last instance of the input from the output when the player presses backspace.

try this :

local UserInputService = game:GetService("UserInputService")
local Players = game:GetService("Players")
local player = Players.LocalPlayer
local outputText = script.Parent.Frame.TextLabel
local inputText = script.Parent.Frame.TextBox

-- For this demo, put some text into the output
outputText.Text = "Hello world!"

-- Function to print user input
local function printInput(input)
	outputText.Text = outputText.Text .. "\n" .. input
end

repeat
	wait()
until player.Character and player.Character:FindFirstChild("HumanoidRootPart")

inputText.FocusLost:Connect(function() -- Refocus after pressing enter
	inputText:CaptureFocus()
end)

inputText:GetPropertyChangedSignal("Text"):Connect(function()
	local inputTextString = inputText.Text
	if inputTextString ~= "" then
		outputText.Text = outputText.Text .. "\n" .. inputTextString
	end
end)

UserInputService.InputBegan:Connect(function(input, isProcessed)
	if isProcessed then
		return
	end

	if input.KeyCode == Enum.KeyCode.Backspace then
		local inputTextString = inputText.Text
		local inputLength = #inputTextString

		if inputLength > 0 then
			local truncatedText = string.sub(inputTextString, 1, inputLength - 1)
			inputText.Text = truncatedText

			-- Remove last instance of input from output
			local outputTextString = outputText.Text
			local lastIndexOfInput = string.find(outputTextString, inputTextString, 1, true)
			if lastIndexOfInput then
				local outputTextLength = #outputTextString
				local outputTextBeforeInput = string.sub(outputTextString, 1, lastIndexOfInput - 2)
				local outputTextAfterInput = string.sub(outputTextString, lastIndexOfInput + inputLength, outputTextLength)
				outputText.Text = outputTextBeforeInput .. outputTextAfterInput
			end
		end
	end
end)

I hope this helps…

Same issue as before. In this case, where I typed “Hey”, and deleted the “y”, the only text on the output should be “Hello World!\nHe”, but instead it’s “Hello World!\nH\nHe\nHey\nHe”.

W explaining

local UserInputService = game:GetService("UserInputService")
local Players = game:GetService("Players")
local player = Players.LocalPlayer
local outputText = script.Parent.Frame.TextLabel
local inputText = script.Parent.Frame.TextBox

-- For this demo, put some text into the output
outputText.Text = "Hello world!"

-- Function to print user input
local function printInput(input)
	outputText.Text = outputText.Text .. "\n" .. input
end

local previousInputText = ""

repeat
	wait()
until player.Character and player.Character:FindFirstChild("HumanoidRootPart")

inputText.FocusLost:Connect(function() -- Refocus after pressing enter
	inputText:CaptureFocus()
end)

inputText:GetPropertyChangedSignal("Text"):Connect(function()
	local inputTextString = inputText.Text
	local inputTextLength = #inputTextString
	local previousInputTextLength = #previousInputText

	-- Find the difference between the new and old input text
	local difference = string.sub(inputTextString, previousInputTextLength + 1, inputTextLength)

	-- Append the difference to the output
	if difference ~= "" then
		outputText.Text = outputText.Text .. difference
	end

	previousInputText = inputTextString
end)

UserInputService.InputBegan:Connect(function(input, isProcessed)
	if isProcessed then
		return
	end

	if input.KeyCode == Enum.KeyCode.Backspace then
		local inputTextString = inputText.Text
		local inputLength = #inputTextString

		if inputLength > 0 then
			local truncatedText = string.sub(inputTextString, 1, inputLength - 1)
			inputText.Text = truncatedText

			-- Remove last instance of input from output
			local outputTextString = outputText.Text
			local lastIndexOfInput = string.find(outputTextString, inputTextString, 1, true)
			if lastIndexOfInput then
				local outputTextLength = #outputTextString
				local outputTextBeforeInput = string.sub(outputTextString, 1, lastIndexOfInput - 2)
				local outputTextAfterInput = string.sub(outputTextString, lastIndexOfInput + inputLength, outputTextLength)
				outputText.Text = outputTextBeforeInput .. outputTextAfterInput
			end
		end
	end
end)