1

Buenas,

La finalidad de este código es comprobar si un registro (número), enviado mediante el form, existe en la BBDD. El botón submit (que se encuentra invisible) ha de visualizarse en pantalla si se confirma que el registro introducido existe en la BBDD.

Ocurre que el input submit desaparece de pantalla unicamente cuando se introduce un registro en el input text y luego se borra.

No entiendo porque el condicional de este código jQuery no aplica como pienso que debiera.

El código se encuentra dividido en 2 archivos.

Archivo 1 -- JAVASCRIPT + HTML :

$(document).ready(function() {

document.seleccionar.modificar.style.visibility = "hidden";
                         
      var consulta;
             
      $("#id").focus();
                                                 
      $("#id").keyup(function(e){
             
             consulta = $("#id").val();
                                      
             $("#resultado").delay(100).queue(function(n) {      
                                           
                  $("#resultado").html('<img src="imagenes/loading/ajax-loader.gif" />');
                                           
                        $.ajax({
                              type: "POST",
                              url: "comprobar.php",
                              data: "b="+consulta,
                              dataType: "html",
                              error: function(){
                                    alert("Error petición ajax");
                              },
                              
success: function(data){  
        
$("#resultado").html(data);        
n();
        
if (data == 1){
document.seleccionar.modificar.style.visibility = "visible"; 
}
}
                  });
                                           
             });
                                
      });
                          
});

-------------------------------------------------------------

<form name="seleccionar" id="seleccionar" action="modificar.php" method="post">
    <input type="int" required id="id" name="id" placeholder="Introduce ID..." value="" />
 <span id="resultado"></span>
    <input type="submit" id="modificar" name="modificar" value="Modificar" /><br><br/>  
</form>

Archivo 2 -- PHP :

<?php
      $user = $_POST['b'];
       
      if(!empty($user)) {
            comprobar($user);
      }
       
      function comprobar($b) {
   
   include("conexion_db.php");
   
   $query = mysqli_query($conexion, "SELECT * FROM formulario WHERE id = '".$b."'");        
   
            $contar = mysqli_num_rows($query);
                
            if($contar == 0){
                  echo "<span><img src=\"imagenes\web\action_delete.png\"></span>";    
            }else{
                  echo "<span><img src=\"imagenes\web\action_check.png\"></span>";
            }
   
   echo json_encode($contar);
      }     
?>

Agradeceria si alguien puediera indicarme el motivo por el que el input submit no se visualiza cuando se ejecuta la condición. Gracias de antemano.

A. Cedano
  • 86,578
  • 19
  • 122
  • 221
Joel
  • 21
  • 1
  • 1
  • 3
  • 1) ¿Tienes una función llamada `n();`? Al menos veo que la estás llamando... ¿cuál es su código? 2) ¿Los asteriscos son parte del código: `**if (data == 1){ document.seleccionar.modificar.style.visibility = "visible"; }** ` 3) Puedes cambiar la visibilidad del submit directamente: `$('#modificar').show();` – A. Cedano Aug 30 '17 at 03:07
  • 4) En la parte de PHP yo no haría `echo` de otra cosa que del objeto json, introduciendo en él todos mis datos. Luego, en la parte de jQuery muestro lo que tenga que mostrar. O sea: `if($contar == 0){ $datos=array("contar"=>$contar, "img"=>"action_delete.png"); }else{ $datos=array("contar"=>$contar, "img"=>"action_check.png"); } echo json_encode($datos);` con el resultado obtenido actúo entonces del lado de jQuery/HTML. – A. Cedano Aug 30 '17 at 03:28
  • 1) La función n(); es utilizada aqui $("#resultado").delay(100).queue(function(n) { para realizar la búsqueda. 2) Los asteriscos los he escrito por error al intentar poner en negrita esa parte del código. Corregido. 3) He probado substituir el código por $('#modificar').show(); pero sucede lo mismo. – Joel Aug 30 '17 at 03:29
  • Revisa mi anterior comentario, o sea el punto 4. Creo que debes retornar desde el PHP un objeto json con **toda** tu información y leer ese objeto en jQuery para actuar en consecuencia. Hacer echo de la imagen y luego del objeto json en la parte de PHP es muy probable que te de problemas. E cualquier caso, haz un `console.log(data)` para verificar que estarás recibiendo bien los datos. – A. Cedano Aug 30 '17 at 03:32
  • Entiendo lo que quieres decir pero no sabria como enfocar los resultados obtenidos desde PHP en jQuery. He comprobado que los datos se reciben correctamente: {"contar":0,"img":"action_delete.png"} si no hay equivalencias en la BBDD y {"contar":1,"img":"action_check.png"} si si que hay. – Joel Aug 30 '17 at 06:15

2 Answers2

3

EDIT

