11522 sujets

JavaScript, DOM et API Web HTML5

Bonjour,

quand j'essaie de rentrer dans l'événement change() d'une liste déroulante dynamique, il n'exécute pas le code qui se trouve à l'intérieur.

Il n'intercepte pas l'event suivant : $('#country-'+$('#COUN_ID').val()).change(function(event){});

voici mon code javascript/jQuery :


(function($){
    var postcodes_table = {};
     
    $("#post_codes select").each(function(){
        // Pour éviter de réutiliser le selecteur tout le temps
        var select_postcode = $(this);
 
        postcodes_table[select_postcode.attr('id')] = select_postcode;
 
        select_postcode.remove();
    });
 
    $('#COUN_ID').change(function(event){
        var country_id = $(this).val();
 
        if (country_id == 0)
        {
            $("#post_codes").hide();
        }
        else
        {
            $("#post_codes").show();
 
            $("#post_codes").empty().append(postcodes_table['country-'+country_id]);
        }
    }).trigger('change');
 
    var cities_table = {};
 
    $("#cities select").each(function(){
        var select_city = $(this);
 
        cities_table[select_city.attr('id')] = select_city;
 
        select_city.remove();
    });
     
    $('#country-'+$('#COUN_ID').val()).change(function(event){
        var postal_code_id = $(this).val();
 
        if (postal_code_id == 0)
        {
            $("#cities").hide();
        }
        else
        {
            $("#cities").show();
 
            $("#cities").empty().append(cities_table['postcode-'+postal_code_id]);
        }
    }).trigger('change');
})(jQuery);


Voici le code HTML :


<!-- Registration Form -->
<div class="row">
    <div class="col-lg-4 offset-lg-4 bg-light rounded register-class" id="register-box">
        <h2 class="text-center mt-2">Register</h2>
        <form action="" method="post" role="form" class="p-2" id="register-form">
            <div class="form-group countries" id="countries">
                <select name="COUN_ID" id="COUN_ID" class="form-control">
                    <option value="0">Sélectionnez un pays ...</option>
                    <?php foreach ($countries as $country): ?>
                        <option value="<?= $country->COUN_ID; ?>"<?= $country_id == $country->COUN_ID ? ' selected' : ''; ?>><?= $country->COUN_TITLE; ?></option>
                    <?php endforeach ?>
                </select>
            </div>
            <div class="form-group postcodes" id="post_codes">
                <?php foreach ($postcodesByCountry as $countryId => $postalCodes): ?>
                    <select name="POST_ID" id="country-<?= $countryId; ?>" class="form-control">
                        <option value="0">Sélectionnez un code postal ...</option>
                        <?php foreach ($postalCodes as $postalCodeId => $postalCodeName): ?>
                            <option value="<?= $postalCodeId; ?>"<?= $postcode_id == $postalCodeId ? ' selected' : ''; ?>><?= $postalCodeName; ?></option>
                        <?php endforeach ?>
                    </select>
                <?php endforeach ?>
            </div>
            <div class="form-group cities" id="cities">
                <?php foreach ($citiesByCountry as $postCodeId => $towns): ?>
                    <select name="CITY_ID" id="postcode-<?= $postCodeId; ?>" class="form-control">
                        <option value="0">Sélectionnez une ville ...</option>
                        <?php foreach ($towns as $townId => $townName): ?>
                            <option value="<?= $townId; ?>"<?= $city_id == $townId ? ' selected' : ''; ?>><?= $townName; ?></option>
                        <?php endforeach ?>
                    </select>
                <?php endforeach ?>
            </div>
            <div class="form-group">
                <input type="submit" name="register-btn" id="register-btn" value="Inscription" class="btn btn-primary btn-block">
            </div>
        </form>
    </div>
</div>


Avez-vous une idée à propos du fait que l'événement change() ne se déclenche pas ?

Est-ce possible de déclencher un event sur un sélecteur dont le nom est dynamique (ex : country-1, country-2, ...) ?

Merci d'avance

Bonne journée
Thierry
Modérateur
Bonjour,

Déjà, est-ce que le code php a bien généré le code html que tu espères ? (il faut regarder le code html généré dans ton navigateur).

Amicalement,
Bonsoir à vous,

merci pour votre réponse.

En effet, le code PHP est bien généré.

Je n'ai aucun erreur javascript. Je ne vois aucune erreur dans la console.

En fait, quand je sélectionne les pays, il intercepte bien l'événement change pour afficher les codes postaux par pays.

