I have two selectpicker. One for city and other for towns. When citySelectpicker changes I load towns with AJAX.
There is no problem with this. When I try to get on change event on TownSelect nathing happens. TownSelect onchange not working.
But I refresh page. And directly change the townSelect Change event works. but before it I use CityChange it is not work.
index.php
<!DOCTYPE html>
<html lang="en" class="no-js">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css">
<link rel="stylesheet" href="css/bootstrap-select.css" />
<script src = "https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.bundle.min.js"></script>
<script src="js/bootstrap-select.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.bundle.min.js"></script>
<link rel="stylesheet" href="css/jquery-ui.css">
<?php
header("Cache-Control: no cache");
?>
</head>
<body>
<div class="cityList col-lg-3 col-md-6 col-sm-3">
<label for="citySelect2" class="labelsfilter ml-2">City</label>
<select class="selectpicker mb-3" id="citySelect2" name="citySelect2" data-width="100%" data-live-search="false" required="required">
<option value="">Select City</option>
<?php
$myQuery = "SELECT * FROM tessCityTable";
$statement = $konn->prepare($myQuery);
$statement->execute();
$results = $statement->fetchAll(PDO::FETCH_ASSOC);
if ($results){
foreach ($results as $result){
if (isset($cityID2)){
if ($cityID2 == $result['cityID']){
echo ('<option value="'.$result['cityID'].'" selected>'.$result['cityName'].'</option>');
}
else {
echo ('<option value="'.$result['cityID'].'">'.$result['cityName'].'</option>');
}
}
else {
echo ('<option value="'.$result['cityID'].'">'.$result['cityName'].'</option>');
}
}
}
?>
</select>
</div>
<div id="townList2" class="townList2 col-lg-3 col-md-6 col-sm-3">
<label for="townSelect2" class="labelsfilter ml-2">Town</label>
<select class="selectpicker mb-3 show-tick townSelect2" id="townSelect2" name="townSelect2[]" multiple="multiple" data-live-search="false" data-width="100%" data-selected-text-format="count">
<option value="0">Select Town</option>
</select>
</div>
</body>
</html>
<script>
$(document).ready(function() {
$('#townSelect2').selectpicker();
$("#citySelect2").change(function() {
var selectedCity = $(this).val();
$.ajax({
type: "POST",
url: "query.php",
data: 'keyword=' + selectedCity,
success: function(data) {
var response = JSON.parse(data);
$('.townList2').html(response.townList);
$('.townSelect2').selectpicker('refresh');
}
});
});
$('#townSelect2').on('changed.bs.select', function(e) {
//Nothing Happens
console.log("changed.bs.select event triggered");
console.log("e:", e);
});
$("#townSelect2").change(function() {
//Nothing Happens
console.log("changeEvent");
});
})
</script>
And query.php
if (!empty($_POST["keyword"])) {
$townList = "";
$cityID = $_POST['keyword'];
$myQuery = "SELECT * FROM tessTownTable WHERE cityID=:cityID";
$statement = $konn->prepare($myQuery);
$statement->bindParam(':cityID', $cityID);
$statement->execute();
$result = $statement->fetchAll(PDO::FETCH_ASSOC);
if (!empty($result)) {
$townList = $townList . '<label for="townSelect2" class="labelsfilter ml-2">İlçe</label>';
$townList = $townList . '<select class="selectpicker mb-3 show-tick townSelect2" id="townSelect2" name="townSelect2[]" multiple="multiple" data-live-search="false" data-width="100%" data-selected-text-format="count">';
$townList = $townList . '<option value="0">İlçe Seçiniz</option>';
foreach ($result as $town) {
$townList = $townList . '<option value="'.$town['townID'].'">'.$town['townName'].'</option>';
}
$townList = $townList . '</select>';
$konn = null;
$statement = null;
$response = array(
"townList" => $townList
);
$jsonResponse = json_encode($response);
echo $jsonResponse;
}
}
2
Answers
Here is an answer. But I really dont want to use obServer. but cant find any solution If I find anything without obServer I will update the answer.
Please check the Javascript part.
[TL:DR]:
swap
with
and use
instead of
You need to use event delegation in order to use an event on a dynamically added element like your
townSelect2
– select.Explanation:
If you attach an event handler for the
changed.bs.select
– event to all elements with the idtownSelect2
that event will get attached to all elements with the idtownSelect2
that are present in the DOM when the script is being loaded. That means, that you have to either attach the event again when you dynamically add an element to the DOM, like you do in your ajax success, or that you need to delegate the event to a parent element that in fact is present when your DOM loads.Also, you are returning a completed
<select>
ELement from your PHP endpoint, but you are inserting it in your current<select>
selemt with.html(...)
. You need to replace it, in order to prevent invalid HTML like this :