He reproducido el escenario y el código funciona, excepto en los casos en que introducía el valor 0 en el input o cuando el mismo se quedaba en blanco. El motivo es que, en el antiguo código PHP, en esos casos se creaba un objeto JSON inválido y la petición Ajax retornaba un parse error. Para evitarlo, he mejorado el código PHP, obligándolo a crear siempre un json válido. Verás que, si no se producen valores, el código PHP retornará un json con los valores establecidos a null. Tú puedes cambiar esos valores por otros, que te pueden servir para manejar los nulos. Es algo en lo que no se piensa, sin embargo, el usuario puede introducir cualquier cosa en el input y hay que manejarla adecuadamente.

También he mejorado la forma de obtener los valores del objeto json, usando: data.img y data.contar.

En la parte HTML he dedicado un diva la imagen, porque en las pruebas, la imagen se me colocaba encima del input, al estarla poniendo en el mismo elemento. Ese cambio lo puedes obviar si lo deseas así.

Mi console.log arroja datos como estos:

{contar: "1", img: "action_check.png"}

O bien:

{contar: "0", img: "action_delete.png"}

O bien, cuando se introduce 0 en el input o se deja en blanco:

{contar: null, img: null}

Y muestra imágenes de prueba que he puesto para cada caso.

Si no te funciona, entonces sería un problema de ruta del archivo que pones en la url de la petición Ajax o por otro motivo ajeno al código.

Debajo, dejo el código modificado.


