This topic is locked
[SOLVED]

Virtual Keyboard Issue: Works in Tabs, Not in Pop-Ups

6/7/2024 5:41:26 AM
PHPRunner General questions
Q
qbin author

Sure, here is the optimized text for your forum post:

Hello,

I'm trying to implement a virtual keyboard on the add page. When I open the add page in a separate tab, it works perfectly. However, if I open it in a pop-up, it doesn't work at all—no errors, it just doesn't function.

I've tried placing the JavaScript code directly in the event handlers for both the add and list pages. I've also attempted including the script from multiple external files as well as a single external file. Despite these efforts, the virtual keyboard still doesn't work in the pop-up, though it works flawlessly when not using a pop-up.

Am I missing something?

Thanks
img alt
!

Here is the code for the numerical keyboard.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>POS Virtual Keyboard</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/simple-keyboard@latest/build/css/index.css">;
<style>
#keyboard {
display: none;
}
#keyboard.active {
display: block;
}
</style>
</head>
<body>
<div>
<input type="text" id="inputField1" placeholder="Tap to type..." />
<input type="text" id="inputField2" placeholder="Tap to type..." />
<button id="showKeyboardButton">Keyboard</button>
<div id="keyboard" class="simple-keyboard"></div>
</div>

<script src="https://cdn.jsdelivr.net/npm/simple-keyboard@latest/build/index.js"></script>;
<script>
document.addEventListener("DOMContentLoaded", function() {
const Keyboard = window.SimpleKeyboard.default;
let currentInputField = null;

const keyboard = new Keyboard({
onChange: input => onChange(input),
onKeyPress: button => onKeyPress(button),
layout: {
default: [
"7 8 9",
"4 5 6",
"1 2 3",
"0 . {tab} {enter} {bksp}"
]
},
display: {
"{bksp}": "⌫",
"{enter}": "⏎",
"{tab}": "⇥"
}
});

function onChange(input) {
if (currentInputField) {
currentInputField.value = input;
moveCursorToEnd(currentInputField);
}
}

function onKeyPress(button) {
if (button === "{bksp}") handleBackspace();
if (button === "{enter}") handleEnter();
if (button === "{tab}") handleTab();
}

function handleBackspace() {
const input = keyboard.getInput();
keyboard.setInput(input.substring(0, input.length - 1));
if (currentInputField) {
currentInputField.value = input.substring(0, input.length - 1);
moveCursorToEnd(currentInputField);
}
}

function handleEnter() {
if (currentInputField) {
const form = currentInputField.closest('form');
if (form) {
form.submit(); // Submit the form if the input is inside a form
} else {
const inputs = document.querySelectorAll('input[type="text"]');
const index = Array.prototype.indexOf.call(inputs, currentInputField);
if (index > -1 && index < inputs.length - 1) {
inputs[index + 1].focus();
setTimeout(() => moveCursorToEnd(inputs[index + 1]), 0);
}
}
}
}

function handleTab() {
if (currentInputField) {
const inputs = document.querySelectorAll('input[type="text"]');
const index = Array.prototype.indexOf.call(inputs, currentInputField);
if (index > -1 && index < inputs.length - 1) {
const nextInputField = inputs[index + 1];
currentInputField = null; // Temporarily clear currentInputField to prevent re-triggering the tab event
nextInputField.focus();
setTimeout(() => {
keyboard.setInput(""); // Clear keyboard input to prevent adding a tab character
moveCursorToEnd(nextInputField);
currentInputField = nextInputField; // Reset currentInputField
}, 0);
}
}
}

function moveCursorToEnd(input) {
input.focus();
if (input.setSelectionRange) {
const length = input.value.length;
input.setSelectionRange(length, length);
} else if (input.createTextRange) {
const range = input.createTextRange();
range.collapse(false);
range.select();
}
}

document.querySelectorAll('input[type="text"]').forEach(input => {
input.addEventListener("focus", function() {
if (currentInputField !== input) {
currentInputField = input;
keyboard.setInput(input.value);
document.getElementById("keyboard").classList.add("active");
}
});
});

document.getElementById("showKeyboardButton").addEventListener("click", function() {
const keyboardElement = document.getElementById("keyboard");
keyboardElement.classList.toggle("active");
if (keyboardElement.classList.contains("active")) {
if (currentInputField) {
keyboard.setInput(currentInputField.value);
}
}
});

document.addEventListener("click", function(event) {
if (!event.target.closest("#keyboard") && !event.target.closest('input[type="text"]') && !event.target.closest('#showKeyboardButton')) {
document.getElementById("keyboard").classList.remove("active");
}
});
});
</script>
</body>
</html>
Sergey Kornilov admin 6/7/2024

You need to contact this code author in this regard. You cannot expect people here to help you with some totally random piece of code that someone else wrote.

Q
qbin author 6/7/2024

I've shared this here because I suspect there might be something I've missed, such as not incorporating JS where necessary (event X or something).
Since the functionality seems intact when I avoid using popups, I don't believe the issue lies solely within the script itself.

C
cristi 6/7/2024

PHPRunner page templates are bootstrap based so what you call "popup" is actually a "modal".

If you study the code behind an "add" page and an modal "add" page you will see that there are quite big differences: field names not being static, other clasess for divs, etc - and here lies your issue.

Just of curiosity: you used some AI to describe the problem for you? - your post starts with: "Sure, here is the optimized text for your forum post:" - nothing wrong with that, just curious....

Q
qbin author 6/10/2024

Hi Cristi,

Thank you for your help. I know that PHPRunner assigns an ID (that record ID or something like this) to every field when opening it in a modal. Since I'm not a JavaScript expert, I managed to solve the issue with a simpler code that doesn't use any library, rather than tweaking the existing code.

Yes, I've described the problem to an AI, ask it to improve it and generate a title for me (lack of inspiration :)... ).