Par contre, quand je sélectionne un code postal, il n'intercepte pas le change sur les codes postaux et n'affiche donc pas les villes par code postal.

La seule différence, c'est que l'id de la liste déroulante des codes postaux est un id dynamique par rapport à celui des pays qui est une chaîne de caractères.

Encore merci pour votre aide.

Bon dimanche à vous,
Thierry
Modérateur
Bonjour,

Il faudra un exemple minimal avec les tableaux php $countries, $postcodesByCountry, et $citiesByCountry (disons 2 pays, 2 ou 3 codes postaux, et les villes correspondantes) pour pouvoir tester.

Et aussi les valeurs initiales de $country_id, $postcode_id, et $city_id.

Amicalement,
Bonjour,

Tout d'abord, merci pour votre réponse.

voici donc mon code :

Code javascript/jQuery :


(function($){
    // Gestion des codes postaux par pays
    var postcodes_table = {};

    $("#post_codes select").each(function(){
        var select_postcode = $(this);
        
        postcodes_table[select_postcode.attr('id')] = select_postcode;
        select_postcode.remove();
    });

    $('#COUN_ID').change(function(event){
        var country_id = $(this).val();

        if (country_id == 0)
        {
            $("#post_codes").hide();
        }
        else
        {
            $("#post_codes").show();
            $("#post_codes").empty().append(postcodes_table['country-'+country_id]);
        }
    }).trigger('change');

    // Gestion des villes par code postal
    var cities_table = {};

    $("#cities select").each(function(){
        var select_city = $(this);
        
        cities_table[select_city.attr('id')] = select_city;
        select_city.remove();
    });

    //$('#country-'+$('#COUN_ID').val()).change(function(event){
    $('[id^="country-"]').change(function(event){
        var postal_code_id = $(this).val();
        
        if (postal_code_id == 0)
        {
            $("#cities").hide();
        }
        else
        {
            $("#cities").show();
            $("#cities").empty().append(cities_table['postcode-'+postal_code_id]);
        }
    }).trigger('change');
})(jQuery);


Code HTML :


<!DOCTYPE html>
<html lang="fr">
<head>
    <meta charset="UTF-8" />
    <meta name="author" content="thirt" />
    <meta name="description" content="gestion des villes">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <title>Responsive registration form</title>
    <link rel="stylesheet" type="text/css" href="../../public/css/bootstrap.min.css" />
    <link rel="stylesheet" type="text/css" href="css/registration.css" />
</head>
<body class="bg-dark">
    <div class="container mt-4">
        <div class="row">
            <div class="col-lg-4 offset-lg-4 alert-class" id="alert">
                <div class="alert alert-success">
                    <strong id="result"></strong>
                </div>
            </div>
        </div>
        <!-- Registration Form -->
        <div class="row">
            <div class="col-lg-4 offset-lg-4 bg-light rounded register-class" id="register-box">
                <h2 class="text-center mt-2">Register</h2>
                <form action="" method="post" role="form" class="p-2" id="register-form">
                    <div class="form-group countries" id="countries">
                        <select name="COUN_ID" id="COUN_ID" class="form-control">
                             <option value="0">Sélectionnez un pays ...</option>
                             <option value="1">Belgique</option>
                             <option value="2">France</option>
                             <option value="3">Maroc</option>
                        </select>
                    </div>
                    <div class="form-group postcodes" id="post_codes">
                        <select name="POST_ID" id="country-1" class="form-control clspostcode">
                           <option value="0">Sélectionnez un code postal ...</option>
                           <option value="1">1000</option>
                           <option value="2">5000</option>
                           <option value="3">4000</option>
                           <option value="4">8000</option>
                           <option value="5">2000</option>
                           <option value="6">6000</option>
                           <option value="7">5300</option>
                           <option value="8">4500</option>
                           <option value="9">4520</option>
                           <option value="10">9000</option>
                        </select>
                        <select name="POST_ID" id="country-2" class="form-control clspostcode">
                           <option value="0">Sélectionnez un code postal ...</option>
                           <option value="11">57000</option>
                        </select>
                        <select name="POST_ID" id="country-3" class="form-control clspostcode">
                           <option value="0">Sélectionnez un code postal ...</option>
                           <option value="12">40000</option>
                        </select>
                    </div>
                    <div class="form-group cities" id="cities">
                        <select name="CITY_ID" id="postcode-7" class="form-control">
                           <option value="0">Sélectionnez une ville ...</option>
                           <option value="1">Petit-Warêt</option>
                           <option value="2">Seilles</option>
                           <option value="3">Andenne</option>
                        </select>
                        <select name="CITY_ID" id="postcode-9" class="form-control">
                           <option value="0">Sélectionnez une ville ...</option>
                           <option value="4">Wanze</option>
                           <option value="5">Antheit</option>
                           <option value="6">Vinalmont</option>
                        </select>
                    </div>
                    <div class="form-group">
                        <input type="submit" name="register-btn" id="register-btn" value="Inscription" class="btn btn-primary btn-block">
                    </div>
                </form>
            </div>
        </div>
        <script type="text/javascript" src="../../public/js/jquery-3.3.1.min.js"></script>
        <script type="text/javascript" src="../../public/js/bootstrap.min.js"></script>
        <script type="text/javascript" src="js/registration.js"></script>
        <script type="text/javascript" src="js/linked_select.js"></script>
    </div>
