Name and ID changing - javascript

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>

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.

Related

Dynamic text input with HTML output

I need to display the data entered into several text fields using div elements. There should be a dedicated div for each text input.
I have looked around all I have found is how to create dynamic inputs. But none of them explains how to use the created fields to read the info and display the info
function display_array()
{
var e = "<hr/>";
for (var y=0; y<array.length; y++)
{
e += "Element " + y + " = " + array[y] + "<br/>";
}
document.getElementById("Result").innerHTML = e;
}
//Counter to maintain number of textboxes and give them unique id for later reference
var intTextBox = 0;
/**
* Function to add textbox element dynamically
* First we incrementing the counter and creating new div element with unique id
* Then adding new textbox element to this div and finally appending this div to main content.
*/
function addElement() {
intTextBox++;
var objNewDiv = document.createElement('div');
objNewDiv.setAttribute('id', 'div_' + intTextBox);
objNewDiv.innerHTML = 'Textbox ' + intTextBox + ': <input type="text" id="tb_' + intTextBox + '" name="tb_' + intTextBox + '"/>';
document.getElementById('content').appendChild(objNewDiv);
}
/**
* Function to remove textbox element dynamically
* check if counter is more than zero then remove the div element with the counter id and reduce the counter
* if counter is zero then show alert as no existing textboxes are there
*/
function removeElement() {
if(0 < intTextBox) {
document.getElementById('content').removeChild(document.getElementById('div_' + intTextBox));
intTextBox--;
} else {
alert("No textbox to remove");
}
}
<p>Demo of adding and removing textboxes dynamically using simple JavaScript</p>
<p>
Add
Remove
</p>
<div id="content"></div>
<input type="button" id="button2" value="Display" onclick="display_array();"></input>
<div id="Result"></div>
i give you 3 changes and not sure if that is what you want,see this demo:
https://jsfiddle.net/xianshenglu/ev1f38L3/
first change: add var array,,,,
var array=document.getElementsByClassName('tb');
second,add .value
e += "Element " + y + " = " + array[y].value + "<br/>";
third,add class="tb"
objNewDiv.innerHTML = 'Textbox ' + intTextBox + ': <input type="text"
id="tb_' + intTextBox + '" class="tb" name="tb_' + intTextBox + '"/>';
I have updated the code to output two separate text fields but to have it display together is not working.
function display_array()
{
var array=document.getElementsByClassName('tb');
var e = "<hr/>";
var array2=document.getElementsByClassName('tb2');
var e2 = "<hr/>";
for (var y=0; y<array.length; y++)
{
e += array[y].value ''+'' e2 += array2[y].value;
// e2 += "Mac " + y + " = " + array2[y].value;
}
document.getElementById("Result").innerHTML = e + 'm' + e2;
//document.getElementById("Result2").innerHTML = e;
}
//Counter to maintain number of textboxes and give them unique id for later reference
var intTextBox = 0;
var intTextBox2 = 0;
/**
* Function to add textbox element dynamically
* First we incrementing the counter and creating new div element with unique id
* Then adding new textbox element to this div and finally appending this div to main content.
*/
function addElement() {
intTextBox++;
intTextBox2++;
var objNewDiv = document.createElement('div');
objNewDiv.setAttribute('id', 'div_' + intTextBox);
objNewDiv.innerHTML = 'Textbox ' + intTextBox + ': <input type="text" id="tb_' + intTextBox + '" class="tb" name="tb_' + intTextBox + '"/>';
document.getElementById('content').appendChild(objNewDiv);
var objNewDiv = document.createElement('div');
objNewDiv.setAttribute('id', 'div_' + intTextBox);
objNewDiv.innerHTML = 'Textbox1 ' + intTextBox + ': <input type="text" id="tb2_' + intTextBox + '" class="tb2" name="tb2_' + intTextBox + '"/>';
document.getElementById('content').appendChild(objNewDiv);
}
<p>Demo of adding and removing textboxes dynamically using simple JavaScript</p>
<p>
Add
Remove
</p>
<div id="content"></div><div id="content2"></div>
<input type="button" id="button2" value="Display" onclick="display_array();"></input>
<div id="Result"></div>

Simple Javascript Calculator

