Изменение строкового поля в форме.
Проблема: Стандартные поля input[type="string"] не подходили для ввода большого текста, нужно добавить перенос текста по строкам, если он не помещается в поле, а также возможность изменить его размер.
Решение: Добавить код, которые ищет все input[type="string"] на странице, скрывает его и создает новый элемент textarea. Оба этих элемента связываются уникальным dataset, через который настроена передача данных.
function replaceStringInputsWithTextareas() {
const stringInputs = document.querySelectorAll('input[type="string"]');
stringInputs.forEach((input) => {
if (input.dataset.textareaReplaced) return;
const linkId =
"textarea_" + Date.now() + "_" + Math.random().toString(8).substr(2, 4);
input.dataset.textareaLinkId = linkId;
input.dataset.textareaReplaced = "true";
const textarea = document.createElement("textarea");
textarea.dataset.linkedInputId = linkId;
textarea.className = input.className;
textarea.value = input.value || "";
textarea.style.resize = "vertical";
input.style.display = "none";
const container = document.createElement("div");
container.className = linkId;
input.parentNode.insertBefore(container, input);
container.appendChild(textarea);
container.appendChild(input);
textarea.addEventListener("input", function () {
input.value = this.value;
input.dispatchEvent(new Event("input", { bubbles: true }));
});
});
}
document.addEventListener("DOMContentLoaded", function () {
setTimeout(function () {
replaceStringInputsWithTextareas();
}, 200);
});
Было (Текст в 1 строку , просто исчезает если не влазит)
Стало (Текст переносится, можно расширить поле, если он не влазит)
Улучшение интерфейса формы
Проблема: При изменении стандартных полей всегда возникают ошибки в интерфейсе, название поля не работает, подсказки для поля уплывают. Также в стандартном интерфейсе подсказки для поля пишутся снизу, что неудобно для чтения, если в него пишутся большие вопросы.
Решение: Изменении логики названия полей, теперь они находятся над полями, а также изменение структуры формы, при наличии подсказки для поля она переносится под вопрос, над полем.
function organizeFieldsSafe() {
const containers = document.querySelectorAll(
".b24-form-control-string, .b24-form-control-list, .b24-form-control-text"
);
containers.forEach((container) => {
if (container.dataset.organized) return;
const label = container.querySelector(".b24-form-control-label");
const comment = container.querySelector(".b24-form-control-comment");
if (label) {
container.prepend(label);
}
if (comment && label) {
label.insertAdjacentElement("afterend", comment);
}
container.dataset.organized = "true";
});
document.addEventListener("DOMContentLoaded", function () {
setTimeout(function () {
organizeFieldsSafe();
}, 200);
});
<style>
.b24-form-control-label {
margin-bottom: 8px !important;
display: block !important;
font-weight: 600 !important;
color: #333 !important;
position: relative !important;
left: 0 !important;
transform: translateY(0%) !important;
right: 0 !important;
white-space: normal !important;
padding-left: 0 !important;
}
Было: (Названия полей внутри, подсказки для поля под полем)
Стало: (Названия и подсказки для полей вынесены над полем)
Автоматическое удаление повторных названий в множественных полях
Проблема: В множественных полях есть функция «Добавить еще», в которой можно добавить дополнительные значения, но так как названия в полях были вынесены над поля, это ломает интерфейс.
Решение: Находить множественные поля и проверять количество названий. Все кроме первого удалять.
function removeExtraLabels() {
const containers = document.querySelectorAll(".b24-form-control-string, .b24-form-control-list, .b24-form-control-text");
let totalRemoved = 0;
containers.forEach((container, containerIndex) => {
const labels = container.querySelectorAll(".b24-form-control-label");
const fields = container.querySelectorAll("input, textarea, select");
if (fields.length > 1 && labels.length > 1) {
for (let i = labels.length - 1; i >= 1; i--) {
labels[i].remove();
totalRemoved++;
}
}
});
return totalRemoved;
}
document.addEventListener("DOMContentLoaded", function () {
setTimeout(function () {
removeExtraLabels();
}, 200);
});
setInterval(removeExtraLabels, 1000);
Было: (Названия множественного поля находятся в поле, поэтому дублируются)
Стало: (Названия сверху, удаляются при добавлении новых вариантов ответа)
Изменение названия формы на ФИО оцениваемого сотрудника
Проблема: При оценке необходимо понимать какого сотрудника мы оцениваем, нужно вывести его ФИО в название формы
Решение: При отправке URL формы, необходимо добавить параметр name, в котором передать ФИО оцениваемого сотрудника, после чего записать ФИО в название формы
ffunction getNameFromUrl() {
const urlParams = new URLSearchParams(window.location.search);
return urlParams.get("name");
}
function updateFormTitle() {
const name = getNameFromUrl();
if (name) {
const formTitle = document.querySelector(".b24-form-header-title");
formTitle.textContent = name;
}
}
document.addEventListener("DOMContentLoaded", function () {
setTimeout(function () {
updateFormTitle();
}, 200);
});
Было: (Название формы вынесено перед ней, статичное)
Стало: (Изменяется в зависимости от параметра name, переданного в ссылке)
Общий код для всех настроек:
<script>
function replaceStringInputsWithTextareas() {
const stringInputs = document.querySelectorAll('input[type="string"]');
stringInputs.forEach((input) => {
if (input.dataset.textareaReplaced) return;
const linkId =
"textarea_" + Date.now() + "_" + Math.random().toString(8).substr(2, 4);
input.dataset.textareaLinkId = linkId;
input.dataset.textareaReplaced = "true";
const textarea = document.createElement("textarea");
textarea.dataset.linkedInputId = linkId;
textarea.className = input.className;
textarea.value = input.value || "";
textarea.style.resize = "vertical";
input.style.display = "none";
const container = document.createElement("div");
container.className = linkId;
input.parentNode.insertBefore(container, input);
container.appendChild(textarea);
container.appendChild(input);
textarea.addEventListener("input", function () {
input.value = this.value;
input.dispatchEvent(new Event("input", { bubbles: true }));
});
});
}
function organizeFieldsSafe() {
const containers = document.querySelectorAll(
".b24-form-control-string, .b24-form-control-list, .b24-form-control-text"
);
containers.forEach((container) => {
if (container.dataset.organized) return;
const label = container.querySelector(".b24-form-control-label");
const comment = container.querySelector(".b24-form-control-comment");
if (label) {
container.prepend(label);
}
if (comment && label) {
label.insertAdjacentElement("afterend", comment);
}
container.dataset.organized = "true";
});
}
function removeExtraLabels() {
const containers = document.querySelectorAll(
".b24-form-control-string, .b24-form-control-list, .b24-form-control-text"
);
let totalRemoved = 0;
containers.forEach((container, containerIndex) => {
const labels = container.querySelectorAll(".b24-form-control-label");
const fields = container.querySelectorAll("input, textarea, select");
if (fields.length > 1 && labels.length > 1) {
// Удаляем все лейблы кроме первого (сохраняем индекс 0)
for (let i = labels.length - 1; i >= 1; i--) {
labels[i].remove();
totalRemoved++;
}
}
});
return totalRemoved;
}
function getNameFromUrl() {
const urlParams = new URLSearchParams(window.location.search);
return urlParams.get("name");
}
function updateFormTitle() {
const name = getNameFromUrl();
if (name) {
const formTitle = document.querySelector(".b24-form-header-title");
formTitle.textContent = name;
}
}
document.addEventListener("DOMContentLoaded", function () {
setTimeout(function () {
replaceStringInputsWithTextareas();
organizeFieldsSafe();
removeExtraLabels();
updateFormTitle();
}, 500);
});
setInterval(removeExtraLabels, 1000);
</script>
<style>
.b24-form-control-label {
margin-bottom: 8px !important;
display: block !important;
font-weight: 600 !important;
color: #333 !important;
position: relative !important;
left: 0 !important;
transform: translateY(0%) !important;
right: 0 !important;
white-space: normal !important;
padding-left: 0 !important;
}
.b24-form-control-comment {
margin-bottom: 4px !important;
display: block !important;
font-size: 12px !important;
color: #666 !important;
}
.b24-form-control-list
.b24-form-control-icon-after
.b24-form-control-not-empty.b24-form-control,
.b24-form-control-list
.b24-form-control-icon-after
.b24-form-control-not-empty.b24-form-control-label {
padding: 0 80px 0 15px;
}
textarea.b24-form-control {
min-height: 80px;
resize: vertical;
width: 100%;
box-sizing: border-box;
padding: 12px;
border: 1px solid #c6cdd3;
border-radius: 2px;
}
</style>