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?

GreedyAi
  • 2,709
  • 4
  • 29
  • 55

2 Answers2

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.

Shilly
  • 8,511
  • 1
  • 18
  • 24
  • how do I create a template in javascript? – GreedyAi Jul 03 '15 at 11:27
  • 1
    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. – Shilly Jul 03 '15 at 11:29
  • is it document.createTextNode() or document.createNode()? cause my compiler didn't show me document.createNode() – GreedyAi Jul 03 '15 at 11:31
  • document.createElement for nodes, document.createTextNode for text you want to place inside elements. I updated the prev response. – Shilly Jul 03 '15 at 11:32
  • is there no automated translator or smth? I want to do the whole placeholder div. I am not sure I am doing it correctly. – GreedyAi Jul 03 '15 at 11:46
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>
Community
  • 1
  • 1
GreedyAi
  • 2,709
  • 4
  • 29
  • 55