I'm trying to learn Javascript and I feel like I have a decent grasp on the fundamentals but I am having problems making it do things that i want .. for example.. I am trying to create a simple form in html that calculates the sum of 2 numbers.. here is my html and javascript:
<head>
<script type="text/javascript">
function adder(a,b) {
var a = document.getElementById('firstNum').value;
var b = document.getElementById('secondNum').value;
var numbers = new Array(a,b);
var sum = 0;
for (i=0; i < numbers.length; i++) {
sum += parseInt(numbers[i]);
}
//this part i need help with
document.getElementById('answer').write("First Number: " + a + " plus Second Number: " + b + " is " + sum).value; //this part i need help with
</script>
</head>
<body>
<form id="additionForm">
A + B = C : <input type="text" id="firstNum" placeholder="A">
+ <input type="text" id="secondNum" placeholder="B">
<input type="button" id="addBtn" value="Add" onClick="adder();">
= <input type="text" id="answer" placeholder="C">
</form>
</body>
My problem is that i don't know how to get the javascript to overwrite the value attribute for my form input id=answer .. or if i'm supposed to be using Jquery instead .. thanks in advance.
function adder() {
var a = parseInt( document.getElementById('firstNum').value, 10);
var b = parseInt( document.getElementById('secondNum').value, 10);
var sum = a + b;
//this part i need help with
document.getElementById('answer').value = "First Number: " + a + " plus Second Number: " + b + " is " + sum).value; //this part i need help with
}
If you want to modify an input field in javascript, you can simply set the value attribute:
document.getElementById('answer').value = "First Number: " + a + " plus Second Number: " + b + " is " + sum;

Multiple input fields using JS

Got the following JS code:
<script language="javascript">
fields = 0;
pNR = 0;
err = 0;
function addInput() {
if (fields != 40) {
document.getElementById('text').innerHTML += "<input type='text' name='first" + pNR + "' value='' /><input type='text' name='second" + pNR + "' value='' /><br />";
fields += 1;
pNR += 1;
} else {
if (err == 0) {
document.getElementById('text').innerHTML += "<br />Adaugati maxim 40 ingrediente.";
err = 1;
}
document.form.add.disabled = true;
}
}
</script>
and the following HTML:
<input name="name" style="color:#ffffff;" class="name required" type="button" onclick="addInput()" value="Add" />
<div id="text">
</div>
By default, there are no fields. When I press the Add button (fields are added two by two with different names), fill in the fields and click again the Add button, the filled fields are emptied. What did I do wrong?
You aren't simply adding new inputs.
You are:
converting the existing ones to HTML (the value attribute is unchanged, it will still have the default value, not the current value)
adding the HTML for the new inputs to it
generating new DOM elements from that HTML.
Don't use innerHTML. Use createElement, appendChild and friends.
This:
document.getElementById('text').innerHTML += "<input type='text' name='first" + pNR + "' value='' /><input type='text' name='second" + pNR + "' value='' /><br />";
Becomes this:
var firstInput = document.createElement("input");
var secondInput = document.createElement("input");
firstInput.type = secondInput.type = "text";
firstInput.name = "first" + pNR;
secondInput.name = "second" + pNR;
var text = document.getElementById("text");
text.appendChild(firstInput);
text.appendChild(secondInput);
text.appendChild(document.createElement("br"));
And, for the else case:
var text = document.getElementById("text");
text.appendChild(document.createElement("br"))
text.appendChild(document.createTextNode("Adaugati maxim 40 ingrediente."));
Working example: http://jsbin.com/OqIWeMum/2/edit

How to dynamically assign an id to an image

var intFields = 0;
var maxFields = 10;
function addElement() {
"use strict";
var i, intVal, contentID, newTBDiv, message = null;
intVal = document.getElementById('add').value;
contentID = document.getElementById('content');
message = document.getElementById('message');
if (intFields !== 0) {
for (i = 1; i <= intFields; i++) {
contentID.removeChild(document.getElementById('strText' + i));
}
intFields = 0;
}
if (intVal <= maxFields) {
for (i = 1; i <= intVal; i++) {
intFields = i;
newTBDiv = document.createElement('div');
newTBDiv.setAttribute('id', 'strText' + intFields);
newTBDiv.innerHTML = "<input placeholder='recipient" + intFields + "#email.com' type='text' name='" + intFields + "'/><a href='javascript:removeElement();'><img id='strImg + " + intFields + "' src='images/minus.png' alt='Add A Field'/></a><input type='text' value='" + newTBDiv.id + "'/>";
contentID.appendChild(newTBDiv);
message.innerHTML = "Successfully added " + intFields + " fields.";
}
} else {
for (i = 1; i <= maxFields; i++) {
intFields = i;
newTBDiv = document.createElement('div');
newTBDiv.setAttribute('id', 'strText' + intFields);
newTBDiv.innerHTML = "<input placeholder='recipient" + intFields + "#email.com' type='text' name='" + intFields + "'/><a href='javascript:removeElement();'><img id='strImg + " + intFields + "' src='images/minus.png' alt='Add A Field'/></a><input type='text' value='" + newTBDiv.id + "'/>";
contentID.appendChild(newTBDiv);
message.innerHTML = "Unable to create more than 10 receipient fields!";
}
}
}
My script here dynamically adds up to 10 fields where users will be able to enter an email address and to the right of the text box i add an image of a minus sign that calls another script. I'm having trouble working out how to assign and keep track of the minus signs. I need to be able to have the minus sign script's recognize the text box it is by and remove it. I can write the remove script easily enough but I'm unsure of how to tell the image which text box to remove. Any help, suggestions, or comments are greatly appreciated.
Thanks,
Nick S.
You can add a class to the field called minus and then check through like that. I would suggest using jquery for this.
To add the class
$("#element").addClass("minus");
To remove all elements with that class
$("body input").each(function (i) {
if($(this).attr("class") == "minus"){
$(this).remove();
}
});
The two best options, imo, would be 1) DOM-traversal, or 2) manipulating ID fragments.
Under the first way, you would pass a reference to the element where the event takes place (the minus sign) and then navigate the DOM from there to the get the appropriate text box (in jQuery you could use $(this).prev(), for example).
Under the second way, you would assign a prefix or a suffix to the ID of the triggering element (the minus sign), and the same prefix or suffix to the target element (the text box). You can then (again) generate the appropriate ID for your target element by simple string manipulation of the ID from the triggering element.
Is that sufficient to get you started?
Try adding a class to the field and the same class to the minus sign.
So add this right after the setAttribute id,
newTBDiv.setAttribute('class', 'field' + intFields);
then just remove any elements that have that class.

