From 435eb780eab8117d7b3f3af3a8d1df788699ca36 Mon Sep 17 00:00:00 2001 From: Alexandre Delaunay Date: Thu, 25 Sep 2025 15:03:26 +0200 Subject: [PATCH 1/2] better solution for computeDynamicInputSize --- js/common.js | 66 ---------------------------- js/modules/Forms/EditorController.js | 2 +- 2 files changed, 1 insertion(+), 67 deletions(-) diff --git a/js/common.js b/js/common.js index 23a79f743cd..685c0f1f150 100644 --- a/js/common.js +++ b/js/common.js @@ -1676,72 +1676,6 @@ function waitForElement(selector) { }); } -/** - * Get the ideal width of an input element based on its content. - * This allow to make dynamic inputs that grow and shrink based on their content. - * - * Inspired by: https://phuoc.ng/collection/html-dom/resize-the-width-of-a-text-box-to-fit-its-content-automatically/ - * - * @param {HTMLElement} input - * @param {String} real_font_size It seems the font size computed by styles.fontSize - * is not really accurate when using rem units. - * This parameter allows to directly provide the - * accurate font size if it's known. - * - * @return {String} The ideal width of the input element - */ -function getRealInputWidth(input, real_font_size = null) -{ - let fakeEle = $("#fake_dom_getRealInputWidth"); - - // Initialize our fake element only once to prevent useless computations - if (fakeEle.length === 0) { - // Create a div element - fakeEle = document.createElement('div'); - fakeEle.id = "fake_dom_getRealInputWidth"; - - // Hide it completely - fakeEle.style.position = 'absolute'; - fakeEle.style.top = '0'; - fakeEle.style.left = '0'; - fakeEle.style.left = '-9999px'; - fakeEle.style.overflow = 'hidden'; - fakeEle.style.visibility = 'hidden'; - fakeEle.style.whiteSpace = 'nowrap'; - fakeEle.style.height = '0'; - - // Append the fake element to `body` - document.body.appendChild(fakeEle); - } else { - fakeEle = fakeEle[0]; - } - - // We copy some styles from the textbox that effect the width - const styles = window.getComputedStyle(input); - - // Copy font styles from the textbox - fakeEle.style.fontFamily = styles.fontFamily; - fakeEle.style.fontSize = real_font_size ?? styles.fontSize; - fakeEle.style.fontStyle = styles.fontStyle; - fakeEle.style.fontWeight = styles.fontWeight; - fakeEle.style.letterSpacing = styles.letterSpacing; - fakeEle.style.textTransform = styles.textTransform; - - fakeEle.style.borderLeftWidth = styles.borderLeftWidth; - fakeEle.style.borderRightWidth = styles.borderRightWidth; - fakeEle.style.paddingLeft = styles.paddingLeft; - fakeEle.style.paddingRight = styles.paddingRight; - - // Compute width - const string = input.value || input.getAttribute('placeholder') || ''; - fakeEle.innerHTML = string.replace(/\s/g, '&' + 'nbsp;'); - - const fakeEleStyles = window.getComputedStyle(fakeEle); - const width = fakeEleStyles.width; - - return width; -} - /** * Get UUID using crypto.randomUUID() if possible * Else fallback to uniqid() diff --git a/js/modules/Forms/EditorController.js b/js/modules/Forms/EditorController.js index b21e596099d..2b2d6b6387d 100644 --- a/js/modules/Forms/EditorController.js +++ b/js/modules/Forms/EditorController.js @@ -1755,7 +1755,7 @@ export class GlpiFormEditorController * @param {HTMLElement} input */ #computeDynamicInputSize(input) { - $(input).css("width", getRealInputWidth(input, "1.2rem")); + $(input).css("width", Math.max(input.value.length + 1, 15) + "ch"); } /** From f606f4debb6e8cac55dc6e26c498ee0faeeae3be Mon Sep 17 00:00:00 2001 From: Alexandre Delaunay Date: Fri, 26 Sep 2025 15:24:17 +0200 Subject: [PATCH 2/2] remove entirely --- js/modules/Forms/EditorController.js | 32 +--------------------------- 1 file changed, 1 insertion(+), 31 deletions(-) diff --git a/js/modules/Forms/EditorController.js b/js/modules/Forms/EditorController.js index 2b2d6b6387d..8dbf6dbf56d 100644 --- a/js/modules/Forms/EditorController.js +++ b/js/modules/Forms/EditorController.js @@ -31,7 +31,7 @@ * --------------------------------------------------------------------- */ -/* global _, tinymce_editor_configs, getUUID, getRealInputWidth, sortable, tinymce, glpi_toast_info, glpi_toast_error, bootstrap, setupAjaxDropdown, setupAdaptDropdown, setHasUnsavedChanges, hasUnsavedChanges */ +/* global _, tinymce_editor_configs, getUUID, sortable, tinymce, glpi_toast_info, glpi_toast_error, bootstrap, setupAjaxDropdown, setupAdaptDropdown, setHasUnsavedChanges, hasUnsavedChanges */ import { GlpiFormConditionVisibilityEditorController } from '/js/modules/Forms/ConditionVisibilityEditorController.js'; import { GlpiFormConditionValidationEditorController } from '/js/modules/Forms/ConditionValidationEditorController.js'; @@ -130,13 +130,6 @@ export class GlpiFormEditorController this.#initEventHandlers(); this.#refreshUX(); - // Adjust dynamics inputs size - $(this.#target) - .find("[data-glpi-form-editor-dynamic-input]") - .each((index, input) => { - this.#computeDynamicInputSize(input); - }); - // These computations are only needed if the form will be edited. if (!this.#is_readonly) { // Validate default question type @@ -418,11 +411,6 @@ export class GlpiFormEditorController ); break; - // Compute the ideal width of the given input based on its content - case "compute-dynamic-input": - this.#computeDynamicInputSize(target[0]); - break; - // Change the type category of the target question case "change-question-type-category": await this.#changeQuestionTypeCategory( @@ -1089,11 +1077,6 @@ export class GlpiFormEditorController .find("[data-glpi-form-editor-question-details-name]")[0] .focus(); - // Compute dynamic inputs size - new_question.find("[data-glpi-form-editor-dynamic-input]").each((index, input) => { - this.#computeDynamicInputSize(input); - }); - // Enable sortable on the new question this.#enableSortable(new_question); } @@ -1750,14 +1733,6 @@ export class GlpiFormEditorController throw new Error(`Field not found: ${field}`); } - /** - * Compute the ideal width of the given input based on its content. - * @param {HTMLElement} input - */ - #computeDynamicInputSize(input) { - $(input).css("width", Math.max(input.value.length + 1, 15) + "ch"); - } - /** * Set or remove loading state for question type specific content. * This makes the content appear disabled and non-interactive during condition checks. @@ -2151,11 +2126,6 @@ export class GlpiFormEditorController .find("[data-glpi-form-editor-comment-details-name]")[0] .focus(); - // Compute dynamic inputs size - new_comment.find("[data-glpi-form-editor-dynamic-input]").each((index, input) => { - this.#computeDynamicInputSize(input); - }); - // Enable sortable on the new comment this.#enableSortable(new_comment); }