Get mobile keyboard with html5 (DEF-3503)

Any updates on this? Was hoping WASM changed things for mobile but it still doesn’t work.

I tried the on screen keyboard but unfortunately it’s been our most voiced concerns from QA, since we require user input a couple of times and game is mostly played on mobile browsers.

I tried adding a Custom Virtual Keyboard that inserts user input to a hidden field in index.html then polling that field every 0 seconds via html5.run() but it’s buggy and simply isn’t a replacement for the native mobile keyboard.

Kindly assist.

We don’t have an update for this I’m afraid. I did however play around with this a bit during the weekend. On HTML5 it’s possible to at run-time create an input field and give that focus to bring up the native virtual keyboard. You can then poll for input in the text field and forward the input to your Lua code.

CODE: https://github.com/britzl/defold-input/blob/master/in/keyboard.lua
DEMO: https://britzl.github.io/Defold-Input/ (click on the Keyboard button to test)

Note: I wasn’t able to get the native keyboard to show when the canvas was fullscreen though. Not sure if that is possible to be honest.

3 Likes

@britzl Thanks for the code. It works great on Android but doesn’t seem to respond on iOS most of the time. Any ideas?

I only tested on Android. The keyboard.lua modul polls the keyboard very frequently to make it feel responsive, but I’m thinking that it does so too frequently:

Let me give it a try on an iOS device.

1 Like

Jeez. Safari prevents DOM elements from programmatic focus (which is what I do to show the keyboard) when the focus() call happens outside of an input event (which is the case when doing it from Defold). I’m currently stuck unless someone has a clever idea…

1 Like

Something like,

in the Asset Portal would be mighty nice. :wink:

1 Like

I’m guessing using the virtual keyboard in HTML5 on iOS is still a brick wall?

I think so. I haven’t googled for a solution since this was discussed last.

1 Like

Hi, I know this is an old thread, but I thought Id share something I managed to get working. The code shown below does a few different things, so I will explain after the code.

	self.platform_info = sys.get_sys_info()
-- The system OS name: "Darwin", "Linux", "Windows", "HTML5", "Android" or "iPhone OS"
if self.platform_info.system_name == "HTML5" then
	local html_data = [[
	var html = "<div style='position:absolute;left:0px;top:0px;z-index:-1;'>";
	html = html + "<input id='hiddenInput' type='text' name='hiddenInput' /></div>";
	document.getElementById("canvas-container").insertAdjacentHTML("afterend", html);
]]
html5.run(html_data)
		
local js_data = [[
	var script = document.createElement("script");
	var funcscr = "var inputcurr = '';\n";
	funcscr = funcscr + "var inputdata = {};\n";
	funcscr = funcscr + "var winsize = [window.width,window.height];\n";

	funcscr = funcscr + "window.addEventListener('resize', windowSizeChanged);\n";
	funcscr = funcscr + "window.addEventListener('load', function() {\n";
	funcscr = funcscr + "  winsize = [window.width,window.height];\n";
	funcscr = funcscr + "})\n";

	funcscr = funcscr + "function windowSizeChanged() {\n";
	funcscr = funcscr + "  window.resizeTo(winsize[0],winsize[1]);\n";
	funcscr = funcscr + "}\n";
	
	funcscr = funcscr + "const inputtext = document.querySelector('#hiddenInput');\n";
	funcscr = funcscr + "inputtext.addEventListener('keydown', (e) => {\n";
	funcscr = funcscr + "  var key = e.key;\n";
	funcscr = funcscr + "});\n";

	funcscr = funcscr + "function clearFocus(){ \n ";
	funcscr = funcscr + "  inputcurr = 'none';\n";
	funcscr = funcscr + "  var canvas = document.getElementById('canvas');\n";
	funcscr = funcscr + "  canvas.focus();\n";
	funcscr = funcscr + "}\n";
	
	funcscr = funcscr + "function clearInput(id, curr){ \n ";
	funcscr = funcscr + "  inputdata[id] = '';\n";
	funcscr = funcscr + "  inputcurr = id;\n";
	funcscr = funcscr + "  document.getElementById('hiddenInput').value = curr;\n";
	funcscr = funcscr + "  var input = document.getElementById('hiddenInput');\n";
	funcscr = funcscr + "  input.focus();\n";
	funcscr = funcscr + "}\n";
	
	funcscr = funcscr + "function getInputText(id){ \n ";
	funcscr = funcscr + "  var input = document.getElementById('hiddenInput');\n";
	funcscr = funcscr + "  input.focus();\n";
	funcscr = funcscr + "  inputdata[id] = input.value;\n";
	funcscr = funcscr + "  return inputdata[id];\n";
	funcscr = funcscr + "}\n";

	script.innerHTML = funcscr;
	document.body.appendChild(script);
	]]

	html5.run(js_data)
end

There are two sections of code. The first adds some html to the canvas container to provide a hidden input text box as others have described above.

The second set of code injects a resize handler, keydown handler and a number of functions to be used in the Defold script.

Within your script, when you want to start getting the text from the input box use:

html5.run( "clearInput('"..myid.."', 'starting text')" )

This will insert “starting text” into the hidden text box and create a mapped response using myid defold variable - note the myid must be some valid string. Whenever you want to use the text input of that input you can use:

local value = html5.run("getInputText('"..myid.."')")

The clearFocus function is used to hide away the keyboard.
One additional thing you may need to to is to disable the “resize” handler in the default js-web template. This is because if you have the keyboard popup the game will attempt to resize, which is not really useful in these cases. Heres where I commented out the handler in my js-web template:

	resize_game_canvas();
//window.addEventListener('resize', resize_game_canvas, false);    <----------------------
window.addEventListener('orientationchange', resize_game_canvas, false);
window.addEventListener('focus', resize_game_canvas, false);
</script>

Hope this helps. Im glad to have a working solution for android. Will need to test on IOS.

7 Likes

Ok. It looks like the above has issues running on Safari. I am investigating and hope to have a fix soon.

2 Likes

Has there been any update on this or is a virtual in-game keyboard still the way to get input text from mobile browsers?

A virtual in game keyboard is unfortunately still the way to go.