</body>
</html>


J'espère que vous avez tout le code dont vous avez besoin. Si ce n'est pas le cas, n'hésitez pas à revenir près de moi.

Encore merci pour votre aide.

Bonne journée
Thierry
Modérateur
Bonjour,

C'est le fait de retirer les éléments du DOM qui met la panique. Quand tu les remets, il faudrait aussi re-déclarer les $('...').change(...), ce qui est lourd (il vaudrait mieux selon moi simplement cacher/montrer les select).

Pour faire marcher le code sans tout bouleverser, on déplace $('[id^="country-"]').change() à l'intérieur de $('#COUN_ID').change() (je n'ai pas vérifié toutes les implications que cela pouvait avoir, il faut tester) :

(function($){
    // Gestion des codes postaux par pays
    var postcodes_table = {};

    $("#post_codes select").each(function(){
        var select_postcode = $(this);
        
        postcodes_table[select_postcode.attr('id')] = select_postcode;
        select_postcode.remove();
    });

    $('#COUN_ID').change(function(event){
        var country_id = $(this).val();

        if (country_id == 0)
        {
            $("#post_codes").hide();
        }
        else
        {
            $("#post_codes").show();
            $("#post_codes").empty().append(postcodes_table['country-'+country_id]);
			
            $('[id^="country-"]').change(function(event){
              var postal_code_id = $(this).val();
		
              if (postal_code_id == 0)
              {
                $("#cities").hide();
              }
              else
              {
                $("#cities").show();
                $("#cities").empty().append(cities_table['postcode-'+postal_code_id]);
              }
            }).trigger('change');
        }
    }).trigger('change');

    // Gestion des villes par code postal
    var cities_table = {};

    $("#cities select").each(function(){
        var select_city = $(this);
        
        cities_table[select_city.attr('id')] = select_city;
        select_city.remove();
    });

})(jQuery);

Amicalement,
Bonjour Parsimonhi,

tout d'abord, merci pour votre réponse.

Le souci, c'est que cela ne fonctionnera pas quand je changerai de code postal.

En fait, ça fonctionnera quand je sélectionnerai un pays mais pas quand je sélectionnerai un code postal.

En fait, quand je choisis un pays, j'ai la liste déroulante avec les codes postaux qui doit s'afficher en fonction du pays sélectionné.

Par après, quand je sélectionne un code postal, je dois avoir la liste déroulante avec les villes qui doit s'afficher en fonction du code postal et c'est cela qui ne fonctionne pas.

Encore merci pour votre aide.

Bonne soirée.
Thierry
Modérateur
Bonjour,

T'as testé ?

Parce qu'avec le code html que tu as donné, ça a l'air de marcher.

EDIT: voici mon code complet
<!doctype html>
<html lang="fr">
<head>
    <meta charset="UTF-8" />
    <meta name="author" content="thirt" />
    <meta name="description" content="gestion des villes">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <title>Responsive registration form</title>
	<script src="https://code.jquery.com/jquery-3.3.1.js"></script>
    <!--
    <link rel="stylesheet" type="text/css" href="../../public/css/bootstrap.min.css" />
    <link rel="stylesheet" type="text/css" href="css/registration.css" />
	-->