JQuery help, How to Hide all button in JQuery

I'm trying to make a request/reply section in my project.
I want to achieve these functionality in that code (that I'm not able to implement; so guys please help me out):
1> When user click on reply button; other reply area(text-area +button) should be hide (means at a time only one reply area should be visible to the user).
2> when user click on reply button text-area will focus and page will slide down (suppose user reply 10 comment focus will automatically set to the 10 number text area and page will slide down to that position accordingly).
Here is my so far code guys:
//method call on the click of reply link.
function linkReply_Clicked(issueId) {
Id = issueId;
textId = "text_" + issueId + count;
btnReply = "btnReply_" + issueId + count;
btnCancel = "btnCancel_" + issueId + count;
var textareasArray = document.getElementsByTagName("textarea");
var btnArray = document.getElementsByTagName("input");
for (i = 0; i < textareasArray.length; i++) {
textareasArray[i].style.display = "none";
btnArray[i].style.display = "none";
}
var str = "<table cellpadding='3' cellspacing='0' width='58%'>";
str += "<tr><td valign='top' align='left'>";
str += "<textarea id=" + textId + " rows='5' cols='60'></textarea>";
str += "</td></tr>";
str += "<tr><td valign='top' align='right'>";
str += "<input id=" + btnReply + " type='button' onclick='btnReply_Clicked(Id ,textId)' value='Reply' /> ";
str += "<input id=" + btnCancel + " type='button' onclick='btnCancel_Clicked(Id ,textId)' value='Cancel' /> ";
str += "</td></tr>";
str += "</table>";
document.getElementById("divOuter_" + issueId).innerHTML = str;
$("#" + textId + "").focus();
}
// submit user reply and try to hide that reply area.
function btnReply_Clicked(issueId, textID) {
var comment = document.getElementById(textID).value;
if (comment != '') {
$.getJSON("/Issue/SaveComment", { IssueId: issueId, Comment: comment }, null);
$("#text_" + issueId + count).hide();
$("#btnReply_" + issueId + count).hide();
$("#btnCancel_" + issueId + count).hide();
document.getElementById(textID).value = '';
count = count + 1;
}
}
// cancel user reply and try to hide that reply area.
function btnCancel_Clicked(issueId, textId) {
$("#text_" + issueId + count).hide();
$("#btnReply_" + issueId + count).hide();
$("#btnCancel_" + issueId + count).hide();
document.getElementById(textId).value = '';
count = count + 1;
}
I changed a bit of this because you can do it much easier since you're already using jQuery :)
Go here for the demo version
You can replace all of your posted code with this:
function linkReply_Clicked(issueId) {
$(".replyTable").hide();
var tbl = $("<table class='replyTable' cellpadding='3' cellspacing='0' width='58%'></table>");
tbl.append("<tr><td valign='top' align='left'><textarea rows='5' cols='60'></textarea></td></tr>");
tbl.append("<tr><td valign='top' align='right'><input type='button' class='reply' value='Reply' /> <input type='button' class='cancel' value='Cancel' /> </td></tr>");
tbl.find(".reply").click(function() {
var comment = $(this).closest("table").find("textarea").val();
if (comment != '') {
$.getJSON("/Issue/SaveComment", { IssueId: issueId, Comment: comment }, null);
$(this).closest("div").empty();
}
}).siblings(".cancel").click(function() {
$(this).closest("div").empty();
});
var div = $("#divOuter_" + issueId).empty().append(tbl);
$('html, body').animate({ scrollTop: $(div).offset().top }, 500,
function() { div.find("textarea").focus(); });
}
This does the following things differently with the slide effect & the hiding and scrolling from the question:
Click handlers for reply/cancel buttons are now in-line, no need for extra functions
The inputs no longer have IDs you need to track, it just finds them relatively
Table has a class replyTable so it all old ones can be hidden quickly
Inputs have classes to find them easier (to bind the click handlers)
No more count, no need :)
Animates the body, does a quick scroll effect to the location and focuses the text area
Removes old tables to cleanup

Categories