Yuval Simon
Yuval Simon

Reputation: 335

Name and ID changing

I try to build an register form. This register form as text box called "address1" and near it a button called "Add Address". The function of the button - it adds text box for more addresses. the button near the previous address boxes changes to "Remove" which remove the address box and the button. The problem is: I have to set the text boxes in order - 1,2,3,... - I have to change their names and id's. For example - if I remove addressbox number 4 (name, id="address4") then all the next text boxes's names and id's should decrease by 1. I try to do this in for loop. This is hard to explain so I just give you the code. Try in your VS to write for example 'document.getElementById("address"+n).' and you'll see that you even don't see in the list you get that you can write after the dot id or name or value. I realized it is because there is a variable in this is the problem I think. Now here's the code:

<html>
<head>
    <title>Untitled Page</title>
    <script type="text/javascript">
        var n1 = 1; //counting the buttons and divs. doesn't decrease. 
                    //In another words - it counts the number of calls to Add()
        var n3 = 1; //counting the address text fields. 
                    //It being reduced and increased so that it will represent the exact number of text fields
        function Add() {
            n1++;
            n3++;
                s1 = "<div id='div" + n1 + "'>";
                s1 += "Address <input type='text' name='address" + n3 + "' id='address" + n3 + "' />";
                s1 += "<input type='button' name='add" + n1 + "' id='add" + n1 + "' value='Add Branch' onclick='Add();' /><br />";
                s1 += "</div>";
                var n2 = n1 - 1;
                document.getElementById('div' + n2).insertAdjacentHTML('afterEnd', s1);
                document.getElementById('add' + n2).onclick = function () { Remove(n2, (n3-1)); };
                document.getElementById('add' + n2).value = 'Remove';
        }
        function Remove(nn1, nn2) { //nn1 - div number to remove. nn2 - the address field number in this div
            var parent = document.getElementById('barcode');
            var child = document.getElementById('div' + nn1);
            parent.removeChild(child);
            for (nn2 += 1; nn2 <= n3; nn2++) {
                var n2 = nn2 - 1; //nn2 - current address text field. n2 - the new number for the address field
                document.getElementById('address' + nn2).setAttribute('name', 'address' + n2);
                document.getElementById('address' + nn2).setAttribute('id', 'address' + n2);
                document.getElementById('address' + n2).setAttribute('value', 'address' + n2);
                // try: document.getElementById('address' + nn2).name='address'+n2. doesn't work (for me)
            }
            n3--;
        }
        var check = false;
    </script>
</head>
<body>
    <form name='barcode' id='barcode' action="" >
        <div id='div1'>
        Address <input type='text' name='address1' id='address1' />
        <input type='button' name='add1' id='add1' value='Add Branch' onclick='Add();' /><br />
        </div></form>
</body>
</html>

Sorry for the disorder :) I keeped in this code only what linked to the address field and I added comments. Thanks very much!

edit: I forgot that you don't see the bug in this code because I already tried to fix it. Before I changed the code it ordered all the divs, text fields and add/remove buttons so all the exsisting items will always be numbered in order (1, 2, 3, ...). The problem in the following code can be seen if you click 2 times add button, then you remove the first address field and then you click the add button again.

<html>
<head>
    <script type="text/javascript">
        var n1 = 1;
        function Add() {
                n1++;
                s1 = "<div id='div" + n1 + "'>";
                s1 += "Address <input type='text' name='address" + n1 + "' id='address" + n1 + "' />";
                s1 += "<input type='button' name='add" + n1 + "' id='add" + n1 + "' value='Add Branch' onclick='Add()' /><br />";
                s1 += "</div>";
                var n2 = n1 - 1;
                document.getElementById('div' + (n2)).insertAdjacentHTML('afterEnd', s1);
                document.getElementById('add' + (n2)).onclick = function () { Remove(n2); };
                document.getElementById('add' + (n2)).value = 'Remove';
        }
        function Remove(n) {
            var parent = document.getElementById('barcode');
            var child = document.getElementById('div' + n);
            parent.removeChild(child);
            for (n += 1; n <= n1; n++) {
                var n2 = n1 - 1;
                document.getElementById('add' + n).onclick = function () { Remove(n2); };
                document.getElementById('address' + n).setAttribute('name', 'address' + n2);
                document.getElementById('add' + n).setAttribute('name', 'add' + n2);
                document.getElementById('address' + n).setAttribute('id', 'address' + n2);
                document.getElementById('add' + n).setAttribute('id', 'add' + n2);
                document.getElementById('div' + n).setAttribute('id','div' + n2);
            }
            n1--;
            document.getElementById('add' + n1).onclick = function () { Add() };
        }
    </script>
</head>
<body>
    <form name='barcode' id='barcode' action="" >
            <div id='div1'>
            Address <input type='text' name='address1' id='address1' />
            <input type='button' name='add1' id='add1' value='Add Branch' onclick='Add();' /><br />
            </div>
       </form>
</body>
</html>

Upvotes: 0

Views: 286

Answers (1)

Filipe Silva
Filipe Silva

Reputation: 21657

I think you are working a bit too hard to maintain the order of the addresses and i don't see a general reason to do it (if you have one, please add it to your question).

If you add the inputs with a unique index like you are doing, they will always be different and ordered.

Here's what you can do:

Pass the event caller to the functions Add and Remove and inside you can make the changes you want to those elements.

For example your Remove function (that you would call with Remove(this);) would look like this:

function Remove(callerButton) { 
    var parent = document.getElementById('barcode');

    var child = callerButton.parentNode;
    // child is the DIV you want to remove
    parent.removeChild(child);
    n3--;
}

This way you wouldn't need to do all the sorting you are doing right now.

At the end you can access all the remaining elements with:

var addresses = document.getElementById("barcode").getElementsByTagName("input");

for(var i = 0; i < addresses.length; i++) {
    if(addresses[i].type == "text") {
        // I'm printing them in the console, you can do with it whatever you like
        // If you want to exclude the one with "Add Branch in front of it you can validate for address+n1
        console.log("Element.id : " + addresses[i].id + " - Element.value: "+ addresses[i].value );
    }
}

I added a jsFiddle with these changes (added a submit button to show the remaining fields in the form).

See if it solves your problem.

Upvotes: 2

Related Questions