Formulario creado por PHP Ajax que no se envía

Tengo un conjunto de tres cuadros combinados (menús desplegables) que están llenos de PHP con valores de una base de datos. Probé estos cuadros combinados cambiando el botón Enviar repetido a type='submit'y cargando la propia página php. Trabajan sin problemas de esta manera.

Sin embargo, cuando cargo la página Ajax, el botón de envío se niega a activar la función Ajax. He probado la página creando un conjunto de cuadros combinados estáticos con html y, en este caso, el Ajax se activa sin problemas. Sin embargo, el uso de los cuadros combinados creados por PHP no activa el Ajax.

Espero que alguien pueda arrojar algo de luz sobre cuál es el problema con mi código.

El HTML y jQuery:

<div id="gallery_container">
    <ul class="new_arrivals_gallery"></ul>
    <div class="pagination"></div>
</div>
<script type="text/javascript" src="js/libs/jquery-1.6.1.min.js"></script> 
<script>

$(document).ready(function() {

    function loadData(imgFamily, imgClass, imgGender){
        $.ajax
        ({
            type: "GET",
            url: "filter_test.php",
            data: {imgFamily:imgFamily, imgClass:imgClass, imgGender:imgGender},
            success: function(data) {
                $("#gallery_container").html(data);
            },
        });
    }
    loadData(1);  // For first time page load default results

    //Bind keypress event to Ajax call
    $('.filter').keypress(function(e) {
        if(e.keyCode == 13) {
            var imgFamily = $('#imgFamily').attr('value');
            var imgClass = $('#imgClass').attr('value');
            var imgGender = $('#imgGender').attr('value');
            //Fetch the images
            loadData(imgFamily, imgClass, imgGender);
        }
    });

    //Bind the click event to Ajax call on submit
    $("#submit").click(function(){
        var imgFamily = $('#imgFamily').attr('value');
        var imgClass = $('#imgClass').attr('value');
        var imgGender = $('#imgGender').attr('value');
        //Fetch the images
        loadData(imgFamily, imgClass, imgGender);
    })
});

PHP (aunque no creo que el problema esté aquí):

Solo muestro un cuadro combinado para ahorrar espacio, y dado que todos son iguales

// Queries for combo boxes
$imgFamily_query = "SELECT DISTINCT imgFamily FROM images WHERE $clause";
$imgClass_query = "SELECT DISTINCT imgClass FROM images WHERE $clause";
$imgGender_query = "SELECT DISTINCT imgGender FROM images WHERE $clause";


// Create the form and combo boxes
echo "<form name='refine' action=''>
        <fieldset><legend>Refine Results</legend>";

    // imgFamily combo box
    if($imgFamily_result = mysql_query($imgFamily_query))  {
      if($imgFamily_success = mysql_num_rows($imgFamily_result) > 0) {
        // Start combo-box
        echo "<label for='imgFamily' id='imgFamily_label'>Choose a family</label>\n
            <select class='filter' id='imgFamily' name='imgFamily'>\n
            <option value='1'></option>\n";
        // For each item in the results...
        while ($imgFamily_row = mysql_fetch_array($imgFamily_result))
          // Add a new option to the combo-box
          echo "<option value='$imgFamily_row[imgFamily]'>$imgFamily_row[imgFamily]</option>\n";
        // End the combo-box
        echo "</select>\n";
      } else { echo "No results found."; }
    } else { echo "Failed to connect to database."; }


    // Add a submit button to the form
    echo "</fieldset>
        <fieldset><input type='button' name='submit' value='submit' id='submit'></fieldset>
    </form>";

Muchas gracias por la ayuda.

preguntado el 27 de agosto de 11 a las 21:08

A mí me parece un código que huele ... Debería publicar sólo el código relevante que crea que causa el problema. Es difícil seguir tu código. -

¿Podrías explicar qué quieres decir con "cuando cargo la página Ajax" porque no es tu problema que NO se esté cargando cuando haces clic en enviar? Además, ¿ha intentado también vincular una función simple, como "alert ('test');" al oyente para que sepa que funciona? -

@Callie Lo que quiero decir con "cuando cargo la página Ajax" es cuando cargo la página que contiene el Ajax en lugar de la página que contiene el PHP. No he intentado colocar ninguna función de alerta en mi código. ¿Dónde sugieres que intente eso? -

¿Solo se aceptaron 2 respuestas de las últimas 9 preguntas? -

@Majid Fouladpour Si echas un vistazo a dichas preguntas, verás por qué. Estas preguntas no fueron respondidas de manera completa. Siempre entendí que la respuesta aceptada era una indicación de una respuesta correcta y completa. -

2 Respuestas

