0

I've written a script using jQuery Ajax and PHP which should fetch data from a MySQL database and append the result as an <option> within a <select> element.

The code should work like this:

When the name in the text input changes, all options of class .modpick are removed from the <select> element. An Ajax call then connects to a PHP script which checks whether there is more than one record in the database with the same name. If not, another Ajax call connects to another PHP script which pulls the data from the database and echos it out as an <option> element. The Ajax callback then appends the data from the PHP script to the <select> element.

The problem I'm having is that sometimes the <option> element is appended twice, so when you open the <select> element it displays the same <option> twice. What is really confusing is that this doesn't happen all the time - only occassionally.

I can't figure out why this is happening, especially as it doesn't happen every time, nor can I identify whether it's a problem with the jQuery or the PHP. Any help would be greatly appreciated.

The code:

jQuery:

$(document).on('change', "#uploadname", function () {
    uploadname = $(this).val();
    $('.modpick').remove();
    $.ajax({
        url: "uploadnames.php",
        type: "POST",
        data: {
            uploadname: uploadname
        },
        success: function (data) {
            $('#checkulinputs').html(data);
            uploademailcheck = $('#emailupcheckinput').val();

            if (uploademailcheck == 'nochoose') {
                uploademail = '';
                $('#ulemailcheck').slideUp();
                $.ajax({
                    url: "uploadnamesmodules.php",
                    type: "POST",
                    data: {
                        uploadname: uploadname
                    },
                    success: function (data) {
                        $(data).appendTo($('#uploadmoduleselect'));
                    }
                });
            }
        }
    })
})

PHP:

include_once('../../dbconnect.php');

$name = mysqli_real_escape_string($conn, $_POST['uploadname']);
$query = "SELECT * FROM marking_assignments WHERE name = '$name' ORDER BY unit ASC";
$details = $conn->query($query);

while ($row = $details->fetch_assoc()){
 $modnamequery = "SELECT mod_name FROM modules WHERE module = '" . $row['unit'] . "'";
 $modname = $conn->query($modnamequery);
 while ($line = $modname->fetch_assoc()){
  $descrip = $line['mod_name'];
  }

echo '<option  value="' . $row['unit'] . '" id="m' . $row['unit'] . '" class="modpick">' . $descrip . '</option>'; 

}

HTML (After query has been run - note the two identical <option> elements):

<form id="uploadfeedbackform" method="POST" action="uploadfeedback.php">
  <input type="text" class="inputs" name="upload_name" id="uploadname" placeholder="Enter Student Name" />

  <div id="checkulinputs"></div>
  <div id="ulemailcheck" class="emailchecker"></div>

  <select id="uploadmoduleselect" name="uploadmodules">
     <option  value="choose" class="choosemod">Select Module</option>
     <option value="405" id="m405" class="modpick">4.05 Managing Health & Safety at Work</option>
     <option value="405" id="m405" class="modpick">4.05 Managing Health & Safety at 
  </select>
 </form>

1 Answer 1

1

Seems to me that your change handler can be called multiple times, leading to multiple ajax requests which (quite rightly) fire their success callbacks. Ajax requests will just queue up rather than replacing the previous request, leading to a possible queue of pending callbacks.

You can store the ajax request in a variable and abort() the request in the event that your handler somehow gets called twice.

Example:

var myRequest;

//in your change handler...
if (myRequest)
{
    myRequest.abort();
}
myRequest = $.ajax({...});

This way there will only be one active ajax request at a time, and only one success callback that is pending.

Sign up to request clarification or add additional context in comments.

1 Comment

No problem, glad to have helped :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.