skip to Main Content

I have a <select> with only one option, i want to get the rest of the options from a database using PHP and then populate said <select> with the PHP result using AJAX.

Unfortunately my code is not working, im not surprised as im new to both AJAX and jQuery but i dont get any errors to guide myself through the issue.

The PHP works as expected because its used in another part of the site and i have no issues with it so my error must be in the AJAX (no big surprise here).

Below my HTML:

<select class="custom-select my-1 mr-sm-2" id="producto" name="producto" required>
    <option disabled selected value>Elegir...</option>
</select>

Below my AJAX code:

<script type="text/javascript">
$(document).ready(function() {
    $("#producto").click(function() {
        $.ajax({
            url: 'fetch_lista_productos_compra.php',
            type: 'get',
            success: function(data) {
                $("#producto").append(data);
            }
        });
    });
});
</script>

Below my PHP code:

<?php 

require $_SERVER['DOCUMENT_ROOT'].'/testground/php/db_key.php';

$conn = mysqli_connect($servername, $username, $password, $dbname);

$sql_query = mysqli_query($conn, "SELECT * FROM productos WHERE disponibilidad = 'disponible'");

while ($row = mysqli_fetch_assoc($sql_query)) {
    $titulo = $row['titulo'];
    echo <<<EOT
    <option value="$titulo">$titulo</option>n
EOT;
}
?>

As always any kind of help is greatly appreacited and thanks for your time.

IMPORTANT EDIT

<select> has a duplicated id, perhaps i should i have stated this from the start as i know think thats whats causing my issue.

The fact is that in this <form> the selects are created dynamically on user request. They click on Add product and a new select with the products avaiable is created, i know the id/name of said input must have [ ] (id="producto[]") for it to be converted into an array but i dont know how to make the AJAX deal with this dynamically created reapeated selects issue. I apologise for this belated aclaration i realise now it is of the utmost importance.

4