Esto es lo que está sucediendo (básicamente una reformulación de lo que dice @GolezTrol):

  1. Tu página termina de cargarse
  2. loadData (1) se ejecuta, pero debido a que es una llamada asincrónica, la ejecución continúa antes de que se obtengan los elementos del formulario.
  3. jquery ejecutado $('.filter').keypress(function(e) pero todavía no hay elementos con esa clase, por lo que no se realiza ninguna vinculación.
  4. $("#submit").click(function(){ tiene el mismo destino, no tenemos ningún elemento con submit id todavía.
  5. llega la respuesta a la llamada ajax y success La función agrega los elementos del formulario a gallery_container, pero no hay ataduras.

Lo que debe hacer es llamar a las funciones de enlace de eventos cuando los elementos respectivos se hayan agregado al dom; así que deberías moverlos a después $("#gallery_container").html(data);:

$(document).ready(function() {

    function loadData(imgFamily, imgClass, imgGender){
        $.ajax
        ({
            type: "GET",
            url: "filter_test.php",
            data: {imgFamily:imgFamily, imgClass:imgClass, imgGender:imgGender},
            success: function(data) {
                $("#gallery_container").html(data);
                //Bind keypress event to Ajax call
                $('.filter').keypress(function(e) {
                    if(e.keyCode == 13) {
                        var imgFamily = $('#imgFamily').attr('value');
                        var imgClass = $('#imgClass').attr('value');
                        var imgGender = $('#imgGender').attr('value');
                        //Fetch the images
                        loadData(imgFamily, imgClass, imgGender);
                    }
                });

                //Bind the click event to Ajax call on submit
                $("#submit").click(function(){
                    var imgFamily = $('#imgFamily').attr('value');
                    var imgClass = $('#imgClass').attr('value');
                    var imgGender = $('#imgGender').attr('value');
                    //Fetch the images
                    loadData(imgFamily, imgClass, imgGender);
                });
            }
        });
    }
    loadData(1);  // For first time page load default results
});

Respondido 28 ago 11, 02:08

¡Hermosa! Siempre es agradable cuando alguien explica lo que está sucediendo para que yo pueda entender mejor cuando me enfrente a problemas futuros. El único problema ahora es averiguar a quién darle la respuesta aceptada ... - Stefmikhail

Como dije esto is basado en la respuesta de GolezTrol (la más corta antes de las ediciones). Entonces, diría que la respuesta aceptada está seleccionada correctamente en este momento. - Majid Fouladpour

Eso es muy amable de tu parte. Una pregunta rápida si no le importa. Lo que hace el 1 in loadData(1) ¿significar? Además, ¿qué pasa con el e in function(e) y data in .html(data)? Aún no he podido descifrar eso. - Stefmikhail

Hummm ... ahora que lo mencionas, en realidad loadData(1) toma tres parámetrosimgFamily, imgClass, imgGender), cuando lo llamamos así, dentro de la función imgFamily tendrá un valor de 1, y las otras dos variables imgClass y imgGender será indefinido, por lo que en realidad está llamando a su script php will una url similar a filter_test.php?imgFamily=imgFamily&imgClass=undefined&imgGender=undefined. La razón por la que eso no causa ningún problema es porque no está accediendo a esos parámetros dentro de su código php. e es el evento de pulsación de tecla que le estamos pasando a la función. - Majid Fouladpour

Y también debes data es lo que la llamada ajax recibe del servidor (el html que genera el script php). - Majid Fouladpour

Inserta el formulario y, por lo tanto, sobrescribe los elementos a los que está vinculado el evento de envío. Debe volver a ejecutar el código que vincula los eventos después de haber insertado el nuevo formulario.

Una forma más limpia sería devolver un objeto JSON o XML que contenga solo la información modificada y actualizar su formulario actual en lugar de insertar uno completamente nuevo, pero eso será más trabajo.

function loadData(imgFamily, imgClass, imgGender){
    $.ajax
    ({
        type: "GET",
        url: "filter_test.php",
        data: {imgFamily:imgFamily, imgClass:imgClass, imgGender:imgGender},
        success: function(data) {
            $("#gallery_container").html(data);

            bindEvents(); // <---- Call it here
        },
    });
}

// Separate function
function bindEvents()
{
    //Bind keypress event to Ajax call
    $('.filter').keypress(function(e) {
        if(e.keyCode == 13) {
            var imgFamily = $('#imgFamily').attr('value');
            var imgClass = $('#imgClass').attr('value');
            var imgGender = $('#imgGender').attr('value');
            //Fetch the images
            loadData(imgFamily, imgClass, imgGender);
        }
    });

    //Bind the click event to Ajax call on submit
    $("#submit").click(function(){
        var imgFamily = $('#imgFamily').attr('value');
        var imgClass = $('#imgClass').attr('value');
        var imgGender = $('#imgGender').attr('value');
        //Fetch the images
        loadData(imgFamily, imgClass, imgGender);
    })
}

$(document).ready(function() {

    loadData(1);  // For first time page load default results

    bindEvents(); // <---- And here (where your code originally was).
});

Respondido 28 ago 11, 02:08

¿Cómo haría yo para hacer eso? ¿Debo solo envolver la llamada Ajax en la función de preparación del documento? - Stefmikhail

Pon el código que realiza $("#submit").click ... en una función separada. Puede llamar a esa función desde .ready, y después de procesar la solicitud Ajax. - GolezTrol

Lo siento, no te sigo. ¿Alguna posibilidad de que puedas editar tu respuesta con un ejemplo? - Stefmikhail

Hecho. Se movió el código de inicialización a la función bindEvents, que se llama en dos lugares. También movió la función loadData, ya que no es necesario declararla dentro del controlador .ready. - GolezTrol

Si ambos funcionan, ambos están bien. Pero .success puede ser mejor, porque ese es el lugar donde modifica el html, por lo que es el único momento en el que necesita volver a vincular los eventos. También puede optar por agregar un <script> elemento en el html devuelto. Esto también se ejecutará en la inserción. Pero elegiría la solución que te di. - GolezTrol

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.