0

Tengo funcionando un formulario que se envía con AJAX para que un archivo PHP procese los datos pero cada vez que la petición es enviada se recarga la página desde donde se envió. Quisiera saber si es posible que se envíen los datos al fichero PHP y no se recargue la página para poder obtener el estado de la petición y mostrar un mensaje que diga que se enviaron los datos.

Código JS

/*=============================================
=                   File                   =
=============================================*/

const realFileBtn = document.getElementById("real-file");
const customBtn = document.getElementById("custom-button");
const customTxt = document.getElementById("custom-text");

customBtn.addEventListener("click", function () {
    realFileBtn.click();
});

realFileBtn.addEventListener("change", function () {
    if (realFileBtn.value) {
        customTxt.innerHTML = realFileBtn.value.match(
            /[\/\\]([\w\d\s\.\-\(\)]+)$/
        )[1];
    } else {
        customTxt.innerHTML = `
                    Ninguna imagen seleccionada`;
    }
});

/*============  End of File  =============*/

const formulario = document.getElementById("formulario");
const btnEnviar = document.getElementById("btnEnviar");

let nombreCategoria = document.getElementById("nombreCategoria");
let inputValidar = document.getElementById("custom-text");
let inputArchivo = document.getElementById("real-file");

if (inputValidar.textContent === "Ninguna imagen seleccionada") {
    btnEnviar.disabled = true;
}

inputArchivo.addEventListener("change", () => {
    if (
        inputValidar.textContent !== "Ninguna imagen seleccionada" &&
        nombreCategoria.value !== ""
    ) {
        btnEnviar.disabled = false;
        btnEnviar.classList.remove("botonDesactivado");
    }
});

nombreCategoria.onkeyup = () => {
    if (
        nombreCategoria.value !== "" &&
        inputValidar.textContent !== "Ninguna imagen seleccionada"
    ) {
        btnEnviar.disabled = false;
        btnEnviar.classList.remove("botonDesactivado");
    } else {
        btnEnviar.disabled = true;
        btnEnviar.classList.add("botonDesactivado");
    }
};

insertarDatos = (e) => {
    e.preventDefault();

    const arhivo = document.getElementById("real-file");
    const nombreCategoría = document.getElementById("nombreCategoria");

    let datosEnviar = new FormData(formulario);
    datosEnviar.append(arhivo, nombreCategoría);

    let xhtpp = new XMLHttpRequest();

    xhtpp.open("POST", "/src/admin/categorias/subirCategoria.php", true);

    xhtpp.onload = function () {
        if (this.status === 200) {
            console.log(this.responseText);
        }
    };

    xhtpp.send(datosEnviar);
};

btnEnviar.addEventListener("click", insertarDatos);

Código PHP

<?php

require_once($_SERVER["DOCUMENT_ROOT"] . "/src/comprobarSesion.php");
require_once($_SERVER["DOCUMENT_ROOT"] . "/src/conexionbd.php");


if ($_SESSION['email'] !== 'admin@admin.com')
{
    header("Location: /pages/login.php");
    exit;
}
else
{

    $nombreCategoria = $_POST['nombreCategoria'];

    $nombreImagen = $_FILES['imagen']['name'];
    var_dump($nombreImagen);

    $tipoImagen = $_FILES['imagen']['type'];
    var_dump($tipoImagen);

    $temporalImagen = $_FILES['imagen']['tmp_name'];
    var_dump($temporalImagen);

    $rutaImagen = $_SERVER["DOCUMENT_ROOT"] . "/img/categorias/$nombreImagen";
    var_dump($rutaImagen);

    $insertarDatos = "INSERT INTO `categorias` ( `nombre_categoria`, `ruta_imagen`) VALUES ('$nombreCategoria', '$rutaImagen')";


    move_uploaded_file($temporalImagen, $rutaImagen);

    mysqli_query($conn, $insertarDatos);
}

Código HTML y PHP

<?php

require_once($_SERVER["DOCUMENT_ROOT"] . "/src/comprobarSesion.php");

if ($_SESSION['email'] !== 'admin@admin.com')
{
    header("Location: /pages/login.php");
}


?>

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="/css/admin/categorias/agregarCategorias.css">
</head>

<body>

    <form enctype="multipart/form-data" action="/src/admin/categorias/subirCategoria.php" method="post" id="formulario">


        <main class="contenedor">

            <div class="contenedor__nombre" id="contenedor__nombre">

                <p>Nombre de la Categoría</p>

                <input type="text" name="nombreCategoria" id="nombreCategoria">

            </div>

            <div class="contenedor__imagen">

                <input type="file" id="real-file" hidden="hidden" name="imagen" />
                <button type="button" id="custom-button">Subir Imagen</button>
                <br>
                <span id="custom-text">Ninguna imagen seleccionada</span>

            </div>

            <button class="contenedor__enviar botonDesactivado" id="btnEnviar">Enviar</button>

    </form>

    <script src="/js/admin/peticionCategoria.js"></script>

</body>

</html>

Cualquier ayuda o sugerencia es agradecida.

PD: Si no es mucha molestia quisiera saber cómo convertir el código de la petición AJAX a Fetch API. Gracias de antemano.

C0D3BREAK3R
  • 312
  • 1
  • 9
  • No estoy seguro de por qué habría de refrescarse, pero yo eliminaría el
    de la ecuación (el html), puedes hacerlo alterando la función "insertarDatos" con "let datosEnviar = new FormData();" y "formData.append(......);" generando el formulario "a mano" y evadiendo el método submit del
    (que podría causar los refresh)
    – Ricardo Galain Feb 27 '21 at 21:10
  • Gracias por la sugerencia, lo que hace que se refresque la página es la etiqueta form, pero al cambiar esta por un div y eliminar todos los atributos que tenia la etiqueta form excepto el id obtengo el siguiente error en consola: Uncaught TypeError: Failed to construct 'FormData': parameter 1 is not of type 'HTMLFormElement'. at HTMLButtonElement.insertarDatos (peticionCategoria.js:69) – C0D3BREAK3R Feb 28 '21 at 02:01
  • Como describe claramente, la linea con "new FormData(formulario);" es incorecta, no puedes instanciar un formulario en base a un div, se espera (como dice ahi) un 'HTMLFormElement'. Por eso deberás instanciarlo sin un formulario base ("new FormData();") y añadirle los campos a enviar con el metodo ".append(......);" – Ricardo Galain Feb 28 '21 at 02:15

0 Answers0