JS three file inputs form code simplification

Tengo un formulario con tres entradas de archivos. Esas entradas están ocultas con css porque quería personalizarlas, así que están representadas por sus etiquetas.

Tengo una solución de trabajo que adjunta un nombre de archivo y tamaño de archivo a su etiqueta cuando el archivo es elegido pero repite el mismo código tres veces.

He probado tantos para el bucle / para / para soluciones de bucle pero no he logrado la misma funcionalidad.

¿Puede alguien ayudar con una solución que no repite el mismo código tres veces?

const file1 = document.querySelector('#file_1');

file1.addEventListener('change', (e) => {
    // Get the selected file
    const [file] = e.target.files;
    // Get the file name and size
    const { name: fileName, size } = file;
    // Convert size in bytes to kilo bytes
    const fileSize = (size / 1000).toFixed(2);
    // Set the text content
    const fileNameAndSize = `${fileName} - ${fileSize}KB`;
    document.querySelector('.file1-name').textContent = fileNameAndSize;
});

const file2 = document.querySelector('#file_2');

file2.addEventListener('change', (e) => {
    // Get the selected file
    const [file] = e.target.files;
    // Get the file name and size
    const { name: fileName, size } = file;
    // Convert size in bytes to kilo bytes
    const fileSize = (size / 1000).toFixed(2);
    // Set the text content
    const fileNameAndSize = `${fileName} - ${fileSize}KB`;
    document.querySelector('.file2-name').textContent = fileNameAndSize;
});

const file3 = document.querySelector('#file_3');

file3.addEventListener('change', (e) => {
    // Get the selected file
    const [file] = e.target.files;
    // Get the file name and size
    const { name: fileName, size } = file;
    // Convert size in bytes to kilo bytes
    const fileSize = (size / 1000).toFixed(2);
    // Set the text content
    const fileNameAndSize = `${fileName} - ${fileSize}KB`;
    document.querySelector('.file3-name').textContent = fileNameAndSize;
});

Pregunta hecha hace 3 años, 4 meses, 29 días - Por techtrailblazer


3 Respuestas:

  • Este snippet abajo hace lo que quieres mientras mantiene el código exactamente igual.

    for (const i of [1,2,3]) {
        const file = document.querySelector(`#file_${i}`);
        file.addEventListener('change', (e) => {
            // Get the selected file
            const [file] = e.target.files;
            // Get the file name and size
            const { name: fileName, size } = file;
            // Convert size in bytes to kilo bytes
            const fileSize = (size / 1000).toFixed(2);
            // Set the text content
            const fileNameAndSize = `${fileName} - ${fileSize}KB`;
            document.querySelector(`.file${i}-name`).textContent = fileNameAndSize;
        });
    }
    

    Un mejor enfoque sería reutilizar el mismo onChange manejador. Necesitas saber qué '.fileN-name' elemento va con qué entrada de formulario. Una manera de lograrlo sería utilizar un atributo de datos HTML5 para que pudiera leerlo en el manejador de eventos como e.target.dataSet.[YOUR_PROPERTY_NAME_HERE]. Esto requeriría cambiar el HTML sin embargo.

    Respondida el Dec 18, 2020 a las 18:26 - por devdoodle

    Votos positivos: 0 | Votos negativos: 0

  • Puedes simplificar tu código utilizando una sola función para manejar la lógica de los cambios en los archivos y reutilizándola para las tres entradas de archivos. Aquí te muestro cómo hacerlo:

    ```javascript // Función para manejar los cambios en los archivos const handleFileChange = (inputId, textClass) => { const fileInput = document.querySelector(inputId);

    fileInput.addEventListener('change', (e) => {
        // Get the selected file
        const [file] = e.target.files;
        // Get the file name and size
        const { name: fileName, size } = file;
        // Convert size in bytes to kilo bytes
        const fileSize = (size / 1000).toFixed(2);
        // Set the text content
        const fileNameAndSize = `${fileName} - ${fileSize}KB`;
        document.querySelector(textClass).textContent = fileNameAndSize;
    });
    

    };

    // Llamar a la función para las tres entradas de archivos handleFileChange('file1', '.file1-name');handleFileChange('file2', '.file2-name');handleFileChange('file_3', '.file3-name');```

    Con esta modificación, ahora estás reutilizando la misma lógica para manejar los cambios en los archivos en las tres entradas de archivos, evitando repetir el mismo código varias veces.

    Respondida el Dec 19, 2020 a las 18:24 - por Gpt

    Votos positivos: 0 | Votos negativos: 0

  • Claro, aquí hay una solución que no repite el mismo código tres veces:

    ```js const inputFiles = document.querySelectorAll('input[type="file"]');

    inputFiles.forEach((inputFile) => { inputFile.addEventListener('change', (e) => { const file = e.target.files[0];

    if (file) {
      const fileNameAndSize = `${file.name} - ${(file.size / 1000).toFixed(2)}KB`;
      inputFile.nextElementSibling.textContent = fileNameAndSize;
    }
    

    }); }); ```

    En este código:

    • Seleccionamos todas las entradas de archivos (input) usando `document.querySelectorAll('input[type="file"]')`.
    • Recorremos cada entrada de archivo y agregamos un detector de eventos `change`.
    • Dentro del detector de eventos, obtenemos el archivo seleccionado de la entrada de archivo.
    • Si se selecciona un archivo, creamos una cadena que contiene el nombre del archivo y el tamaño del archivo en kilobytes.
    • Finalmente, establecemos el contenido de texto del elemento hermano siguiente de la entrada del archivo (que asumimos que es una etiqueta que representa la entrada del archivo) con el nombre del archivo y el tamaño.

    Este código simplifica el código original al eliminar la repetición y hacerlo más genérico para cualquier número de entradas de archivo.

    Respondida el Dec 19, 2020 a las 18:34 - por Gemini

    Votos positivos: 0 | Votos negativos: 0