Redactado una respuesta me permitiré hacer algunas indicaciones sobre el código.

  1. $(document).ready(function() {... es obsoleto desde jQuery 3 (ver esta pregunta). Lo cambiaremos por $(function() {....
  2. Manejar las peticiones Ajax solamente con success: function(data){ ... no es recomendable y success a su vez también es obsoleto. Lo cambiaremos por done e incluiremos controlar el código en caso de que la petición falle, usando fail.
  3. Aplicaremos cambios usando el id del elemento.
  4. Como decía en los comentarios, haremos echo una sola vez con todos nuestros datos y luego leeremos el JSON desde jQuery y actuaremos en consecuencia. Haciendo esto aplicamos una regla básica del uso de jQuery/Ajax: hacer peticiones al servidor en background y manejar la respuesta desde la misma página en que fueron hechas sin tener que refrescar. El problema de hacer echo varias veces en el PHP es que no tendrás un control estricto de la respuesta que vas a recibir.

HTML / JS

$(function() { 

  $("#modificar").hide();
  var consulta;
  $("#id").focus();                                                     
  $("#id").keyup(function(e){
         consulta = $("#id").val();
         $("#resultado").delay(100).queue(function(n) {       
              $("#resultado").html('<img src="imagenes/loading/ajax-loader.gif" />');

                    var request = $.ajax({
                      url: "comprobar.php",
                      method: "POST",
                      data: "b="+consulta,
                      dataType: "json"
                    });

                    request.done(function( data ) {
                        console.log(data);
                        img=data.img;
                        contar=data.contar;
                        imagen='<img src="imagenes/web/'+img+'/">';
                        $("#imagen").html(imagen);                               

                        n();

                        if (contar == 1){

                              $("#modificar").show();

                        }else{

                              $("#modificar").hide();

                        }

                    });

                    request.fail(function( jqXHR, textStatus ) {
                      alert( "Error petición Ajax: " + textStatus );
                    });         
        }); 
    });    
});

<form name="seleccionar" id="seleccionar" action="modificar.php" method="post">
<input type="int" required id="id" name="id" placeholder="Introduce ID..." value="" />
<span id="resultado"></span>
<input type="submit" id="modificar" name="modificar" value="Modificar" /><br><br/>  
<div id="imagen"></div> 
</form>

PHP

<?php
      $user = $_POST['b'];

      if(!empty($user)) {

            $datos=comprobar($user);

      }else{
            /*
                *Hay que prever que no se envíen datos
                *construir un json que sea válido
                *los valores pueden ser otros
            */
            $datos=array("contar"=>null, "img"=>null); //Aquí puedes poner en vez de null un nombre de imagen válido: "img"=>"una_imagen.png"

      }

      /*Imprimimos el json*/
      header('Content-Type: application/json');
      echo json_encode($datos);


      function comprobar($b) {
            include("conexion_db.php");

           $query = mysqli_query($conexion, "SELECT * FROM formulario WHERE id = '".$b."'");        

           $contar = mysqli_num_rows($query);

           if($contar == 0){ 

                $datos=array("contar"=>$contar, "img"=>"action_delete.png"); 

           }else{ 

                $datos=array("contar"=>$contar, "img"=>"action_check.png"); 
           } 

           return $datos;

      }     
?>

Nota: Esta consulta "SELECT * FROM formulario WHERE id = '".$b."'" es vulnerable a Inyección SQL, para dar seguridad al código, considera el uso de consultas preparadas: "SELECT * FROM formulario WHERE id = ?" pasando aparte el valor de $b usando métodos existentes para ello.

A. Cedano
  • 86,578
  • 19
  • 122
  • 221
  • Muy amable por tu tiempo. Agradezco muchisimo tu ayuda. En el código HTML/JS aparece un SyntaxError: illegal character en la linea: imagen=''; aparentemente el error estarua en: '+obj.img+' – Joel Aug 30 '17 at 17:50
  • Es que copié eso de tu PHP. Debería quitarse el error escribiéndolo así: `imagen='';` es que en tu PHP los separadores de carpetas en la ruta de imagen estaban escritos al revés: `**\**` – A. Cedano Aug 30 '17 at 18:06
  • Ahora no detecta el error de sintaxis tras corregir en el path los separadores. Pero cuando escribo un dato en el input type="int" aparece el siguiente mensaje: Error petición Ajax: parsererror – Joel Aug 30 '17 at 19:10
  • @Joel quizá esto no sea necesario: `obj = JSON.parse(data);` y puedas acceder directamente a los valores devueltos así: `imagen=data["img"]; contar=data["contar"];` en vez de usar `obj.img` y `obj.contar` Intenta así y comenta la línea de `obj = JSON.parse(data);` . Si no funciona, haz `console.log(data);` y comenta el resultado. – A. Cedano Aug 30 '17 at 19:19
  • He comentado la linea `obj = JSON.parse(data);` y substituido `imagen='';``por `imagen=data["img"];` y `contar=obj.contar;` por `contar=data["contar"];` pero sigue apareciendo el mismo mensaje de error que antes. He añadido lo siguiente `request.fail(function( jqXHR, textStatus, data ) { console.log(data);` para revisar la salida y aparece esto: – Joel Aug 30 '17 at 22:48
  • SyntaxError: Error de sintaxis { [functions]: , __proto__: { [functions]: , __proto__: { [functions]: , __proto__: { }, message: "", name: "Error" }, message: "", name: "SyntaxError" }, description: "Error de sintaxis", message: "Error de sintaxis", name: "SyntaxError", number: -2146827286, stack: "SyntaxError: Error de sintaxis at ajaxConvert (http://localhost/formulario/jquery.tablesorter/jquery-latest.js:8754:8) – Joel Aug 30 '17 at 23:57
  • @Joel he editado la respuesta con algunas indicaciones. He reproducido el caso, probado el código y funciona. Prueba con el código como aparece ahora (lo he modificado). Debería funcionar también para ti. – A. Cedano Aug 31 '17 at 04:42
  • Perfectisimo !!! El campo submit aparece y desaparece en función de la validación que se realiza contra la BBDD. Mil gracias @A. Cedano !!!! Un error de sintaxis no me permitia visualizar las imágenes. He cambiado esto `imagen='';` por esto `imagen='';`. Cuando el valor del campo `input type=int` es null o "0" aparece por pantalla el icono de link roto debido a que intenta mostrar una imagen ubicada en la ruta `` (sucede en Firefox y IE). Revisaré el caso. Lo dicho mil gracias por tu tiempo. Saludos – Joel Aug 31 '17 at 06:57
  • @Joel, lo último que comentas no tiene que ver con el navegador, si te fijas bien en la respuesta editada, para evitar el `parse error` cuando el valor sea `0` o no haya datos, he forzado la respuesta de un json en el cual `img` es igual a `null` (está claramente indicado y comentado en el `else` del PHP). Si en lugar de `null` tu pones un nombre de imagen válido, en esos casos te mostrará esa imagen, como ocurre cuando el valor es igual a `1` o como ocurre cuando el valor es igual a `0`. – A. Cedano Aug 31 '17 at 10:41
  • Has pensado hasta en el más mínimo detalle. Efectivamente es como indicas. Modificando en el PHP `"img"=>null` por la imagen que quieras mostrar en el caso de que`"contar"=>null` aparece la imagen correctamente. Me obceque en el códgo HTML/JS y no revise el PHP pese a tus indicaciones de la edición. También me confundió el hecho de que en Chrome al haber valor null en el input no aparecía por pantalla el icono de link roto cosa que si sucedía en Firefox y IE. Una vez más, millones de gracias. Gratitud infinita !!!! – Joel Aug 31 '17 at 17:14
  • @Joel en cuanto al funcionamiento del sitio, sugiero que leas [¿Qué debo hacer cuando alguien contesta mi pregunta?](https://es.stackoverflow.com/help/someone-answers) – A. Cedano Sep 06 '17 at 06:21
0

Buenas, habría que ver cual es la funcionalidad de la funcion "n" , por si estas haciendo algo ahí que evite que continue la ejecución del codigo.

Como consejo, deberías asegurarte que el PHP devuelve lo que esperas, para eso, prueba con el console.log();

Mi propuesta de codigo es:

success: function(data){  
  console.log('Data que devuelves => '+data);             
  $("#resultado").html(data);                               
  n();  //Explicar que hace esta funcion??

  if (data == 1){
   $('#modificar').css('display','block');
  }
}

Suerte,