1

I have a graphical problem with a prototype symfony form. My "CompetenceGroupe" entity can have many "CompetenceItem" entity objects. Everything work fine, but the rendering is not perfect.

When I create a new CompetenceGroupe, in my form, I can add and delete CompetenceItems sub-forms. A competenceItem form have a text input, a select input and a "delete" button (in red, generated by javascript).

I try to align those three elements, but the delete button always goes under the two others elements.

What I wish to render in the view :

enter image description here

And what I have now :

enter image description here

In my Developper Tool from Google Chrome, I can see that the delete button (with class "btn-danger") is not in the same div than the two others elements of my prototype (with class "competence_groupe_competence_items_0") :

enter image description here

I give you the code of my prototype view (competence_item_prototype.html.twig)

{% block competence_item_widget %}

    <div id="{{ form.vars.id }}" class="row">

        <div class="col-md-7">
            {{ form_label(form.libelle, "Libelle", {'label_attr': {'class': 'sr-only control-label'}}) }}
            {{ form_errors(form.libelle) }}
                {{ form_widget(form.libelle, {'attr': {'class': 'form-control', 'placeholder': 'Libellé'}}) }}
        </div>

        <div class="col-md-3">
            {{ form_label(form.niveau, "Niveau", {'label_attr': {'class': 'sr-only control-label'}}) }}
            {{ form_errors(form.niveau) }}
                {{ form_widget(form.niveau, {'attr': {'class': 'form-control selectModal'}}) }}
        </div>

    </div>

{% endblock %}

And my main view (with CompetenceGroupe form) and Javascript code for generate the "delete" buttons on each prototype forms :

{% form_theme formAddCompetence 'espaceUtilisateur/forms/prototypes/competence_item_prototype.html.twig' %}

{{ form_start(formAddCompetence, { 'attr': {'class': 'formCompetenceAdd'} }) }}

    <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
        <h4 class="modal-title" id="myModalLabel">{{ libelleCategorie }}</h4>
    </div>

    <div class="modal-body">

        <h4><span class="label label-default">Les champs marqués d'un astérisque sont obligatoires.</span></h4>

        {{ form_row(formAddCompetence.titre) }}

        {{ form_row(formAddCompetence.competence_items) }}

        {{ form_widget(formAddCompetence._token) }}

        <br>
        <a href="#" id="add_category" class="btn btn-default">Ajouter une catégorie</a>

    </div>

    <div class="modal-footer">
        <button type="button" class="btn btn-default" data-dismiss="modal">Annuler</button>

        {% if objectCompetence.idCompetenceGroupe is not empty %}
            {{ form_widget(formAddCompetence.edit) }}
            <input type="hidden" name="idCompetenceGroupe" id="idCompetenceGroupe" value="{{ objectCompetence.idCompetenceGroupe }}">
        {% else %}
            {{ form_widget(formAddCompetence.save) }}
        {% endif %}
    </div>

</form>

<script type="text/javascript">
    $(document).ready(function() {
        // On récupère la balise <div> en question qui contient l'attribut « data-prototype » qui nous intéresse.
        var $container = $('div#competence_groupe_competence_items');

        // On définit un compteur unique pour nommer les champs qu'on va ajouter dynamiquement
        var index = $container.find(':input').length;

        // On ajoute un nouveau champ à chaque clic sur le lien d'ajout.
        $('#add_category').click(function(e) {
            addCategory($container);

            e.preventDefault(); // évite qu'un # apparaisse dans l'URL
            return false;
        });

        // On ajoute un premier champ automatiquement s'il n'en existe pas déjà un (cas d'une nouvelle annonce par exemple).
        if (index == 0) {
            addCategory($container);
        } else {
            // S'il existe déjà des catégories, on ajoute un lien de suppression pour chacune d'entre elles
            $container.children('div').each(function() {
                addDeleteLink($(this));
            });
        }

        // La fonction qui ajoute un formulaire CategoryType
        function addCategory($container) {
            // Dans le contenu de l'attribut « data-prototype », on remplace :
            // - le texte "__name__label__" qu'il contient par le label du champ
            // - le texte "__name__" qu'il contient par le numéro du champ
            var template = $container.attr('data-prototype')
                            .replace(/__name__label__/g, 'Catégorie n°' + (index+1))
                            .replace(/__name__/g,        index)
                    ;


            // On crée un objet jquery qui contient ce template
            var $prototype = $(template);

            // On ajoute au prototype un lien pour pouvoir supprimer la catégorie
            addDeleteLink($prototype);

            // On ajoute le prototype modifié à la fin de la balise <div>
            $container.append($prototype);

            // Enfin, on incrémente le compteur pour que le prochain ajout se fasse avec un autre numéro
            index++;
        }

        // La fonction qui ajoute un lien de suppression d'une catégorie
        function addDeleteLink($prototype) {

            // Création du lien
            //var $deleteLink = $('<div><a href="#" class="btn btn-danger">Supprimero</a></div>'); // OLD
            var $deleteLink = $('<div class="col-md-1"><button class="btn btn-danger"><i class="fa fa-trash-o"></i></button></div>');

            // Ajout du lien
            $prototype.last().append($deleteLink); // OLD

            // Ajout du listener sur le clic du lien pour effectivement supprimer la catégorie
            $deleteLink.click(function(e) {
                $prototype.remove();

                e.preventDefault(); // évite qu'un # apparaisse dans l'URL
                return false;
            });
        }
    });
</script>

Thanks for anyone can take time for help me.

1 Answer 1

1

Can you not just append it to the .row?

    function addDeleteLink($prototype) {

        // Création du lien
        //var $deleteLink = $('<div><a href="#" class="btn btn-danger">Supprimero</a></div>'); // OLD
        var $deleteLink = $('<div class="col-md-1"><button class="btn btn-danger"><i class="fa fa-trash-o"></i></button></div>');

        // Ajout du lien
        $prototype.find('.row').append($deleteLink); // OLD

        // Ajout du listener sur le clic du lien pour effectivement supprimer la catégorie
        $deleteLink.click(function(e) {
            $prototype.remove();

            e.preventDefault(); // évite qu'un # apparaisse dans l'URL
            return false;
        });
    }
Sign up to request clarification or add additional context in comments.

Comments

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.