Нужно чтобы в input выполнялся атрибут maxlength="1" при вводе с виртуальной клавиатуры на JS
// SCRIPT FOR KEYBOARD
const Keyboard = {
elements: {
keys: []
},
eventHandlers: {
oninput: null,
},
properties: {
value: "",
},
init() {
// Create main elements
this.elements.main = document.createElement("div");
this.elements.keysContainer = document.createElement("div");
// Setup main elements
this.elements.main.classList.add("keyboard", "keyboard--hidden");
this.elements.keysContainer.classList.add("keyboard__keys");
this.elements.keysContainer.appendChild(this._createKeys());
// Add to DOM
this.elements.main.appendChild(this.elements.keysContainer);
document.body.appendChild(this.elements.main);
// Automatically use keyboard for elements with .use-keyboard-input
document.querySelectorAll(".use-keyboard-input").forEach(element => {
element.addEventListener("focus", () => {
this.open(element.value, currentValue => {
element.value = currentValue;
});
});
});
},
_createKeys() {
const fragment = document.createDocumentFragment();
const keyLayout = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "bks"];
// Creates HTML for an icon
const createIconHTML = (icon_name) => {
return `<i class="material-icons">${icon_name}</i>`;
};
keyLayout.forEach(key => {
const keyElement = document.createElement("button");
const insertLineBreak = ["bks"].indexOf(key) !== -1;
// Add attributes/classes
keyElement.setAttribute("type", "button");
keyElement.classList.add("keyboard__key");
switch (key) {
case "bks":
// keyElement.classList.add("keyboard__key--wide");
keyElement.innerHTML = createIconHTML("bks");
keyElement.addEventListener("click", () => {
this.properties.value = this.properties.value.substring(0, this.properties.value.length - 1);
this._triggerEvent("oninput");
});
break;
default:
keyElement.textContent = key.toLowerCase();
keyElement.addEventListener("click", () => {
this.properties.value += this.properties.capsLock ? key.toUpperCase() : key.toLowerCase();
this._triggerEvent("oninput");
});
break;
}
fragment.appendChild(keyElement);
if (insertLineBreak) {
fragment.appendChild(document.createElement("br"));
}
});
return fragment;
},
_triggerEvent(handlerName) {
if (typeof this.eventHandlers[handlerName] == "function") {
this.eventHandlers[handlerName](this.properties.value);
}
},
open(initialValue, oninput) {
this.properties.value = initialValue || "";
this.eventHandlers.oninput = oninput;
},
};
window.addEventListener("DOMContentLoaded", function () {
Keyboard.init();
});
<div id="blok0">
<fieldset >
<input type="num" readonly style="cursor: pointer" id="number1" class="use-keyboard-input" maxlength="1" />
<input type="num" readonly style="cursor: pointer" id="number1" class="use-keyboard-input" maxlength="1" />
<input type="num" readonly style="cursor: pointer" id="number1" class="use-keyboard-input" maxlength="1" />
<input type="num" readonly style="cursor: pointer" id="number1" class="use-keyboard-input" maxlength="1" />
<input type="num" readonly style="cursor: pointer" id="number2" class="use-keyboard-input" maxlength="1" />
</fieldset >
</div>
Добрый день! Нашел в интернете виртуальную клавиатуру на js (сам в js не силен). Прикрутил к своему коду. Работает, но не выполняется атрибут maxlength="1". С аппаратной клавы все нормально. Что нужно и где подправить, чтобы заработало.
Ответы (1 шт):
Дело в том, что maxlength ограничивает ввод в поле input только когда это делает пользователь с клавиатуры, в данном же случае ввод в поле делается через javascript, изменяя свойство value, поэтому тут атрибут просто игнорируется.
Решить проблему можно добавив в обработчик нажатия на кнопку виртуальной клавиатуры проверку на наличие атрибута maxlength. Например так (для примера установил тут разные значения maxlength для разных полей ввода):
// SCRIPT FOR KEYBOARD
const Keyboard = {
elements: {
keys: []
},
eventHandlers: {
oninput: null,
},
properties: {
value: "",
},
init() {
// Create main elements
this.elements.main = document.createElement("div");
this.elements.keysContainer = document.createElement("div");
// Setup main elements
this.elements.main.classList.add("keyboard", "keyboard--hidden");
this.elements.keysContainer.classList.add("keyboard__keys");
this.elements.keysContainer.appendChild(this._createKeys());
// Add to DOM
this.elements.main.appendChild(this.elements.keysContainer);
document.body.appendChild(this.elements.main);
// Automatically use keyboard for elements with .use-keyboard-input
document.querySelectorAll(".use-keyboard-input").forEach(element => {
element.addEventListener("focus", () => {
this.open(element.value, key => {
if (key === "bks") {
element.value = element.value.substring(0, element.value.length - 1);
return
}
if (element.getAttribute('maxlength') && element.value.length >= element.getAttribute('maxlength')) {
return
}
element.value += key;
});
});
});
},
_createKeys() {
const fragment = document.createDocumentFragment();
const keyLayout = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "bks"];
// Creates HTML for an icon
const createIconHTML = (icon_name) => {
return `<i class="material-icons">${icon_name}</i>`;
};
keyLayout.forEach(key => {
const keyElement = document.createElement("button");
const insertLineBreak = ["bks"].indexOf(key) !== -1;
// Add attributes/classes
keyElement.setAttribute("type", "button");
switch (key) {
case "bks":
keyElement.innerHTML = createIconHTML("bks");
break;
default:
keyElement.textContent = key.toLowerCase();
break;
}
keyElement.addEventListener("click", () => {
this._triggerEvent("oninput", key);
});
fragment.appendChild(keyElement);
if (insertLineBreak) {
fragment.appendChild(document.createElement("br"));
}
});
return fragment;
},
_triggerEvent(handlerName, key) {
if (typeof this.eventHandlers[handlerName] == "function") {
this.eventHandlers[handlerName](key);
}
},
open(initialValue, oninput) {
this.properties.value = initialValue || "";
this.eventHandlers.oninput = oninput;
},
};
window.addEventListener("DOMContentLoaded", function () {
Keyboard.init();
});
<html lang="en">
<head>
<script src="main.js"></script>
<title>test</title>
</head>
<body>
<div id="blok0">
<fieldset>
<input type="num" style="cursor: pointer" id="number1" class="use-keyboard-input" maxlength="1"/>
<input type="num" style="cursor: pointer" id="number2" class="use-keyboard-input" maxlength="2"/>
<input type="num" style="cursor: pointer" id="number3" class="use-keyboard-input" maxlength="3"/>
<input type="num" style="cursor: pointer" id="number4" class="use-keyboard-input" maxlength="4"/>
<input type="num" style="cursor: pointer" id="number5" class="use-keyboard-input" />
</fieldset>
</div>
</body>
</html>