Dynamically add set of inputs to html form - javascript

I am currently creating a HTML form, I have a section in which contains 8 text inputs. This is the section so far:
<div class="form-title"><h3>Clinical Information</h3></div>
<div class="form-title">Time Assesed:</div>
<input class="form-field" type="time" name="timeassessd" /><br />
<div class="form-title">Blood Pressure:</div>
<input class="form-field" type="text" name="bp" /><br />
<div class="form-title">Pulse:</div>
<input class="form-field" type="date" name="pulse" /><br />
<div class="form-title">Resp. Rate:</div>
<input class="form-field" type="text" name="breathing" /><br />
<div class="form-title">Temp:</div>
<input class="form-field" type="text" name="temp" /><br />
<div class="form-title">SPO2:</div>
<input class="form-field" type="text" name="spo2" /><br />
<div class="form-title">GCS:</div>
<input class="form-field" type="text" name="gcs" /><br />
<div class="form-title">AVPU:</div>
<input class="form-field" type="text" name="avpu" /><br />
What I need is to have a button that when the user presses the button it will create another section identical to the one above adding the fields to the form. Each form will also need a number on the end of the name. I have looked around at different forums but I cant find one with a whole section to add in just individual inputs which doesn't help me here. Thanks.

You need to make a JS function to add the section. the function would look something like this:
function add_section() {
new_row = "";
new_row += "";
new_row += '<div class="form-title"><h3>Clinical Information</h3></div>';
new_row += '<div class="form-title">Time Assesed:</div>';
new_row += '<input class="form-field" type="time" name="timeassessd" /><br />';
new_row += '<div class="form-title">Blood Pressure:</div>';
new_row += '<input class="form-field" type="text" name="bp" /><br />';
new_row += '<div class="form-title">Pulse:</div>';
new_row += '<input class="form-field" type="date" name="pulse" /><br />';
new_row += '<div class="form-title">Resp. Rate:</div>';
new_row += '<input class="form-field" type="text" name="breathing" /><br />';
new_row += '<div class="form-title">Temp:</div>';
new_row += '<input class="form-field" type="text" name="temp" /><br />';
new_row += '<div class="form-title">SPO2:</div>';
new_row += '<input class="form-field" type="text" name="spo2" /><br />';
new_row += '<div class="form-title">GCS:</div>';
new_row += '<input class="form-field" type="text" name="gcs" /><br />';
new_row += '<div class="form-title">AVPU:</div>';
new_row += '<input class="form-field" type="text" name="avpu" /><br />';
var pos = $("selecter"); //element selecter after which you need to add the section
$(pos).after(new_row);
}
And then on the click of the button, call this function. It will work.
Also the name of input fields should be an array ex: name="avpu[]"
If not using array, the post method would only get the value of the last input element having same names.

Could you post the whole form?
What you can do, if you're using jQuery, is, that you clone the jQuery node of the form and than manipulate the input names, and than append the content to your form.
Something like that:
var num = 1;
function add_form_elements(num) {
var clonedForm = $('#id_of_the_form').clone();
clonedForm.find('input').each(function(id, elm) {
elm.attr("name",elm.attr("name") + num);
});
$('#id_of_the_form').append(clonedForm.innerHTML);
num++;
});
Than you need to add an EventListener to your button and bind the add_form_elements function to it.

Make new div, which content all you want to duplicate and is invisible.
<div class="copyable" style="display: none;">
<div class="form-title"><h3>Clinical Information</h3></div>
<div class="form-title">Time Assesed:</div>
<input class="form-field" type="time" name="timeassessd" /><br />
<div class="form-title">Blood Pressure:</div>
<input class="form-field" type="text" name="bp" /><br />
<div class="form-title">Pulse:</div>
<input class="form-field" type="date" name="pulse" /><br />
<div class="form-title">Resp. Rate:</div>
<input class="form-field" type="text" name="breathing" /><br />
<div class="form-title">Temp:</div>
<input class="form-field" type="text" name="temp" /><br />
<div class="form-title">SPO2:</div>
<input class="form-field" type="text" name="spo2" /><br />
<div class="form-title">GCS:</div>
<input class="form-field" type="text" name="gcs" /><br />
<div class="form-title">AVPU:</div>
<input class="form-field" type="text" name="avpu" /><br />
</div>
In JS file:
function add_elm(){
var content = $('.copyable').html(),
$elm = $('.elm'); //element where you want to add copyable content
$elm.append(content);
}
Note: append use for appending html inside parent node. If you want add html exactly after other elm, just use after(content) at the end of code above.

