Bonjour,

J'ai un template twig qui m'affiche des prix formés de 3 inputs (prix, durée, saison) dans deux boucles for imbriquées. La première boucle correspond aux saisons et la secondes aux différentes durées. Donc pour une saison donnée, j'affiche les différents prix ayant chacun une durée différente.

Par ailleurs, je laisse la possibilité, par saison, d'ajouter de nouveaux prix (pour des durées qui n'y seraient pas encore reprises). Ça donne donc ceci au niveau de mon template :

    <h3>Prix</h3>

        {% for season in unique_seasons %}

            <h4>Saison {{ season.season }}</h4>

            {# Don't changing the id and the data-index because they're used in Jquery #}

                <ul class= "prices" id = "ulSeason_{{ season.id }}"  data-prototype = " {{ form_widget ( formPricesAdvert.prices.vars.prototype )| e ( 'html_attr' ) }} ">

                    {% set i = 0 %}

                    {% for price in formPricesAdvert.prices %}                

                        {% if idsSeasonsPrices[i] == season.id %}

                            <li>
                                {{ form_label(price.price, 'Prix', {'label_attr': {'class': 'foo'}}) }}
                                {{ form_errors(price.price) }}
                                {{ form_widget(price.price) }}

                                {{ form_label(price.duration, 'Durée', {'label_attr': {'class': 'foo'}}) }}
                                {{ form_errors(price.duration) }}
                                {{ form_widget(price.duration) }}

                                {{ form_label(price.season, 'Saison', {'label_attr': {'class': 'foo'}}) }}
                                {{ form_errors(price.season) }}
                                {{ form_widget( price.season ) }}

                                {# Don't giving an id because it's build in Jquery. The fields places order is used in Jquery #}
                                <button type="button" class="btn-remove">
                                    Supprimer cette durée
                                </button>
                            </li>

                        {% endif %}

                        {% set i = i + 1 %}

                    {% endfor %}

                    {# For each missing duration for the season, adding a button to add the price for these durations  #}
                    {% set seasonName = season.season %}

                    {% for configuredDuration in configuredDurations %}

                        {% if missingDurations[seasonName] is defined and configuredDuration in missingDurations[seasonName] %}                        

                            {# Don't changing the id because it's used in Jquery #}    
                            <button type="button" id="btn-add_{{ season.id }}_{{ configuredDuration }}" class="btn-add">
                                Ajouter {{configuredDuration}}
                            </button>

                        {% else %}                        

                            {# Don't changing the id because it's used in Jquery #}    
                            <button type="button" id="btn-add_{{ season.id }}_{{ configuredDuration }}" class="btn-add" style="display: none">
                                Ajouter {{configuredDuration}}
                            </button>

                        {% endif %}

                    {% endfor %}

                </ul>

        {% endfor %}

Lorsqu'on clique sur le bouton "Ajouter durée x", je voudrais que les 3 inputs liés à un prix se créent et s'affichent, avec, en plus, un bouton "Supprimer cette durée", en cas de mauvaise manœuvre de la part de l'utilisateur. J'ai donc ce code Jquery :


$('.btn-add') . on ( 'click' , function ( e ) {

    var collectionHolderPrices = $( this ).parent();

    // Get the data-prototype explained earlier
    var prototype = collectionHolderPrices . data ( 'prototype' );

    // get the new index
    var index = collectionHolderPrices . data ( 'index' );

    var newForm = prototype ;

    // Replace '__name__' in the prototype's HTML to
    // instead be a number based on how many items we have
    newForm = newForm . replace ( /__name__/g , index );

    // increase the index with one for the next item
    collectionHolderPrices . data ( 'index' , index + 1 );

    // Display the form in the page in an li, before the "Add a photo" link li
    var $newFormLi = $ ( '<li></li>' ). append ( newForm );
    var $deletePriceButton = $ ( '<button type="button" class="btn-remove" >Supprimer cette durée</button>' );
    $newFormLi. append ( $deletePriceButton );

    collectionHolderPrices.append($newFormLi);

    //Affectation with right duration and season 
    var idParent = $(this).parent().attr('id');
    var idSeason = idParent.substr(-1);
    var idButton = $(this).attr('id');
    var position = idButton.lastIndexOf("_");
    var duration = idButton.substring(position + 1);
    var seasonInput = $ ( "#" + idParent + " li:last select" );
    var durationInput = $ ( "#" + idParent + " li:last input" );

    seasonInput.val(idSeason);
    durationInput.val(duration);

    $( this ).toggle();

    //Id's affectation to the remove button
    var idButtonRemove = idButton.replace('add', 'remove');
    var btnRemove = $ ( "#" + idParent + " li:last button" );
    btnRemove.attr('id', idButtonRemove);

});

Mon problème est que le bouton "Supprimer cette durée" se crée et s'affiche bien, mais pas les 3 inputs, comme si ma variable "prototype" était vide.

Quelqu'un aurait une idée sur la provenance de ce problème?

Merci d'avance pour votre aide.

2 réponses


dubitoph
Auteur
Réponse acceptée

Résolu en allant chercher le prototype et l'index via la classe et en ajoutant le tout à l'ul récupérée via l'id :

$('.btn-add') . on ( 'click' , function ( e ) {

    var collectionHolderPrices = $( this ).parent();

    // Get the data-prototype explained earlier
    var prototype = $( 'ul.prices' ) . data ( 'prototype' );

    // get the new index
    var index = $( 'ul.prices' ) . data ( 'index' );
...
dubitoph
Auteur

Je viens de remarquer que si je récupère l'ul parente via la classe en faisant

var collectionHolderPrices = $( this ).parent();

, ça fonctionne. Cependant, ça ne m'arrange pas car, dès lors, un prix est ajouté à chaque ul représentant chacune une saison et non pas à la seule ul pour la saison désirée.

J'ai tenté de récupérer l'ul parente en la recherchant par l'id en faisant ceci :

    var idParent = $( this ).parent().attr('id');
    var collectionHolderPrices = $('#' + idParent);

mais le comportement reste alors le même : uniquement le bouton "Supprimer la durée" est créé.