0

I have a dynamic form section which I need the name attribute to be dynamic as well. the number should always get +1 each time the user create a new section !

name="training**1**[institut]"

This is crucial to have a proper SQL insert ... otherwise the array won't have a classical database logics !

JSFIDDLE here

Any idea ? thanks a lot from France !

    <form method="post" action="">

    <!-- INFO SECTION -->
    <div id="infos">
        <h2>Infos personnelles</h2>
        <input placeholder="Prénom">
        <input placeholder="Nom">     
    </div>


    <!-- TRAINING SECTION -->
    <div id="training">
        <h2>Formation</h2>
        <!-- Template -->
        <div id="new-training" style="display:none">
            <div>
                    </br>
                    <p></p>
                    <input id="mytext" type="text" name="training[1][institut]" placeholder="Diplôme" value="">
                    <input name="training[1][institut]" placeholder="Institut">
            </div>
        </div>
    </div>

    <p id="addnew">
        <a href="javascript:addTraining()">+ Ajouter une formation</a>
    </p>

    <p>
        <br>
        <input type="submit" value="Sauvergarder" name="submit">
    </p>
</form>


<script> // 1st : Enregistrer / supprimer une formation

var ct = 1;

function addTraining()
{
    ct++;
    var div1 = document.createElement('div');
    div1.id = ct;
    // link to delete extended form elements
    var delLink = '<a href="javascript:removeTraining('+ ct +')">Supprimer cette formation</a>';
    div1.innerHTML = document.getElementById('new-training').innerHTML + delLink;
    document.getElementById('training').appendChild(div1);
}

function removeTraining(eleId)
{
    d = document;
    var ele = d.getElementById(eleId);
    var parentEle = d.getElementById('training');
    parentEle.removeChild(ele);
}
2
  • Describe your problem.. Commented Aug 21, 2020 at 17:11
  • 1
    @DanielTran sorry, it was a bit unclear. I have just edited the post ! I cant' make the name attribute dynamic ! That's my point. I've been struggling hours with it ! Commented Aug 21, 2020 at 17:27

3 Answers 3

1

The best solution (my opinion) is to use a simple templating engine

https://jsfiddle.net/nget5dq2/1/

Addition to your HTML:

<template id="new_el_template" hidden>
  <div id="row-{cid}">
    <input id="mytext-{cid}" type="text" name="training[{cid}][institut]" placeholder="Diplôme" value="">
    <input name="training[{cid}][institut]" placeholder="Institut">
  </div>
  <a href="javascript:removeTraining({cid})">Supprimer cette formation</a>
</template>

JS

var ct = 1;
function addTraining() {
    ct++;              
    let div = document.createElement('div');
    div.innerHTML = document.getElementById('new_el_template').innerHTML.replace(/\{cid\}/gi, ct);
    document.getElementById('training').appendChild(div);
}
function removeTraining(eleId) {
   document.getElementById('row-' + eleId).parentNode.remove();
}

And yes, you can go ahead and generate the initial element directly from the template.

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

4 Comments

Thank a lot @Unbywyd ! Your piece of code looks DRY ! However the Remove function broke during the code upgrade. Tried to solve it by creating a div with the "training" id in the template ... but without success. Any clue ?
Delete is just not a problem: jsfiddle.net/s9rquj1L but if you need to reset the counter, it requires rendering full rows
Again, if not all rows are deleted, and if all, then you can ask the counter for 0
I owe you a coffee bro ;) Works perfect !
0

write the name attribute this way you should get all the data from the form when u post it.

 <input id="mytext" type="text" name="training[diploma][]" placeholder="Diplôme" value="">
 <input name="training[institut][]" placeholder="Institut">

Comments

0

Here is a working example with comments added throughout..

<!DOCTYPE html>
<html>
<head>
    <title>Test</title>
</head>
<body>


    <form method="post" action="">

    <!-- INFO SECTION -->
    <div id="infos">
        <h2>Infos personnelles</h2>
        <input placeholder="Prénom">
        <input placeholder="Nom">     
    </div>


    <!-- TRAINING SECTION -->
    <div id="training">
        <h2>Formation</h2>
        <!-- Template -->
        <div id="new-training" >
            <div>
                    </br>
                    <p></p>
                    <input id="mytext" type="text" name="training[1][institut]" placeholder="Diplôme" value="">
                    <input name="training[1][institut]" placeholder="Institut">
            </div>
        </div>
    </div>

    <p id="addnew">
        <a style="color: blue" onclick="addTraining()">+ Ajouter une formation</a>
    </p>

    <p>
        <br>
        <input type="submit" value="Sauvergarder" name="submit">
    </p>
</form>



</body>



    
<script>
    

    const addTraining = () => {
        
        //Get parent container to place new input into
        const parent = document.getElementById('training');


        //Create DIV to wrap around input elements
        let div = document.createElement('div')
        
        //Create new input with a unique name attribute
        let newInput1 = document.createElement('input');
        let newInput2 = document.createElement('input');

        //You can get an array of all existing elements and add 1 to create a unique name for each
        let num = parent.querySelectorAll('div').length + 1,
            newName = 'training['+ num +'][institut]';      
        
        //Set name attribute
        newInput1.setAttribute('name', newName);
        newInput2.setAttribute('name', newName);

        //Set other attributes you alreadt had
        newInput1.setAttribute('placeholder', 'Diplôme');
        newInput2.setAttribute('placeholder', 'Institut');
        newInput1.setAttribute('id', 'myText');
        newInput1.setAttribute('type', 'text');

        //Append elements
        parent.appendChild(div);
        div.appendChild(newInput1);
        div.appendChild(newInput2)


    }


</script>

</html>

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.