One approach to your problem, using plain JavaScript is the following (bear in mind that this does require a change to your HTML, in that the section containing the <input> elements you wish to duplicate requires a class-name (here it's "clinicalInformation", but adjust to your own requirements - remembering to change the selector held in the <button> elements' data-duplicates attribute):
// the event is passed automagically from the addEventListener()
// method:
function duplicate(event) {
// preventing the clicked-element's default behaviour
// (which in many cases could cause a page reload):
event.preventDefault();
// using Array.prototype.slice, with Function.prototype.call,
// on the NodeList returned by document.querySelectorAll(),
// to create an array of element nodes;
// 'this.dataset.duplicates' retrieves the attribute-value from
// the 'data-duplicates' attribute of the clicked element:
var allCurrent = Array.prototype.slice.call(document.querySelectorAll(this.dataset.duplicates), 0),
// getting the last element from the array of nodes:
toClone = allCurrent[allCurrent.length - 1],
// cloning that node, including its child elements:
clone = toClone.cloneNode(true),
// creating a RegExp (regular expression) literal,
// to match a sequence of one, or more, numbers (\d+)
// followed by the end of the string ($):
reg = /\d+$/,
// creating an 'empty'/unitialised variable for use
// within the (later) loop:
childElems;
// adding the created clone to the allCurrent array:
allCurrent.push(clone);
// using Array.prototype.forEach() to iterate over the
// array, the arguments (names are user-defined):
// - first (here 'fieldset') is the current array element
// over which we're iterating,
// - second (here 'index') is the index of the current
// array element in the array:
allCurrent.forEach(function(fieldset, index) {
// finding all descendant elements contained within
// the current array-element that have a 'name' attribute,
// using a CSS attribute-selector within
// document.querySelectorAll():
childElems = fieldset.querySelectorAll('[name]');
// iterating over those descendant elements in the
// array-like NodeList:
Array.prototype.forEach.call(childElems, function(elem) {
// if the regular expression matches the name (
// RegExp.prototype.test() returning a Boolean true/false
// based on the string matching, or not matching, the
// regular expression) we replace that match with the index
// (from the outer loop), or if not we simply append the
// index to the current name property-value:
elem.name = reg.test(elem.name) ? elem.name.replace(reg, index) : elem.name + index;
});
// navigating from the cloned node to its parent and, using
// Node.insertBefore(), we insert the created clone before
// the nextSibling of that cloned node:
toClone.parentNode.insertBefore(clone, toClone.nextSibling);
});
}
// getting a reference to the element that should trigger
// the duplication:
var addMore = document.getElementById('duplicate');
// adding an event-handler for the 'click' event
// (note the lack of parentheses):
addMore.addEventListener('click', duplicate)
function duplicate(event) {
event.preventDefault();
var allCurrent = Array.prototype.slice.call(document.querySelectorAll(this.dataset.duplicates), 0),
toClone = allCurrent[allCurrent.length - 1],
clone = toClone.cloneNode(true),
reg = /\d+$/,
childElems;
allCurrent.push(clone);
allCurrent.forEach(function(fieldset, index) {
childElems = fieldset.querySelectorAll('[name]');
Array.prototype.forEach.call(childElems, function(elem) {
elem.name = reg.test(elem.name) ? elem.name.replace(reg, index) : elem.name + index;
});
toClone.parentNode.insertBefore(clone, toClone.nextSibling);
});
}
var addMore = document.getElementById('duplicate');
addMore.addEventListener('click', duplicate)
label {
display: block;
}
<!-- here we're using an actual <form> element -->
<form action="#" method="post">
<!-- using a fieldset to group the related fields together -->
<fieldset class="clinicalInformation">
<!-- the <legend> element semantically titles that group
of related fields -->
<legend class="form-title">
Clinical Information
</legend>
<!-- the <label> semantically associates a text-label
with a specific form-element; that form-element
(<input />, <textarea>, <select>) can appear within
the <label>, or the <label> can have a 'for' attribute
equal to the 'id' of the associated element. -->
<label class="form-title">Time Assesed:
<input class="form-field" type="time" name="timeassessd" />
</label>
<label class="form-title">Blood Pressure:
<input class="form-field" type="text" name="bp" />
</label>
<label class="form-title">Pulse:
<input class="form-field" type="date" name="pulse" />
</label>
<label class="form-title">Resp. Rate:
<input class="form-field" type="text" name="breathing" />
</label>
<label class="form-title">Temp:
<input class="form-field" type="text" name="temp" />
</label>
<label class="form-title">SPO<sub>2</sub>:
<input class="form-field" type="text" name="spo2" />
</label>
<label class="form-title">GCS:
<input class="form-field" type="text" name="gcs" />
</label>
<label class="form-title">AVPU:
<input class="form-field" type="text" name="avpu" />
</label>
</fieldset>
<fieldset>
<button id="duplicate" data-duplicates=".clinicalInformation">Add more</button>
</fieldset>
</form>
Using jQuery, however, since you've used that tag for your question:
// binding an anonymous click event-handler, using on():
$('#duplicate').on('click', function(event) {
// preventing the default action:
event.preventDefault();
// finding all elements that match the selector from
// the clicked-element's 'data-duplicates' attribute:
var allCurrent = $(this.dataset.duplicates),
// finding the last of those elements:
toClone = allCurrent.last(),
// creating the clone, including the child elements:
clone = toClone.clone(true),
// the regular expression (as above):
reg = /\d+$/;
// adding the clone to the 'allCurrent' collection,
// then iterating over them with each(), getting a
// reference to the index of each element in the collection:
allCurrent.add(clone).each(function(index) {
// finding all descendant elements that have a name attribute,
// updating the 'name' property of each of those found
// elements using prop():
$(this).find('[name]').prop('name', function(i, n) {
// the first argument (here: 'i') is the index of the
// current element in the collection,
// the second (here: 'n') is the current value of the
// current element's property.
// exactly the same as above:
return reg.test(n) ? n.replace(reg, index) : n + index;
});
});
// inserting the clone into the document
// after the toClone element:
clone.insertAfter(toClone);
});
$('#duplicate').on('click', function(event) {
event.preventDefault();
var allCurrent = $(this.dataset.duplicates),
toClone = allCurrent.last(),
clone = toClone.clone(true),
reg = /\d+$/;
allCurrent.add(clone).each(function(index) {
$(this).find('[name]').prop('name', function(i, n) {
return reg.test(n) ? n.replace(reg, index) : n + index;
});
});
clone.insertAfter(toClone);
});
label {
display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form action="#" method="post">
<fieldset class="clinicalInformation">
<legend class="form-title">
Clinical Information
</legend>
<label class="form-title">Time Assesed:
<input class="form-field" type="time" name="timeassessd" />
</label>
<label class="form-title">Blood Pressure:
<input class="form-field" type="text" name="bp" />
</label>
<label class="form-title">Pulse:
<input class="form-field" type="date" name="pulse" />
</label>
<label class="form-title">Resp. Rate:
<input class="form-field" type="text" name="breathing" />
</label>
<label class="form-title">Temp:
<input class="form-field" type="text" name="temp" />
</label>
<label class="form-title">SPO<sub>2</sub>:
<input class="form-field" type="text" name="spo2" />
</label>
<label class="form-title">GCS:
<input class="form-field" type="text" name="gcs" />
</label>
<label class="form-title">AVPU:
<input class="form-field" type="text" name="avpu" />
</label>
</fieldset>
<fieldset>
<button id="duplicate" data-duplicates=".clinicalInformation">Add more</button>
</fieldset>
</form>
References:
CSS:
Attribute-selectors.
HTML:
Embedding custom non-visible data with the data-* attributes.
<fieldset>.
<label>.
<legend>.
Using data attributes.
JavaScript:
Array.prototype.forEach().
Array.prototype.slice().
document.querySelectorAll().
Event.preventDefault().
EventTarget.addEventListener().
Function.prototype.call().
Guide to JavaScript regular expressions.
HTMLElement.dataset.
Node.cloneNode.
Node.insertBefore.
Node.parentNode.
RegExp.
RegExp.prototype.test().
String.prototype.replace().
jQuery:
add().
clone().
each().
find().
insertAfter().
last().
on().
prop().

Related

Need help to remove items dynamically using pure javascript

Requirements:
A new text box should appear with a delete button at closing after clicking '+Add Stop'.
If a delete(x) button is clicked, the respective text box should be removed and Stop #(sequence numbering) should be changed as well.
Need help on:
I have tried to achieve the both above requirements. I get results for #1. But for #2, After adding more items, the delete button works/removes only the last added item only but it should work the same for all items.
Stop # sequence number should be maintained after the removal of an item(s). I need help with this logic also.
HTML:
<form action="https://www.example.com" method="POST">
<label for="stype">Service Type:</label>
<select id="stype" name="service-type">
<option disabled="disabled" selected="selected">Choose Service</option>
<option value="From Airport">From Airport</option>
<option value="To Airport">To Airport</option>
</select><br/><br/>
<label for="fullname">Name: </label><input id="fullname" name="name" size="20" type="text" maxlength="20" placeholder="John Doe" required /><br/><br/>
<label for="phone">Phone: </label><input id="phone" name="phone" maxlength="12" type="tel" placeholder="012-345-6789" required /><br/><br/>
<label for="email">Email: </label><input id="email" name="email" size="30" type="email" maxlength="30" placeholder="contact#example.com" required /><br/><br/>
<label for="ptime">Pickup time </label><input id="ptime" name="pickup-time" type="time" required /><br/><br/>
<label for="pdate">Pickup Date </label><input id="pdate" name="pickup-date" type="date" required /><br/><br/>
<div id="add_stop_here">
</div>
<input type="button" id="add" value="+Add Stop" onclick="test();" />
</form>
JavaScript:
var counter = 0;
function test () {
counter += 1;
var addHtml = '\
<div class="input-box">\
<label for="stop'+counter+'">Stop '+counter+':</label>\
<input type="text" id="stop'+counter+'" name="stop"/ > <a id="rmv'+counter+'" class="remove_stop" href="#">x</a>\
</div>';
var add_hre = document.getElementById("add_stop_here");
add_hre.innerHTML += addHtml;
document.querySelector("#rmv"+counter)
.addEventListener('click', function(){
var removeEl = this.parentNode;
add_hre.removeChild(removeEl);
});
}
Some issues to take care of:
To make this work, I would refrain from using id attributes that have a sequential number. It is not best practice.
Instead, in order to link a label element with its input element, make the input element a child of the corresponding label element. Now the id and for attributes are no longer needed.
Don't use innerHTML += as that will reset the values of the inputs that are already in the document, and will remove the event listeners. Instead use insertAdjacentHTML.
To keep the numbering in pace, use a span element that only has that number, and renumber all those span elements after every change. You can also use it after an insert, just to keep the code clean, and avoid that you need to maintain a counter.
To avoid that you need to attach a new event handler for every new element, listen to click events on the container element, and then check in that single handler which element was clicked. This is called event delegation.
Don't name your function test. Give it a useful name, like insertBusStop.
Instead of binding that handler via HTML attribute, bind it via code.
For multi-line strings you can use back tick delimiters (template literals)
I'd suggest that after clicking the Add button, the focus is put on the newly created input element. This facilitates the input procedure for the user.
Here is how that would work:
var add_hre = document.getElementById("add_stop_here");
document.getElementById("add").addEventListener("click", addBusStop);
function addBusStop() {
var addHtml = `
<div class="input-box">
<label>
Stop <span class="stop_number"></span>
<input type="text" name="stop"/> <a class="remove_stop" href="#">x</a>
</label>
</div>`;
add_hre.insertAdjacentHTML("beforeend", addHtml);
renumber();
add_hre.querySelector(".input-box:last-child input").focus();
}
function renumber() {
let i = 1;
for (let labelSpan of add_hre.querySelectorAll(".stop_number")) {
labelSpan.textContent = i++;
}
}
// Use event delegation
add_hre.addEventListener('click', function(e) {
if (!e.target.classList.contains("remove_stop")) return;
var removeEl = e.target.parentNode.parentNode; // need one more level now
add_hre.removeChild(removeEl);
renumber();
});
<div id="add_stop_here"></div>
<input type="button" id="add" value="+Add Stop"/>
You can do this with each() and find() function easily.
var counter = 0;
$("#add").click(function () {
counter++;
$("#add_stop_here").append(
'<div class="input-box"><label for="stop' +
counter +
'">Stop' +
counter +
': <input type="text" id="stop' +
counter +
'" name="stop"/ ></label> <a id="rmv' +
counter +
'" class="remove_stop" href="#">X</a></div>'
);
});
$(document).on("click", ".remove_stop", function () {
$(this).closest("div").remove(); //use closest here
$("#add_stop_here .input-box").each(function (index) {
$(this)
.find("label:eq(0)")
.attr("id", "stop" + (index + 1));
$(this)
.find("label:eq(0)")
.html("Stop" + (index + 1) + '<input type="text" name="stop" />');
});
counter--;
});
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<form action="https://www.example.com" method="POST">
<label for="stype">Service Type:</label>
<select id="stype" name="service-type">
<option disabled="disabled" selected="selected">Choose Service</option>
<option value="From Airport">From Airport</option>
<option value="To Airport">To Airport</option></select
><br /><br />
<label for="fullname">Name: </label
><input
id="fullname"
name="name"
size="20"
type="text"
maxlength="20"
placeholder="John Doe"
required
/><br /><br />
<label for="phone">Phone: </label
><input
id="phone"
name="phone"
maxlength="12"
type="tel"
placeholder="012-345-6789"
required
/><br /><br />
<label for="email">Email: </label
><input
id="email"
name="email"
size="30"
type="email"
maxlength="30"
placeholder="contact#example.com"
required
/><br /><br />
<label for="ptime">Pickup time </label
><input id="ptime" name="pickup-time" type="time" required /><br /><br />
<label for="pdate">Pickup Date </label
><input id="pdate" name="pickup-date" type="date" required /><br /><br />
<div id="add_stop_here"></div>
<input type="button" id="add" value="+Add Stop" />
</form>

How do I input variables to change label text using javascript

I am trying to make it so that when the user inputs a names into the inputbox and then clicks the 'Enter Candidates' button, it will then change the name of the labels below. Is there a way to do this in javascript? i have just started coding so i am a bit of a newbie.
<form class="simple-form">
<div>Enter your candidate <b>names</b> in the boxes below:</div>
<br/>
<label for="C1">Candidate 1:</label>
<input type="text" name="C1" id="C1" class="InputBox" />
<br/>
<label for="C2">Candidate 2:</label>
<input type="text" name="C2" id="C2" class="InputBox" />
<br/>
<label for="C3">Candidate 3:</label>
<input type="text" name="C3" id="C3" class="InputBox" />
<br/>
<label for="C4">Candidate 4:</label>
<input type="text" name="C4" id="C4" class="InputBox" />
<br/>
<label for="C5">Candidate 5:</label>
<input type="text" name="C5" id="C5" class="InputBox" />
<br/>
<input type="button" OnClick="EnterCandidates" value="Enter Candidates" />
<br/>
<br/>
<div>Enter the candidates <b>votes</b> in the boxes below:</div>
<br/>
<label for="V1" id="L_V1">Name 1:</label>
<input type="text" name="V1" id="I_V1" class="InputBox" />
<br/>
<label for="V2" id="L_V2">Name 2:</label>
<input type="text" name="V2" id="I_V2" class="InputBox" />
<br/>
<label for="V3" id="L_V3">Name 3:</label>
<input type="text" name="V3" id="I_V3" class="InputBox" />
<br/>
<label for="V4" id="L_V4">Name 4:</label>
<input type="text" name="V4" id="I_V4" class="InputBox" />
<br/>
<label for="V5" id="L_V5">Name 5:</label>
<input type="text" name="V5" id="I_V5" class="InputBox" />
<br/>
<input type="button" OnClick="" value="Enter Votes" />
<br/>
</form>
Thanks everyone who helped me.
One more question.
I have decided to use this code (thanks #David Thomas):
function EnterCandidates() {
var candidateNameInputs = document.querySelectorAll('input[id^=C]'),
names = document.querySelectorAll('label[for^=V][id^=L_V]');
Array.prototype.forEach.call(names, function(label, index) {
if (candidateNameInputs[index].value !== candidateNameInputs[index].defaultValue) {
label.textContent = candidateNameInputs[index].value;
}
});
}
How do i add a verification so that the user can only use string and it has a certain character limit like 20 characters?
I tried to add one of your guys suggestions to it but i guess i did it wrong because it did not work.
You probably want to use
document.getElementById('Label ID').innerHTML = document.getElementById('Input ID').value
Please see here : http://jsfiddle.net/jzqp70oq/
Hope this is what you are expecting.
document.getElementById('L_V1').innerHTML= document.getElementById('C1').value;
//character validation
var val = document.getElementById('c2').value;
if (!val.match(/^[a-zA-Z]+$/))
{
alert('Only alphabets are allowed');
return false;
}
//Length validation
if (val.length >10) {
alert("characters are too long !")
}
Try this
<head>
<script type="text/javascript">
function test(){document.getElementById('Label_ID').innerHTML=document.getElementById('Input_ID').value;
}
</script>
</head>
//....
<input type="button" onClick="EnterCandidates();" value="Enter Candidates" />
//...
The following JavaScript achieves your desired output, I think:
function EnterCandidates() {
// Using document.querySelectorAll() to get the <input> elements
// whose id attribute/property starts with the upper-case letter C:
var candidateNameInputs = document.querySelectorAll('input[id^=C]'),
// finding the <label> elements whose 'for' attribute starts with
// the upper-case letter V, and whose id starts with the string "L_V":
names = document.querySelectorAll('label[for^=V][id^=L_V]');
// using Function.prototype.call() to iterate over the Array-like
// nodeList, returned by document.querySelectorAll, using an
// an Array method (Array.prototype.forEach()):
Array.prototype.forEach.call(names, function (label, index) {
// the first argument of the anonymous function ('label')
// is the array-element of the Array (or Array-like) structure
// over which we're iterating, and is a <label> element,
// the second argument ('index') is the index of that current
// element in the Array (or Array-like structure).
// if the value of the <input> at the same index in the collection
// as the current <label>'s index has a value that is not
// equal to its default-value:
if (candidateNameInputs[index].value !== candidateNameInputs[index].defaultValue) {
// we update the textcontent of the <label> to be
// equal to that of the value entered in the <input>
label.textContent = candidateNameInputs[index].value;
}
});
}
function EnterCandidates() {
var candidateNameInputs = document.querySelectorAll('input[id^=C]'),
names = document.querySelectorAll('label[for^=V][id^=L_V]');
Array.prototype.forEach.call(names, function(label, index) {
if (candidateNameInputs[index].value !== candidateNameInputs[index].defaultValue) {
label.textContent = candidateNameInputs[index].value;
}
});
}
label::before {
content: "\A";
white-space: pre;
}
label::after {
content: ': ';
}
label,
input {
box-sizing: border-box;
line-height: 1.4em;
height: 1.4em;
margin-bottom: 0.2em;
}
input[type=button]:last-child {
display: block;
}
<form class="simple-form">
<fieldset>
<legend>Enter your candidate <b>names</b> in the boxes below:</legend>
<label for="C1">Candidate 1</label>
<input type="text" name="C1" id="C1" class="InputBox" />
<label for="C2">Candidate 2</label>
<input type="text" name="C2" id="C2" class="InputBox" />
<label for="C3">Candidate 3</label>
<input type="text" name="C3" id="C3" class="InputBox" />
<label for="C4">Candidate 4</label>
<input type="text" name="C4" id="C4" class="InputBox" />
<label for="C5">Candidate 5</label>
<input type="text" name="C5" id="C5" class="InputBox" />
<input type="button" onclick="EnterCandidates()" value="Enter Candidates" />
</fieldset>
<fieldset>
<legend>Enter the candidates <b>votes</b> in the boxes below:</legend>
<label for="V1" id="L_V1">Name 1</label>
<input type="text" name="V1" id="I_V1" class="InputBox" />
<label for="V2" id="L_V2">Name 2</label>
<input type="text" name="V2" id="I_V2" class="InputBox" />
<label for="V3" id="L_V3">Name 3</label>
<input type="text" name="V3" id="I_V3" class="InputBox" />
<label for="V4" id="L_V4">Name 4</label>
<input type="text" name="V4" id="I_V4" class="InputBox" />
<label for="V5" id="L_V5">Name 5</label>
<input type="text" name="V5" id="I_V5" class="InputBox" />
<input type="button" value="Enter Votes" />
</fieldset>
</form>
JS Fiddle demo, for experimentation and development.
Please note that I edited your HTML structure as well, to try and make it more semantic in its structure; removed the <br> nodes, and switched to CSS to to break the elements into new-lines; used the <legend> elements to hold the 'instructions' for each section (removing the <div> element you originally used). Also, I grouped the associated elements together using <fieldset> elements to wrap the <label> and <input> groups together, along with the relevant 'control' button.
Further, since it made it slightly easier to update the text without having to add back 'presentation' strings (the colons), I used CSS to achieve that end in order that presentation could be easily updated without using search/replace when – inevitably – the design changes.
With regard to the update to the question, and the question left in comments:
is there a way to add a verification to this so that the user can only use letters of the alphabet. Also a character limit so that the user can only type <20 characters?And how do i implement it in this code? I will edit my post if there is an answer.
The answer, of course, is "yes," to do so I'd suggest the following approach:
function EnterCandidates() {
var candidateNameInputs = document.querySelectorAll('input[id^=C]'),
names = document.querySelectorAll('label[for^=V][id^=L_V]'),
// A regular expression literal; which means:
// the complete string, from the start (^)
// to the end ($) must comprise of characters
// a-z (inclusive), apostrophe (') and white-space
// (to allow O'Neill, for example); this must be
// zero to 20 characters in length ({0,20}) and
// is case-insensitive (i):
validity = /^[a-z'\s]{0,20}$/i,
// two empty/uninitialised variables for use within
// the forEach() loop:
tempNode, tempVal;
Array.prototype.forEach.call(names, function (label, index) {
// caching the candidateNameInputs[index] Node:
tempNode = candidateNameInputs[index];
// caching the value of that Node:
tempVal = tempNode.value;
// if the value of the Node is not equal to the default-value
// of the Node, AND the value of the Node matches the regular
// expression (returns true if so, false if not):
if (tempVal !== tempNode.defaultValue && validity.test(tempVal)) {
// we remove the 'invalid' class from the Node if
// it's present:
tempNode.classList.remove('invalid');
// update the text of the <label>:
label.textContent = tempVal;
// otherwise, if the value does not match (!) the
// the regular expression:
} else if (!validity.test(tempVal)) {
// we add the 'invalid' class-name to the
// Node:
tempNode.classList.add('invalid');
// and set the text of the <label> to
// its original state, by concatenating
// the string "Name " with the result of the
// current (zero-based) index of the <label>
// after adding 1 (to make it one-based):
label.textContent = 'Name ' + (index + 1);
// otherwise, if the value is equal to the default-value
// we do nothing other than remove the 'invalid'
// class-name from the <input> Node:
} else if (tempVal === tempNode.defaultValue) {
tempNode.classList.remove('invalid');
}
});
}
function EnterCandidates() {
var candidateNameInputs = document.querySelectorAll('input[id^=C]'),
names = document.querySelectorAll('label[for^=V][id^=L_V]'),
validity = /^[a-z'\s]{0,20}$/i,
tempNode, tempVal;
Array.prototype.forEach.call(names, function(label, index) {
tempNode = candidateNameInputs[index];
tempVal = tempNode.value;
if (tempVal !== tempNode.defaultValue && validity.test(tempVal)) {
tempNode.classList.remove('invalid');
label.textContent = tempVal;
} else if (!validity.test(tempVal)) {
tempNode.classList.add('invalid');
label.textContent = 'Name ' + (index + 1);
} else if (tempVal === tempNode.defaultValue) {
tempNode.classList.remove('invalid');
}
});
}
label::before {
content: "\A";
white-space: pre;
}
label::after {
content: ': ';
}
label,
input {
box-sizing: border-box;
line-height: 1.4em;
height: 1.4em;
margin-bottom: 0.2em;
}
input[type=button]:last-child {
display: block;
}
input.invalid {
border-color: #f00;
}
<form class="simple-form">
<fieldset>
<legend>Enter your candidate <b>names</b> in the boxes below:</legend>
<label for="C1">Candidate 1</label>
<input type="text" name="C1" id="C1" class="InputBox" />
<label for="C2">Candidate 2</label>
<input type="text" name="C2" id="C2" class="InputBox" />
<label for="C3">Candidate 3</label>
<input type="text" name="C3" id="C3" class="InputBox" />
<label for="C4">Candidate 4</label>
<input type="text" name="C4" id="C4" class="InputBox" />
<label for="C5">Candidate 5</label>
<input type="text" name="C5" id="C5" class="InputBox" />
<input type="button" onclick="EnterCandidates()" value="Enter Candidates" />
</fieldset>
<fieldset>
<legend>Enter the candidates <b>votes</b> in the boxes below:</legend>
<label for="V1" id="L_V1">Name 1</label>
<input type="text" name="V1" id="I_V1" class="InputBox" />
<label for="V2" id="L_V2">Name 2</label>
<input type="text" name="V2" id="I_V2" class="InputBox" />
<label for="V3" id="L_V3">Name 3</label>
<input type="text" name="V3" id="I_V3" class="InputBox" />
<label for="V4" id="L_V4">Name 4</label>
<input type="text" name="V4" id="I_V4" class="InputBox" />
<label for="V5" id="L_V5">Name 5</label>
<input type="text" name="V5" id="I_V5" class="InputBox" />
<input type="button" value="Enter Votes" />
</fieldset>
</form>
JS Fiddle demo, for experimentation and development.
References:
CSS:
::after pseudo-element.
::before pseudo-element.
content property.
HTML:
<fieldset>
<label>.
<legend>.
JavaScript:
Array.prototype.forEach().
Element.classList.
Function.prototype.call().
HTMLFieldSetElement.
HTMLLabelElement.
HTMLLegendElement.
JavaScript Regular Expressions Guide.
Node.textContent.
RegExp.prototype.test().

Input fields to text output

What im trying to do is create a webform that will take the information put into the fields to add to a predefined text. the code I have so far is as follows:
<form action="" method="post">
<input type="reset" value="Clear">
<p>
<input type="text" name="casenumber" value="Case Number" onclick="this.select()" size="25"/>
</p>
<p>
<input type="text" name="name" value="Name" onclick="this.select()" size="25" />
</p>
<p>
<input type="text" name="dealer code" value="Dealer Code" onclick="this.select()" size="25" />
</p>
<p>
<input type="text" name="cid" value="CID" onclick="this.select()" size="25" />
</p>
<p>
<input type="text" name="callback" value="Callback#" onclick="this.select()" size="25" />
</p>
<p>
<input type="text" name="authentication" value="Dealer Authentication" onclick="this.select()" size="25" />
</p>
<p>
<input type="text" name="email" value="Email" onclick="this.select()" size="25" />
</p>
<p>
<input type="text" name="ptn" value="PTN" onclick="this.select()" size="25" />
</p>
<p>
<input type="text" name="ban" value="BAN" onclick="this.select()" size="25" />
</p>
<p>
<input type="text" name="banauth" value="Ban Authentication" onclick="this.select()" size="25" />
</p>
<p>
<input type="text" name="type" value="Type of Request" onclick="this.select()" size="25" />
</p>
<p>
Actions Taken:<br/>
<textarea name="actions" rows="5" cols="50"></textarea>
</p>
<p>
<input type="submit" value="Submit" />
</p>
Now I want all of the information entered into these fields to be added to this
SFDC - TSO Case number: input inserted here
Dealer Name: input inserted here
Dealer code: input inserted here
CID: input inserted here
Callback#: input inserted here
Dealer Authentication: input inserted here
Email: input inserted here
PTN#: input inserted here
BAN: input inserted here
BAN Authentication: input inserted here
Type of Request: input inserted here
Actions Taken: input inserted here
Have not been able to find how to do this so any help is appreciated.
Try the following javascript function which is using the placeholder attribute to generate the titles of values for the text generated:
/**
* fId: the form id
* dId: the div id which want to add the text to it
**/
function printToDiv(fId, dId){
f = document.getElementById(fId);
i = f.getElementsByTagName('input');
iTxt = Array();
k = 0;
out = '';
for (j = 0; j < i.length; j++){
if (i[j].type == 'text'){
iTxt[k] = i[j];
k++;
}
}
for (n =0; n < iTxt.length; n++){
out += "<b>"+iTxt[n].placeholder+":</b> "+iTxt[n].value+"<br />\n";
}
div = document.getElementById(dId);
div.innerHTML = out;
}
A generalized DEMO could be found here or here. Ofcourse you can apply any validation for the data by calling any other function inside the regarded function and you can call it by any way you want, for example, from onsubmit event.
I think that you have to use a placeholder.
Look:
http://www.w3schools.com/tags/att_input_placeholder.asp
Exercise:
<form action="" method="POST">
<input type="text" name="X" placeholder="Some text..." />
</form>
If you don't care about language this could be easily done with JavaScript. Just add the class to all your inputs and add a span next to your defined text
<html>
<head>
<script src="https://code.jquery.com/jquery-2.1.4.min.js"></script>
</head>
<body>
<input id='txtCaseNumber' class="copyValue" placeholder="case number"/>
<input id='txtDealer' class="copyValue" placeholder="Dealer Name"/>
Case Number: <span data-inputId="txtCaseNumber"></span>
Dealer Name: <span data-inputId="txtDealer"></span>
<script>
$(document).ready(function(){
$(".copyValue").blur(function(){
var inputId = $(this).attr('id');
var ident = "span[data-inputId='" + inputId + "']";
$(ident).html($(this).val());
});
});
</script>
</body>
</html>
If I am understanding your question correctly. You could do something like this. But this is not the only way, it is just a way.
Sample HTML:
<div class="container">
<input type="text" value="something"/>
<input type="text" value="something"/>
<input type="submit" value="submit" id="submit"/>
</div>
<div id="output"></div>
JS:
var a = [
"SFDC - TSO Case number:",
"Dealer Name:",
"Dealer code:",
"CID:",
"Callback#:",
"Dealer Authentication:",
"Email:",
"PTN#:",
"BAN:",
"BAN Authentication:",
"Type of Request:",
"Actions Taken:"
];
var values = [];
$("#submit").on('click', function()
{
var form = $('.container');
var inputs = form.find('input').not('.exclude'); // add this class to the inputs you don't want to collect the values of, IE clear and submit
var l = inputs.length;
var html = '';
for(var i = 0; i < l; i++)
{
var value = inputs.eq(i).val();
values.push(value);
}
for(var i = 0, ln = a.length; i < ln; i++)
{
html += '<p>' + a[i] + ' ' + values[i] + '</p>';
}
$('#output').append(html);
});
Note: I used jQuery for this example and cleaned up / changed the HTML a bit.
Demo:
http://jsfiddle.net/prb75qvt/4/
If I understand you correctly, you want to take an text fron an input box and paste it somewhere else. Use this code template :
HTML CODE
(The onchange is optional, I just like to use it because it activates a function when the text changes)
<input id="newText" type="text" onchange="myFunction()">
<p>Your text</p><p id="oldText"></p>
JS CODE
("oldText" is used as a placeholder)
function myFunction() {
var inputText = document.getElementById("newText").value;
document.getElementById("oldText").innerHTML = inputText
}

Trying to set an html attribute to a javascript variable

I have a variable "count" in javascript and a radio button that I want to depend on that variable. There is a button to generate more radio buttons, which is why I need their name attributes to differ.
My code:
var count = 1;
function newForm(){
...<input name=count type="radio" value="Website" />...
}
But it's just setting the name of each additional radio button to "count" rather than the number "count" represents.
Here's the whole code:
var count = 1;
function newForm(){
var newdiv = document.createElement('div');
newdiv.innerHTML = '<div class="line"></div><br><input type="text" name="Name"
class="field" placeholder="Full Event Name" /><br><input type="text" name="Location"
placeholder="Event Location" class="field" /><br> <input type="text" name="Date"
placeholder="Event Date" class="field" /> <br> <input type="text" name="End"
placeholder="Event End Date (If Applicable)" class="field" /> <br> <input type="text"
name="Time" placeholder="Event Time" class="field" /> <br> <input type="text"
name="Tags"
placeholder="Relevant Tags" class="field" /> <br> The info is from: <input name=count
type="radio" value="Tweet" checked="" />Tweet <input name=count type="radio"
value="Website"
/>Website <input name=count type="radio" value="Tweet and Website" /> Tweet and
Website';
if(count < 10) {
document.getElementById('formSpace').appendChild(newdiv);
count++;
}
}
That newdiv.innerHTML string above is all on one line in the code, by the way.
If you're trying to create an element, use createElement() :
var count = 1;
function newForm(){
var input = document.createElement('input');
input.name = count;
input.type = 'radio';
input.value = 'Website';
}
in your long string of innerHTML you need to escape your "count" variable... otherwise it's just a string... i.e.
'<input name='+count+' type="radio" value="Tweet and Website" />';
That will make it work but as everyone else is mentioning - you really shouldn't embed long html strings like this.

Switch DIV elements up/down with jQuery/JS

I'm trying to move div elements of a dynamic form up or down:
Here is my form:
<form name="f_form">
Order name <input type="text" name="ord" id="order" />
<div id="fields">
<div id="hid1"><a href="#" id="did1">
<img src="d.jpg" /></a><a href="#" id="uid1">
<img src="u.jpg" /></a><input type="text" name="p_name[]" id="names" />
<input type="text" name="quant[]" id="quant" size="3" />
<input type="text" name="pr[]" id="price" size="10" />
<input type="text" name="sum_a" id="sum" size="10" disabled="disabled"/>
</div>
<input type="button" name="nauj" id="nau" value="Add item"/><br />
</div>
</form>
When I click "add item" button JS is called:
$("#nau").click(function () {
(newdiv = document.createElement('div')).id = "hid"+ (counter + 1) +"";
newdiv.innerHTML = '<img src="d.jpg" /><img src="u.jpg" /><input type="text" name="p_name[]" id="names" />
<input type="text" name="quant[]" id="quant" size="3" />
<input type="text" name="pr[]" id="price" size="10" />
<input type="text" name="sum_a" id="sum" size="10" disabled="disabled"/>X';
document.getElementById('fields').appendChild(newdiv);
counter++;
});
Each form fields row has two arrow (up and down) images: <img src="d.jpg" /><img src="u.jpg" />
when I click on arrow I need to move all row of form fields up or down (move <DIV id=hid..>) tried like this but it didint worked.. (move up function)
$("a[id^='uid']").on('click', function() {
var numrow = $(this).attr("id");
numrow = numrow.substr(3);
var nr = 1;
sumrow = numrow - nr;
var eil = 'id=' + numrow;
numrowas = "#hid"+numrow;
srowas = "#hid"+sumrow;
$(numrowas).before($(srowas));
});
Thanks for advices.
Same sort of solution as #WTK, using .prev(), but different approach. And oh, I couldn't resist and did some cleanup ;)
See http://jsfiddle.net/WmbmF/4/
First of all you're not using on() correctly - the event handler isn't binded as you would expect. The correct syntax would be:
// "watch for" elements matching selector "a[id^='did']" created inside #fields
$("#fields").on('click', "a[id^='did']", function(e) {...})
Second of all, you are trying to operate on id attributes to deremine after/before what div to append your current element. That's messy, a cleaner approach is using .next() and .prev() to determine what is the next or previous node in relation to the clicked one.
I've created a fiddle as an example: http://jsfiddle.net/SPgax/22/
Just as a side note: your code is messy, I didn't act on it because it's beyond scope of your question. No offence :)

Categories