</head>
<style>
</style>
</head>
<body class="bg-dark">
    <div class="container mt-4">
        <div class="row">
            <div class="col-lg-4 offset-lg-4 alert-class" id="alert">
                <div class="alert alert-success">
                    <strong id="result"></strong>
                </div>
            </div>
        </div>
        <!-- Registration Form -->
        <div class="row">
            <div class="col-lg-4 offset-lg-4 bg-light rounded register-class" id="register-box">
                <h2 class="text-center mt-2">Register</h2>
                <form action="" method="post" role="form" class="p-2" id="register-form">
                    <div class="form-group countries" id="countries">
                        <select name="COUN_ID" id="COUN_ID" class="form-control">
                             <option value="0">Sélectionnez un pays ...</option>
                             <option value="1">Belgique</option>
                             <option value="2">France</option>
                             <option value="3">Maroc</option>
                        </select>
                    </div>
                    <div class="form-group postcodes" id="post_codes">
                        <select name="POST_ID" id="country-1" class="form-control clspostcode">
                           <option value="0">Sélectionnez un code postal ...</option>
                           <option value="1">1000</option>
                           <option value="2">5000</option>
                           <option value="3">4000</option>
                           <option value="4">8000</option>
                           <option value="5">2000</option>
                           <option value="6">6000</option>
                           <option value="7">5300</option>
                           <option value="8">4500</option>
                           <option value="9">4520</option>
                           <option value="10">9000</option>
                        </select>
                        <select name="POST_ID" id="country-2" class="form-control clspostcode">
                           <option value="0">Sélectionnez un code postal ...</option>
                           <option value="11">57000</option>
                        </select>
                        <select name="POST_ID" id="country-3" class="form-control clspostcode">
                           <option value="0">Sélectionnez un code postal ...</option>
                           <option value="12">40000</option>
                        </select>
                    </div>
                    <div class="form-group cities" id="cities">
                        <select name="CITY_ID" id="postcode-7" class="form-control">
                           <option value="0">Sélectionnez une ville ...</option>
                           <option value="1">Petit-Warêt</option>
                           <option value="2">Seilles</option>
                           <option value="3">Andenne</option>
                        </select>
                        <select name="CITY_ID" id="postcode-9" class="form-control">
                           <option value="0">Sélectionnez une ville ...</option>
                           <option value="4">Wanze</option>
                           <option value="5">Antheit</option>
                           <option value="6">Vinalmont</option>
                        </select>
                    </div>
                    <div class="form-group">
                        <input type="submit" name="register-btn" id="register-btn" value="Inscription" class="btn btn-primary btn-block">
                    </div>
                </form>
            </div>
        </div>
       <!--
        <script type="text/javascript" src="../../public/js/jquery-3.3.1.min.js"></script>
        <script type="text/javascript" src="../../public/js/bootstrap.min.js"></script>
        <script type="text/javascript" src="js/registration.js"></script>
        <script type="text/javascript" src="js/linked_select.js"></script>
        -->
    </div>
<script>
(function($){
    // Gestion des codes postaux par pays
    var postcodes_table = {};

    $("#post_codes select").each(function(){
        var select_postcode = $(this);
        
        postcodes_table[select_postcode.attr('id')] = select_postcode;
        select_postcode.remove();
    });

    $('#COUN_ID').change(function(event){
        var country_id = $(this).val();

        if (country_id == 0)
        {
            $("#post_codes").hide();
        }
        else
        {
            $("#post_codes").show();
            $("#post_codes").empty().append(postcodes_table['country-'+country_id]);
			
            $('[id^="country-"]').change(function(event){
              var postal_code_id = $(this).val();
		
              if (postal_code_id == 0)
              {
                $("#cities").hide();
              }
              else
              {
                $("#cities").show();
                $("#cities").empty().append(cities_table['postcode-'+postal_code_id]);
              }
            }).trigger('change');
        }
    }).trigger('change');

    // Gestion des villes par code postal
    var cities_table = {};

    $("#cities select").each(function(){
        var select_city = $(this);
        
        cities_table[select_city.attr('id')] = select_city;
        select_city.remove();
    });

})(jQuery);
</script>
</body>
</html>


Amicalement,
Modifié par parsimonhi (05 Feb 2019 - 19:21)
Bonsoir Parsimonhi,

en effet, votre solution semble fonctionner.

En tout cas, un grand merci à vous.

J'ai peut-être une dernière question à vous poser.

Avec votre solution, je suppose qu'il n'y a pas de souci pour récupérer la valuer sélectionné par l'utilisateur en PHP ?

Encore merci pour votre aide et bonne soirée à vous.
Thierry
Modérateur
Bonjour,
THIRT05 a écrit :
Avec votre solution, je suppose qu'il n'y a pas de souci pour récupérer la valuer sélectionné par l'utilisateur en PHP ?


Normalement, ça change rien pour php. Mais comme toujours, et ma mère me l'a encore répété hier soir, il faut tester ! Smiley smile

Amicalement,