Answers


  1. Chosen as BEST ANSWER

    As it turns out the code in the question was actually working properly, the problem was not the code itself but the fact that, as i stated (sadly on a later edit and not right from the start) in the question, there where more than one <select> using the same id, therefore everytime the AJAX was executed the result was appended to the first <select> only, and it was appended over and over again everytime i clicked it, my solution was unifiying both the AJAX that populated the <select> and the jQuery that created the said dynamic <select>'s all in one script thus solving all of my issues at once.

    Below my jQuery/AJAX code:

    <script type="text/javascript">
        $(document).ready(function() {
            var max_fields      = 10;
            var wrapper         = $(".input_fields_wrap");
            var add_button      = $(".add_field_button");
            var x = 0;
            $(add_button).click(function(e) {
                e.preventDefault();
                $.ajax({
                    url: '/testground/php/fetch_lista_productos_compra.php',
                    type: 'get',
                    success: function(data) {
                        if(x < max_fields) {
                            x++;
                            var html = '';
                            html += '<div class="form-group row" id="inputFormRow" style="margin-bottom: 0px;">';
                            html += '<label class="col-3 col-form-label font-weight-bold">Producto</label>';
                            html += '<div class="col-7">';
                            html += '<select class="custom-select my-1 mr-sm-2" id="producto" name="producto[]" required>';
                            html += '<option disabled selected value>Elegir...</option>';
                            html += data;
                            html += '</select>';
                            html += '</div>';
                            html += '<div class="col-1 my-auto" style="padding: 0px 0px 0px 0px;">';
                            html += '<button id="removeRow" type="button" class="btn btn-danger">X</button>';
                            html += '</div>';
                            html += '</div>';
                            $(wrapper).append(html);
                        }
                    }
                });
            });
    
            $(document).on('click', '#removeRow', function () {
                $(this).closest('#inputFormRow').remove(); x--;
            });
        });
    </script>
    

    I want to thank everyone that took the time to help me out with this Swati, Serghei Leonenco and Scaramouche, this community is truly amazing.


  2. <script type="text/javascript">
    $(document).ready(function() {
        $("#producto").change(function() {
            $.ajax({
                url: 'fetch_lista_productos_compra.php',
                type: 'get',
                success: function(data) {
                   console.log(data)
    // $("#producto").append(data);
                }
            });
        });
    });
    </script>`enter code here`
    
    try run this and check in your console that weather you are receiving the data from your php or not.
    
    Login or Signup to reply.
  3. You have to edit your response from this:

    <?php 
    
    require $_SERVER['DOCUMENT_ROOT'].'/testground/php/db_key.php';
    
    $conn = mysqli_connect($servername, $username, $password, $dbname);
    
    $sql_query = mysqli_query($conn, "SELECT * FROM productos WHERE disponibilidad = 'disponible'");
    
    while ($row = mysqli_fetch_assoc($sql_query)) {
        $titulo = $row['titulo'];
        echo <<<EOT
        <option value="$titulo">$titulo</option>n
    EOT;
    }
    ?>
    

    To this:

        <?php 
    
        require $_SERVER['DOCUMENT_ROOT'].'/testground/php/db_key.php';
    
        $conn = mysqli_connect($servername, $username, $password, $dbname);
    
        $sql_query = mysqli_query($conn, "SELECT * FROM productos WHERE disponibilidad = 'disponible'");
    
        $response = '';
    
        while ($row = mysqli_fetch_assoc($sql_query)) {
            $titulo = $row['titulo'];
            $response .= '<option value="' .$titulo . '">' . $titulo . '</option>'; //Concatenate your response
        }
    
        echo $response;
    
    ?>
    

    But i suggest to use JSON to get a response and parse it on client side.
    You can do this by pushing all values in to response array and use json_encode(). At the end you get straight response from the server with just a values, and append thous values whatever you need on client side.

    Update
    Also you append data to your existing select options. You can just add thous by editing this:

    <script type="text/javascript">
    $(document).ready(function() {
        $("select#producto").focus(function() { //Change to on Focus event
            $.ajax({
                url: 'fetch_lista_productos_compra.php',
                success: function(data) {
                    $("select#producto").html(data); //Change all html inside the select tag 
                }
            });
        });
    });
    </script>
    

    Test result:

    $('select#options').focus(function(){
        alert("Hello this is a select trigger");
    });
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <select id="options">
        <option value="test">Test</option>
    </select>
    Login or Signup to reply.
  4. Please don’t construct your html on the server, try to just send the raw data and then construct the html client-side, it’s better that way and it leaves room for changing the view later without much coupling.

    That said, instead of doing:

    while ($row = mysqli_fetch_assoc($sql_query)) {
        $titulo = $row['titulo'];
        echo <<<EOT
        <option value="$titulo">$titulo</option>n
    EOT;
    }
    

    just do

    $rows = [];
    while ($row = mysqli_fetch_assoc($sql_query)) {
        $rows[] = $row;
    }
    
    //this is your best bet when sending data from PHP to JS,
    //it sends the rows as JSON-like string,
    //which you'll parse to an array in the client
    echo json_encode($rows); 
    

    then in the client

    $.ajax({
        url: 'fetch_lista_productos_compra.php',
        type: 'get',
        success: (data /*json-like string*/) => {
            const dataAsArray = JSON.parse(data);
    
            $.each(dataAsArray, (index, row) => {
                 //now HERE you construct your html structure, which is so much easier using jQuery
                let option = $('<option>');
                option.val(row.titulo).text(row.titulo);
                $("#producto").append(option);
            });
        }
    });
    

    Regarding your edit about several selects

    I don’t have access to your server of course so I’m using a mock service that returns JSON. IDs are dynamically generated and all data loading occurs asynchronously after you click on the button.
    Try using your url and modify the success function according to your html.

    $(document).ready(function() {
        $('#add').click(() => {
          //how many so far...?
          let selectCount = $('select.producto').length;
          
          const select = $('<select class="producto">');
          select.attr('id', `producto${selectCount + 1}`);
          
          //then we fetch from the server and populate select
          $.ajax({
            url: 'https://jsonplaceholder.typicode.com/posts',
            type: 'get',
            success: function(data) {
              data.forEach((d) => {
                const option = $('<option>');
                option.val(d.id).text(d.title);
                select.append(option);
              });
            }
          });
          
          document.body.appendChild(select[0]);
        });
    });
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    
    <button id='add'>Add product</button><br>
    <!--<select class="custom-select my-1 mr-sm-2" id="producto" name="producto" required>
        <option disabled selected value>Elegir...</option>
    </select>-->

    HIH

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search