0

ok. so I am trying to create a form so that, when I a button "+" a new form appears beneath the existing one. For example I have form to fill name

VoteType
name: [        ]
{+}  -- (button)

when clicked "+" the form will look like this

VoteType
name: [        ]

Vote1 name [        ]
      image [        ]
      date [        ]

{+} -- (button)

and the button "+" so that I can add Vote2 ... as many as I want.

So I did this form buy when I try to number them, the numbers don't go as I intended.

<fieldset id="fieldset">
    <form method = 'POST' action = ''>{%csrf_token %}
        <p>{{ voteTypeForm }}</p>
    </form>

        <div id="placeholder">
            <div id="template">
                <p><fieldset id="fieldsets">
                    <legend id="legends">Candidate No <input type="text" id="someInput" name="someInput" readonly></input></legend>
                    <form method = 'POST' action = ''>{%csrf_token %}
                        {{ voteForm.as_p}}
                    </form>
                </fieldset></p>
            </div>
        </div>
        <p><button type="button" name="Submit" onclick="Add();">+</button></p>
    <input type = 'submit' value="create"/>
</fieldset>
<script>
    var _counter = 0;
    function Add() {
        _counter++;
        var oClone = document.getElementById("template").cloneNode(true);
        oClone.id += (_counter + "");
        document.getElementById("placeholder").appendChild(oClone);
        document.getElementById("someInput").value = _counter;
    }
</script>

When I click button + it creates forms but numbers them like this:

4 [empty] 1 2 3

instead of

1 2 3 4 5

I was trying to somehow hide the placeholder using style "none", but than it didn't show any of them, than I tried to activate it only when counter is more than 1 but than it showed first one again. I don't usually use javascript so please help. How can I solve this?

2 Answers 2

1

Concerning hiding the template, you can use visibility: hidden to keep the nodes in the DOM so you can select them. Alternatively, if you can use the tag, use that. A last alternative is creating the template in your javascript and keeping the node you want to clone in a variable, instead of keeping it in your DOM.

Haven't figured out yet why the id counter doesn't work properly.

var tmp = document.createElement('div'),
    template;
tmp.innerHTML = '<div id="template"><p><fieldset id="fieldsets"><legend id="legends">Candidate No <input type="text" id="someInput" name="someInput" readonly></input></legend><form method = "POST" action = "">{%csrf_token %}{{ voteForm.as_p}}</form></fieldset></p></div>';
template = tmp.innerHTML;

This is the smallest way I could type it. You might have to change the php? asp? code inside the form action though.

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

5 Comments

how do I create a template in javascript?
var template = document.createElement('div'); template.id = 'template'; In the same way you can create the other nodes, set their properties and append them to your div. It looks a bit messy, but you end up with var template containing the node you want to clone.
is it document.createTextNode() or document.createNode()? cause my compiler didn't show me document.createNode()
document.createElement for nodes, document.createTextNode for text you want to place inside elements. I updated the prev response.
is there no automated translator or smth? I want to do the whole placeholder div. I am not sure I am doing it correctly.
0

Ok so, I had several issues here. One was that the numbers weren't displaying correctly and another one that I didn't want my form to be shown without clicking button [+]. so I decided to keep my html block of code in javascript. I didn't know how to use that code to append it to html code, because appendchild function required node as an argument and not string. To solve this problem I found this stackoverflow question.

For the rest here is my solution code:

{% load staticfiles %}
<link rel="stylesheet" type="text/css" href="{% static 'Vote/style.css' %}" />
<fieldset id="fieldset">
    <form method = 'POST' action = ''>{%csrf_token %}
        <p>{{ voteTypeForm }}</p>
        <div id="placeholder">

        </div>
        <p>
            <button type="button" name="Submit" onclick="Add();">+</button>
        </p>
        <input type = 'submit' value="create"/>
    </form>
</fieldset>
<script type='text/javascript'>
{#    document.write(code);#}
    var _counter = 0;
    var template = document.createTextNode('');
    function appendStringAsNodes(element, html)
    {
        var frag = document.createDocumentFragment(),
            tmp = document.createElement('body'), child;
        tmp.innerHTML = html;
        // Append elements in a loop to a DocumentFragment, so that the browser does
        // not re-render the document for each node
        while (child = tmp.firstChild) {
            frag.appendChild(child);
        }
        element.appendChild(frag); // Now, append all elements at once
        frag = tmp = null;
    }
    function Add() {
        var code = '<div id="template">' +
                '<p>' +
                    '<fieldset id="fieldsets">' +
                        '<legend id="legends">Candidate No ['+ String(_counter+1) +']</legend>' +
                       ' <form method = "POST" action = "">'+
                              '<input type="hidden" name="csrfmiddlewaretoken" value="{{csrf_token }}" />' +
                            '<p><label for="id_name">Name:</label> <input id="id_name" maxlength="50" name="name" type="text" /></p>'+
                            '<p><label for="id_image">Image:</label> <input id="id_image" name="image" type="file" /></p>'+
                        '</form>' +
                   ' </fieldset>' +
                '</p>' +
            '</div>';
        _counter++;
        appendStringAsNodes(document.getElementById("placeholder"),code);
        document.getElementById("someInput").value = _counter;
    }
</script>

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.