0

Estoy realizando una aplicación con php y JQuery y utilizo y utilizo el JQuery para hacer peticiones ajax para cargar algunas partes del la página y se me presenta un problema cuando voy a registrar un nuevo libro mediante el panel que creé para eso, cuando registro un libro por primera vez lo hace normal pero cuando lo vuelvo a hacer lo registra 2 veces y si lo vuelvo a hacer lo realiza mas de dos veces y así sucesivamente...

Este es el código del panel de registro:

<?php
require_once "comprobar_in.php";
require_once "conexion.php";
?>

<header>
<h3 id="tocar">Registrar libro <span id="salir_rl">X</span></h3>
</header>

<form id="frm_reg_lib">

<div class="campo-formulario">
<label for="nombre">Nombre:</label>
<input type="text" maxlength="50" name="nombre" id="nombre" required />
</div>

<div class="campo-formulario">
<label for="autor">Autor:</label>
<input type="text" maxlength="50" name="autor" id="autor" required />
</div>

<div class="campo-formulario">
<label for="estado">Estado:</label>

<div id="c_estado">

  <label for="radio" class="estado">Disponible</label>
  <input type="radio" maxlength="50" name="estado" id="estado" class="estado" required value="Disponible"  checked />

  <br />

  <label for="radio" class="estado">No disponible</label>
  <input type="radio" maxlength="50" name="estado" id="estado" class="estado" value="No disponible" required />
  </div>
  </div>

  <div class="campo-formulario">
  <label for="codigo">Código:</label>
  <input type="text" maxlength="50" name="codigo" id="codigo" required />
  </div>

<div class="campo-formulario">
   <label for="tipo">Tipo:</label>
   <input type="text" maxlength="50" name="tipo" id="tipo" required />
</div>

<div class="campo-formulario">
  <label for="editorial">Editorial:</label>
  <input type="text" maxlength="50" name="editorial" id="editorial" required />
</div>

<div class="campo-formulario">
  <button type="button" class="boton" id="btn_registrar_libro">Registrar</button>
</div>
</form>
<?php 
 require_once "agregar_script.php";
 ?>

contenido de registrar_libro.php:

<?php 
require_once "conexion.php";

$nombre    = $_POST['nombre'];
$autor     = $_POST['autor'];
$estado    = $_POST['estado'];
$codigo    = $_POST['codigo'];
$tipo      = $_POST['tipo'];
$editorial = $_POST['editorial'];

// $nombre    = 'qwe';
// $autor     = 'qwe';
// $estado    = 'Disponible';
// $codigo    = 'qwe';
// $tipo      = 'qwe';
// $editorial = 'qwe';

if($_SERVER['REQUEST_METHOD'] == 'POST'){
$consulta = $conexion->query("INSERT INTO libros (nombre, autor, estado, codigo, tipo, editorial) VALUES ('$nombre', '$autor', '$estado', '$codigo', '$tipo', '$editorial')");
if ($consulta) {
echo "exitoso";
}else{
 echo "error";
}
}
?>

y este el código JQuery que utilizo para cargar las páginas con ajax:

/**
* Registrar nuevo libro
*/

$("#btn_registrar_libro").on("click", function(){
$formulario = $("#frm_reg_lib").serialize();
$.post("registrar_libro.php", $formulario, function(result){
  alert("El libro se agregó correctamente");
if (result == "exitoso") {
  $("#nombre").val("");
  $("#autor").val("");
  $("#codigo").val("");
  $("#tipo").val("");
  $("#editorial").val("");
  $("#tabla").load("tabla.php");
}else if (result == "error") {
  alert("Hubo un problema al registrar el libro");
}
});
});

/**
* Barra de navegación
*/


$("#home").on("click", function(e){
e.preventDefault();
$("#home").removeClass("boton_nav");
$("#home").addClass("activa");
$("#libros, #registros").removeClass("activa");
$("#libros, #registros").addClass("boton_nav");
});

$("#libros").on("click",function(e){
e.preventDefault();
$("#libros").removeClass("boton_nav");
$("#libros").addClass("activa");
$("#home, #registros").removeClass("activa");
$("#home, #registros").addClass("boton_nav");
$("#contenido").load("libros.php");
});

$("#registros").on("click",function(e){
e.preventDefault();
$("#registros").removeClass("boton_nav");
$("#registros").addClass("activa");
$("#home, #libros").removeClass("activa");
$("#home, #libros").addClass("boton_nav");
$("#contenido").load("registros.php");
});

/**
* Mostrar panel para registrar libro
*/

$("#registrarL").on("click", function(e){
e.preventDefault();
$("#registrarL").hide("1000");
$("#reg_libro").show("1000");
});

/**
* Ocultar panel para registrar
*/

