I have a form in which I am going to upload an image, HTML5 for the form, JS to get data and validation and PHP for the back.
So, I get by a function all the data of the form:
HTML5
<?php
require_once '../model/categoriaModel.php';
$dataForm = new CategoriaModel();
?>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Bootstrap core CSS -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<link rel="stylesheet" type="text/css" href="../assets/css/design-food-menu.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"></script>
</head>
<body>
<main role="main" class="backblack">
<br><br>
<div class="container ">
<h2 class="featurette-heading">Capturar <span class="text-muted">Nuevo Producto o Platillo.</span></h2>
<p class="lead">Todos los campos con * son obligatorios. Captura la información de manera correcta.</p>
<br>
<form id="contact" enctype="multipart/form-data" method="post" class="needs-validation" novalidate>
<div class="row">
<div class="col-md-6">
<label for="telefono">Imagen del Producto (500px * 500px)</label>
<img src="../assets/img/not_found.jpg" class="img_n_f" id="output">
<div class="upload-btn-wrapper">
<a class="upload-btn text-center text-white" >Upload a file</a>
<input type="file" name="url_img" id="url_img" style="width: 100%;" onchange="document.getElementById('output').src = window.URL.createObjectURL(this.files[0])" />
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label for="nombre">Nombre del Producto o Platillo</label>
<input type="text" class="form-control" id="nombre_producto" placeholder="ej: Pasta Alfredo" name="nombre_producto" minlength="4" maxlength="250" required pattern="^[a-zA-Z0-9 ]*$">
<div class="valid-feedback">Correcto.</div>
<div class="invalid-feedback">Ingresa un nombre de producto correcto. No aceptamos puros espacios en blanco. Min 5 Max 250 caracteres. No usar (*%/$+-.,).</div>
</div>
<div class="form-group">
<label for="empresa">Descripción General</label>
<input type="text" class="form-control" id="descripcion_producto" placeholder="ej: La Pasta Alfredo consiste en una técnica de ....." name="descripcion_producto" minlength="5" maxlength="500" required pattern="^[a-zA-Z0-9 ]*$">
<div class="valid-feedback">Correcto.</div>
<div class="invalid-feedback">Ingresa una descripción correcta. No aceptamos puros espacios en blanco. Min 5 Max 500 caracteres. No usar (*%/$+-.,).</div>
</div>
<div class="form-group">
<label for="servicio">Categoria del Producto</label>
<select class="form-control" id="id_categoria" name="id_categoria" required>
<option value="">Selecciona la categoria del producto...</option>
<?php
$dataForm->getCategoria();
?>
</select>
<div class="valid-feedback">Correcto.</div>
<div class="invalid-feedback">Selecciona una opción...</div>
</div>
<div class="form-group">
<label for="tipo_descuento">Tipo de Descuento</label><br>
<input type="radio" name="descuento" value="pesos"> desc en $ <input type="radio" name="descuento" value="porcentaje"> desc en % <input type="radio" name="descuento" value="ninguno"> sin descuento
<div class="valid-feedback">Correcto.</div>
<div class="invalid-feedback">Selecciona una opción...</div>
</div>
<div class="form-group" id="descHide">
<label for="desc_total">Descuento del Producto</label>
<input class="form-control" type="number" id="desc_total" name="desc_total" pattern="[0-9]{10}" value="0" min="-9999" max="0">
<div class="valid-feedback">Correcto.</div>
<div class="invalid-feedback">Ingresa un descuento correcto, no aceptamos letras, o caracteres extraños.</div>
</div>
<div class="form-group">
<label for="telefono">Precio del Producto</label>
<input class="form-control" type="number" id="precio_producto" name="precio_producto" placeholder="ej: 250" pattern="[0-9]{10}" required>
<div class="valid-feedback">Correcto.</div>
<div class="invalid-feedback">Ingresa un precio correcto, no aceptamos letras, o caracteres extraños.</div>
</div>
<a onclick="sendForm(this)" class="btn btn-success text-white shadow-lg btn-lg">Guardar</a>
</div>
</div>
</form>
<br><br><br>
</div>
</main>
<!-- SUCCESS / FAIL ACTION MODAL -->
<div class="modal fade" id="actionModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<!-- Modal Header -->
<div class="modal-header">
<h2 class="modal-title"><p id="successModalTitle"></p></h2>
<button type="button" class="close" data-dismiss="modal">×</button>
</div>
<form>
<!-- Modal body -->
<div class="modal-body">
<p id="successModalDescription"></p>
</div>
<!-- Modal footer -->
<div class="modal-footer">
<button class="btn btn-success" type="button" data-dismiss="modal" onclick="this.form.reset();">Continuar</button>
</div>
</form>
</div>
</div>
</div>
<footer class="text-muted bg-white">
<div class="container">
<br>
<p class="float-right">
<a href="#" class="text-warning">Volver al Principio</a>
</p>
<br>
</div>
</footer>
<script src="../assets/jquery/jquery.min.js"></script>
<script type="text/javascript" src="../assets/js/producto.js"></script>
<script src="../assets/js/bootstrap.bundle.min.js"></script>
<!-- Core plugin JavaScript-->
<script src="../assets/jquery-easing/jquery.easing.min.js"></script>
</body>
</html>
And then via Jquery I get the data, validate and send via AJAX to PHP as follows:
// Disable form submissions if there are invalid fields
function sendForm(){
// Get the forms we want to add validation styles to
var forms = document.getElementsByClassName('needs-validation');
// Loop over them and prevent submission
var validation = Array.prototype.filter.call(forms, function(form) {
if (form.checkValidity() === false) {
//$('#actionModal').modal('toggle');
event.preventDefault();
event.stopPropagation();
}else{
var id_categoria = $("#id_categoria option:selected").val();
var nombre_producto = $("#nombre_producto").val();
var descripcion_producto = $("#descripcion_producto").val();
var url_img = $('#url_img').prop('files')[0];
//var url_img = $('#url_img')[0].files[0];
var precio_producto = $("#precio_producto").val();
var desc_total = $("#desc_total").val();
var tipo_descuento = $("input[name='descuento']:checked").val();
if(tipo_descuento=="ninguno"){
var tipo_descuento = "0";
}else if(tipo_descuento=="porcentaje"){
var tipo_descuento = "1";
}else if(tipo_descuento=="pesos"){
var tipo_descuento = "2";
}
//alert('-> ' + id_categoria + ', ' + nombre_producto + ', ' + url_img + ', ' +tipo_descuento + ', ' + descripcion_producto );
var formData = new FormData();
formData.append('id_categoria',id_categoria);
formData.append('nombre_producto',nombre_producto);
formData.append('descripcion_producto',descripcion_producto);
formData.append('archivo',url_img);
formData.append('precio_producto',precio_producto);
formData.append('desc_total',desc_total);
formData.append('tipo_descuento',tipo_descuento);
formData.append('function',"addDataForm");
$.ajax({
data: formData, //send data via AJAX
url: '../controller/ctrlProducto.php', //url file controller PHP
dataType:'json',
contentType: false,
processData: false,
type: 'post', //send POST data
success:function(response) { //get request
if(response.success){
$("#successModalTitle").html("<i class='fas fa-check-circle color-success'></i> ¡Éxito!");
$("#successModalDescription").html(response.message);
$("#contact").trigger("reset");
$("#contact").removeClass("was-validated");
}else{
$("#successModalTitle").html("<i class='fas fa-exclamation-circle color-error'></i> ¡Error!");
$("#successModalDescription").html(response.message);
}
$('#actionModal').modal('toggle');
}
});
}
form.classList.add('was-validated');
});
}
and already in PHP, I do the following, which is really, insert data, save the image and the PHP returns a JSON with 2 attributes to my AJAX request, so that I can read it in JS and assign a SUCCESS message to my MODAL and show it.
$nombre = $_FILES['archivo']['name'];
//$ruta = $_FILES['archivo']['tmp_name'];
$url_imagen = "../assets/img/productos/" . $nombre;
if (move_uploaded_file($_FILES["archivo"]["tmp_name"], $url_imagen)) {
print_r("El Archivo ha sido subido correctamente.");
} else {
print_r("Lo sentimos, hubo un error subiendo el archivo.");
}
require_once 'conn/connection.php';
$connect = new connection();
$connection=$connect->connections();
$sql = "INSERT INTO producto (id_categoria, nombre_producto, descripcion_producto, url_imagen, precio_producto, desc_total, tipo_descuento, f_creacion, f_actualizacion, status) VALUES ('".$_POST['id_categoria'] ."','".$_POST['nombre_producto']."','".$_POST['descripcion_producto']."','".$nombre."','".$_POST['precio_producto']."','".$_POST['desc_total']."','".$_POST['tipo_descuento']."','".date('Y-m-d H:i:s')."','".date('Y-m-d H:i:s')."', '1');";
//print_r($sql);
$jsondata = array();
if ($connection->query($sql)===true) {
$message= "Tu información ha sido enviada correctamente.";
$jsondata['success'] = true;
$jsondata['message'] = $message;
} else {
$message= "Hemos tenido un problema al guardar un información, contacta al servicio técnico.";
$jsondata['success'] = false;
$jsondata['message'] = $message;
}
//Aunque el content-type no sea un problema en la mayoría de casos, es recomendable especificarlo
header('Content-type: application/json; charset=utf-8');
echo json_encode($jsondata, JSON_FORCE_OBJECT);
The INSERT code is fine, it saves the image fine, BUT IT DOES NOT RETURN THE RESPONSE, in the console I see the response, but the MODAL is never activated.
The AJAX request expects a response of type JSON, but with this piece of code you make the type "break":
Solution: Don't print those messages.
As I see you have some print_r in your status messaging, when doing a print_r you interrupt the output of the AJAX JSON request
I hope to help you, greetings!