$("#salir_rl").on("click", function(){
$("#reg_libro").hide("1000");
$("#registrarL").show("1000");
});
Mac32
  • 92
  • 10
  • ¿Puedes poner el contenido del archivo registrar_libro.php? así será más sencillo ayudarte – Mario L Apr 08 '18 at 03:39
  • Listo amigo ya lo agregué – Mac32 Apr 08 '18 at 03:48
  • Cuando tratás de agregar un libro "por segunda vez", te referís a que estás tratando de insertar un libro ya cargado en la base de datos? si es así, tu problema está en la estructura de la base de datos, ya que no deberías poder agregar dos registros con el mismo id (suponiendo que el id de la tabla libros es autoincremental). En el código que pusiste con tu pregunta, no encuentro errores. – Mario L Apr 08 '18 at 03:55
  • Me refiero a que cuando trato de agregar otro libro se registra 2 veces y si intento registrar otro se registra mas de dos veces y así sucesivamente. Creo que tal vez el problema está en la llamada ajax porque es la primera vez que trabajo con esta tecnología y no se mucho de ella. – Mac32 Apr 08 '18 at 04:01
  • La forma en la que utilizas ajax (jQuery) es correcta. Ahí no está el error. – Mario L Apr 08 '18 at 04:18

1 Answers1

0

Actualmente a simple vista no se pueden observar errores de lógica o de código incorrecto si muestra comportamiento equivocado no es por el código expuesto , El único detalle grave es que tu código es propenso a recibir ataques de inyección SQL , que es la consecuencia más cercana de concatenar valores directamente a la consulta ejecutada.

Propongo preparar la query para darle más seguridad, con mysqli_prepare , estos detalles se tomaron en cuenta y se explican más a detalle en la siguiente pregunta ¿Cómo evitar la inyección SQL en PHP?

require_once "conexion.php";

if($_SERVER['REQUEST_METHOD'] === 'POST'){
    $nombre    = $_POST['nombre'];
    $autor     = $_POST['autor'];
    $estado    = $_POST['estado'];
    $codigo    = $_POST['codigo'];
    $tipo      = $_POST['tipo'];
    $editorial = $_POST['editorial'];
    //Preparamos la consulta , para luego bindear los valores recibidos por POST
    if ($sentencia = $conexion->prepare("
            INSERT INTO libros (nombre, autor, estado, codigo, tipo, editorial) 
            VALUES (?, ?, ?, ?, ?, ?)")) 
    {
        /* bindear los  parámetros para marcadores, asumo que todos son Strings */
        $sentencia->bind_param("ssssss", $nombre, $autor,$estado,$codigo,$tipo,$editorial);
        /* ejecutar la consulta */
        if($sentencia->execute()) {
            echo "exitoso";
        }else{
            echo "error";
        }
        $sentencia->close();
    }
    $conexion->close();
}

Además del lado de JQuery puede resetear el form directamente y evitar limpiar cada campo

$("#btn_registrar_libro").on("click", function(){
    $formulario = $("#frm_reg_lib").serialize();
    $.post("registrar_libro.php", $formulario, function(result){
        alert("El libro se agregó correctamente");
        if (result == "exitoso") {
            $("#frm_reg_lib")[0].reset(); //Limpiar el form
            $("#tabla").load("tabla.php");
        }else if (result == "error") {
            alert("Hubo un problema al registrar el libro");
        }
    });
});
Dev. Joel
  • 23,229
  • 3
  • 25
  • 44
  • Ok amigo gracias por las recomendaciones, me ayudan mucho las tendré en cuanta. Cual sería la forma correcta de cargar un documento php dentro de otro mendiante JQuery ajax? al final de los documentos que van dentro de otro tuve que incluir nuevamente el script.js y el jquery.js porque no me funcionaban los eventos. Será que hay una forma de hacerlo sin agregar los scripts en cada archivo? – Mac32 Apr 08 '18 at 04:22
  • 1
    @Mac32 ¿ Tiene lógica y eventos en esa página? bastaría con añadir las librerías en la principal y los evento en la otra página , siempre y cuando añada correctamente el listener. pero eso ya escapa de la pregunta formulada. – Dev. Joel Apr 08 '18 at 04:40
  • Creo que entiendo amigo. Debo dividir el script en 2, la lógica y los eventos, agrego la parte lógica a la página principal y los eventos en cada secundaria. Muchas gracias!. Creo que si tiene que ver con la pregunta porque creo que el problema debe estar en el script JQuery porque el es el que maneja los eventos y llama los archivos php. – Mac32 Apr 08 '18 at 14:27
  • Ese puede ser el detalle entonces. estás lanzando dos veces el evento. Igual tomar en cuenta la seguridad con mi respuesta. Saludos _(y si ayudó a resolver su problema marcar como aceptada mi respuesta)_ – Dev. Joel Apr 08 '18 at 16:07
  • Amigo investigando un poco descubrí que la solución no es agregarle el script a cada página, simplemente utilizando el método on() de la siguiente forma hago que funcionen los botones y sin que se dispare varias veces el evento: $("#contenido").on("click", "#btn_registrar_libro", funciona(){}). Muchas gracias. El problema como dijiste es que cada vez que disparaba el evento y se cargaba la página con ajax se sumaba otro script y cuando lo hacía por segunda vez se sumaba otro mas, mas los que ya tenia y así sucesivamente. Te lo agradezco mucho. – Mac32 Apr 08 '18 at 17:20
  • 1
    @Mac32 sí , no dije lo contrario . debes utilizar event delegation desde la página principal y funcionará correctamente. – Dev. Joel Apr 08 '18 at 17:25