I have a row of text boxes , I have a function to clone them based on what number comes into the function. So if there are going to be 4 users then I want the row to clone 4 times to enter the information of the 4 users. But I also want some way to be able to submit this form , I am having trouble figuring out how to give each row a unique class or id for each text box so I can read through them when submitting.
I was thinking adding "1" to each class (or id) to everything in the first row, then "2" to everything in the second. But I am not too sure as to how to do this. I have an example Here In jsFiddle , Since I have tried to add the for loop and clone a certain amount of times , now the clone isn't even working at all- If anyone has any suggestions , it would really help me out.
<div class="RegisterContainer">
<div class="RegisterHead"><a>Register Attendees</a></div>
<div class="placenewrows"></div>
</div>
<br />
<input type="button" onclick="fnCloneTemplate({'number' : '3'});" value="make 3 rows">
<div class="_template">
<a class="left1">First Name:</a>
<a class="left2"></a><a class="left2">Last Name:</a>
<a class="left3">Phone #</a><a class="left4">Email:</a>
<a class="left5">Optional Comment</a><br />
<input type="text" class="tFirstName left1"/>
<input type="text" class="tLastName left2"/>
<div class="phonenumberbox left3">
<input type="text" class="first3digits" maxlength="3" />
<a style="position:relative;top:-1px;">-</a>
<input type="text" class="next3digits" maxlength="3" />
<a style="position:relative;top:-1px;">-</a>
<input type="text" class="last4digits" maxlength="4" />
</div> <input type="text" class="tEmail left4"/>
function fnCloneTemplate(x){
var NumofClones = (x.number * 1);
for(i=0; i <= NumofClones; i++)
{
var newrow = $('._template').clone().removeclass('_template');
$('.placenewrows').append(newrow);
}
}
There is a typo in your code:
var newrow = $('._template').clone().removeclass('_template');
//----^
removeclass should be removeClass.
http://jsfiddle.net/y543n/
Also you haven't loaded jQuery in your fiddle and there is a scoping issue there, you are using HTML onclick attribute and your function in that context is not defined. You can use jQuery click method instead:
$('input[type=button]').click(function(e){
e.preventDefault();
// ....
})
$('input[type=button]').click(function(e) {
var numofClones = 3;
e.preventDefault();
var b = $('.placenewrows input[type=text]').length;
var newrow = $('._template').clone().removeClass('_template').find('input[type=text]').addClass(function(i, cur) {
return 'something' + ++b
}).end()
for (i = 0; i < numofClones; i++) {
$('.placenewrows').append(newrow);
}
})
http://jsfiddle.net/bgCXX/
You can change your function like below, to avoid multiple time cloning.
function fnCloneTemplate(e){
var NumofClones = (e.data.number * 1),
newrow= $('._template').clone().removeClass('_template'); // in your code
// removeClass spelling
// mistaken
for (i=0; i<NumofClones; i++)
{
$('.placenewrows').append(newrow);
}
}
Using on():
HTML
<input type="button"value="make 3 rows" id="make_clone">
jQuery
function fnCloneTemplate(e){
var NumofClones = (e.data.number * 1),
newrow= $('._template').clone().removeClass('_template');
for (i=0; i<NumofClones; i++)
{
$('.placenewrows').append(newrow);
}
}
$('#make_clone').on('click',{'number' : '3'}, fnCloneTemplate);
THE DEMO
Full Code for clone and unique class
function fnCloneTemplate(x) {
var NumofClones = (x.data.number * 1),
clone = $('._template').clone().removeClass('_template');
for (i = 0; i <= NumofClones; i++) {
var newrow = clone
.find('input[type=text]')
.attr('class', function(i, oldClass) {
return oldClass.replace(/\d/, function(char) {
return +char + i ;
});
return newClass
})
.end();
$('.placenewrows').append(newrow);
}
}
Related
How do I get the next element in HTML using JavaScript?
Suppose I have three <div>s and I get a reference to one in JavaScript code, I want to get which is the next <div> and which is the previous.
use the nextSibling and previousSibling properties:
<div id="foo1"></div>
<div id="foo2"></div>
<div id="foo3"></div>
document.getElementById('foo2').nextSibling; // #foo3
document.getElementById('foo2').previousSibling; // #foo1
However in some browsers (I forget which) you also need to check for whitespace and comment nodes:
var div = document.getElementById('foo2');
var nextSibling = div.nextSibling;
while(nextSibling && nextSibling.nodeType != 1) {
nextSibling = nextSibling.nextSibling
}
Libraries like jQuery handle all these cross-browser checks for you out of the box.
Really depends on the overall structure of your document.
If you have:
<div></div>
<div></div>
<div></div>
it may be as simple as traversing through using
mydiv.nextSibling;
mydiv.previousSibling;
However, if the 'next' div could be anywhere in the document you'll need a more complex solution. You could try something using
document.getElementsByTagName("div");
and running through these to get where you want somehow.
If you are doing lots of complex DOM traversing such as this I would recommend looking into a library such as jQuery.
Well in pure javascript my thinking is that you would first have to collate them inside a collection.
var divs = document.getElementsByTagName("div");
//divs now contain each and every div element on the page
var selectionDiv = document.getElementById("MySecondDiv");
So basically with selectionDiv iterate through the collection to find its index, and then obviously -1 = previous +1 = next within bounds
for(var i = 0; i < divs.length;i++)
{
if(divs[i] == selectionDiv)
{
var previous = divs[i - 1];
var next = divs[i + 1];
}
}
Please be aware though as I say that extra logic would be required to check that you are within the bounds i.e. you are not at the end or start of the collection.
This also will mean that say you have a div which has a child div nested. The next div would not be a sibling but a child, So if you only want siblings on the same level as the target div then definately use nextSibling checking the tagName property.
Its quite simple. Try this instead:
let myReferenceDiv = document.getElementById('mydiv');
let prev = myReferenceDiv.previousElementSibling;
let next = myReferenceDiv.nextElementSibling;
There is a attribute on every HTMLElement, "previousElementSibling".
Ex:
<div id="a">A</div>
<div id="b">B</div>
<div id="c">c</div>
<div id="result">Resultado: </div>
var b = document.getElementById("c").previousElementSibling;
document.getElementById("result").innerHTML += b.innerHTML;
Live: http://jsfiddle.net/QukKM/
This will be easy...
its an pure javascript code
<script>
alert(document.getElementById("someElement").previousElementSibling.innerHTML);
</script>
all these solutions look like an overkill.
Why use my solution?
previousElementSibling supported from IE9
document.addEventListener needs a polyfill
previousSibling might return a text
Please note i have chosen to return the first/last element in case boundaries are broken.
In a RL usage, i would prefer it to return a null.
var el = document.getElementById("child1"),
children = el.parentNode.children,
len = children.length,
ind = [].indexOf.call(children, el),
nextEl = children[ind === len ? len : ind + 1],
prevEl = children[ind === 0 ? 0 : ind - 1];
document.write(nextEl.id);
document.write("<br/>");
document.write(prevEl.id);
<div id="parent">
<div id="child1"></div>
<div id="child2"></div>
</div>
You can use nextElementSibling or previousElementSibling properties
<div>
<span id="elem-1">
span
</span>
</div>
<div data-id="15">
Parent Sibling
</div>
const sp = document.querySelector('#elem-1');
let sibling_data_id = sp.parentNode.nextElementSibling.dataset.id;
console.log(sibling_data_id); // 15
Tested it and it worked for me. The element finding me change as per the document structure that you have.
<html>
<head>
<script type="text/javascript" src="test.js"></script>
</head>
<body>
<form method="post" id = "formId" action="action.php" onsubmit="return false;">
<table>
<tr>
<td>
<label class="standard_text">E-mail</label>
</td>
<td><input class="textarea" name="mail" id="mail" placeholder="E-mail"></label></td>
<td><input class="textarea" name="name" id="name" placeholder="E-mail"> </label></td>
<td><input class="textarea" name="myname" id="myname" placeholder="E-mail"></label></td>
<td><div class="check_icon icon_yes" style="display:none" id="mail_ok_icon"></div></td>
<td><div class="check_icon icon_no" style="display:none" id="mail_no_icon"></div></label></td>
<td><div class="check_message" style="display:none" id="mail_message"><label class="important_text">The email format is not correct!</label></div></td>
</tr>
</table>
<input class="button_submit" type="submit" name="send_form" value="Register"/>
</form>
</body>
</html>
var inputs;
document.addEventListener("DOMContentLoaded", function(event) {
var form = document.getElementById('formId');
inputs = form.getElementsByTagName("input");
for(var i = 0 ; i < inputs.length;i++) {
inputs[i].addEventListener('keydown', function(e){
if(e.keyCode == 13) {
var currentIndex = findElement(e.target)
if(currentIndex > -1 && currentIndex < inputs.length) {
inputs[currentIndex+1].focus();
}
}
});
}
});
function findElement(element) {
var index = -1;
for(var i = 0; i < inputs.length; i++) {
if(inputs[i] == element) {
return i;
}
}
return index;
}
that's so simple
var element = querySelector("div")
var nextelement = element.parentElement.querySelector("div+div")
Here is the browser supports https://caniuse.com/queryselector
I want to dynamically add the id and for attribute for each input and label element.
<div id="splash">
<div class="tab">
<input id="tab-1">
<label for="tab-1"><label>
</div>
<div class="tab">
<input id="tab-2">
<label for="tab-2"><label>
</div>
<div class="tab">
<input id="tab-3">
<label for="tab-3"><label>
</div>
</div>
So basically I would want the id for the input to be tab-# with the # increasing by 1 for each input field and the same for the "for=" attribute for the label.
It's super easy. Just iterate through each .tab, using each's index argument, and modify the attributes of the elements.
$('.tab').each(function (index) {
var tabName = 'tab-' + (index + 1);
$('input', this).attr('id', tabName);
$('label', this).attr('for', tabName);
});
Jsbin: http://jsbin.com/rawatag/4/edit?html,js,output
Ok.
I won't give you a straight answer but this should be more useful in future.
Basically make the container <div id=splash>
Then run this command document.getElementById("parentID").innerHTML += "Something here"
This will add the content (pay attention to. The += sign) to the div (splash)
Then, just wrap this in a loop using a counter to get the desired result
Eg: ...innerHTML += "<div id=tab-" + counter + "></div>"
Note that this can be done in raw JS. No JQuery required.
No need for jQuery here:
es5 (jsfiddle)
function assignInputsAndLabels(root) {
var children = root.children;
var tabNumber = 1;
for (var i = 0; i < children.length; i++) {
if (children[i].classList.contains('tab')) {
children[i].getElementsByTagName('input')[0].setAttribute('id', 'tab-' + tabNumber);
children[i].getElementsByTagName('label')[0].setAttribute('for', 'tab-' + tabNumber);
tabNumber++;
}
}
}
assignInputsAndLabels(document.getElementById('splash'));
es6
function assignInputsAndLabels(root) {
const children = root.children;
let tabNumber = 1;
for (let i = 0; i < children.length; i++) {
if (children[i].classList.contains('tab')) {
children[i].getElementsByTagName('input')[0].setAttribute('id', `tab-${tabNumber}`);
children[i].getElementsByTagName('label')[0].setAttribute('for', `tab-${tabNumber}`);
tabNumber++;
}
}
}
assignInputsAndLabels(document.getElementById('splash'));
The parameter to the function is the wrapper of the elements that have the class of tab. In your case, you'd pass in the DOM node of the element with id of splash. So you'd call the function like this:
assignInputsAndLabels(document.getElementById('splash'));
I have done it using javascript.Check it below
function init(){
var sel = document.getElementsByClassName("tab");
var i=1;
for(let obj of sel){
var attr = "tab-"+i;
obj.getElementsByTagName('input')[0].setAttribute("id",attr);
obj.getElementsByTagName('label')[0].setAttribute("for",attr);
i++;
}
}
addEventListener("load",init);
<div class="tab">
<input type="text">
<label></label>
</div>
<div class="tab">
<input type="text">
<label></label>
</div>
So, I have the following jquery code that clones an element when the input value in a certain field increases.
$(document).ready(function(){
$("#nmovimentos").change(function () {
var direction = this.defaultValue < this.value
this.defaultValue = this.value;
if (direction)
{
var $div = $('div[id^="novomov"]:last');
var num = parseInt( $div.prop("id").match(/\d+/g), 10 ) +1;
var $clone = $div.clone().prop('id', 'novomov'+ num)
$clone.insertAfter('[id^="novomov"]:last');
}
else $('[id^="novomov"]:last').remove();
});
});
However, it clones a div that contains part of a form with lots of input fields.
<div id="novomov1" class="novomov">
<table id="tab">
<tr name="linear1" id="linear1">
<td>
Cardinalidade:<input type="text" name="card1" id="card1" value=""><br>
Angulo 1:<input type="text" name="param1" id="angulo1" value=""><br>
Angulo 2:<input type="text" name="param2" id="angulo2" value=""><br>
Tamanho:<input type="text" name="param3" id="tamanho1" value=""><br>
Descricao:<input type="text" name="descricao1" id="descricao1" value=""><br>
Tempo:<input type="text" name="tempo1" id="tempo1" value=""><br>
</td></tr></table></div>
I need to change the names of all the cloned div's descendents, in order to pass these paramaters to a data base. I thought of incrementing the names by 1, using the var num in the jquery function. However I'm I little lost.. so, any clues on how to do that? thank you very much!
Code changed to retrieve all the inputs inside the cloned div and change its name/id.
<script>
$(document).ready(function(){
$("#nmovimentos").change(function () {
var direction = this.defaultValue < this.value
this.defaultValue = this.value;
if (direction)
{
var $div = $('div[id^="novomov"]:last');
var num = parseInt( $div.prop("id").match(/\d+/g), 10 ) +1;
var $clone = $div.clone().prop('id', 'novomov'+ num)
$clone.insertAfter('[id^="novomov"]:last');
// get all the inputs inside the clone
var inputs = $clone.find('input');
// for each input change its name/id appending the num value
$.each(inputs, function(index, elem){
var jElem = $(elem); // jQuery element
var name = jElem.prop('name');
// remove the number
name = name.replace(/\d+/g, '');
name += num;
jElem.prop('id', name);
jElem.prop('name', name);
});
}
else $('[id^="novomov"]:last').remove();
});
});
</script>
Instead of parsing the id of the element to get the number you should use the data attribute. Also since you are using jQuery you can use .last() to get the last element with that id. Hope this helps.
$('#nmovimentos').on('change', function () {
var direction = this.defaultValue < this.value,
$last = $('#novomov').last(),
$clone,
num;
this.defaultValue = this.value;
if (direction) {
// add id in a data attribute instead of parsing the id
num = parseInt($last.data('id'), 10) + 1;
// set clone id data attribute to have the latest number
$clone = $last.clone().data('id', num);
// add clone after the last div
$last.after($clone);
} else {
$last.remove();
}
});
I got a table that has an entry that looks like this:
<tr>
<td><input type="checkbox" name="ids[]"/><a style="cursor: pointer;" onclick="addtopath('parameter1', 'parameter2')" class="btn_addpath"> Add</a></td>
</tr>
As you can see every table entry countains the function "addtopath('parameter1', 'paramter2');"
The parameters are generated via php; so each item is different. Also, every entry has a checkbox. This is where the trouble occurs.
I want to create a function that runs the "addtopath" function for every table item, that is checked, as if the user clicked the "Add" button.
Hope it makes sense.
Modern browsers...
function runChecked() {
var links = mytable.querySelectorAll("input[name='ids[]']:checked + a.btn_addpath");
[].forEach.call(links, function(link) {
link.onclick();
});
}
IE8+...
function runChecked() {
var inputs = mytable.querySelectorAll("input[name='ids[]']");
for (var i = 0; i < inputs.length; i++) {
if (inputs[i].checked)
inputs[i].nextSibling.onclick();
}
}
IE6+...
function runChecked() {
var inputs = mytable.getElementsByTagName("input");
for (var i = 0, len = inputs.length; i < len; i++) {
if (inputs[i].name === "ids[]" && inputs[i].checked)
inputs[i].nextSibling.onclick();
}
}
I would add the parameters to data attributes in case you want to move to jQuery at some point. It's also good practice.
<td><input type="checkbox" data-one="one" data-two="two" class="btn_addpath"/>Add</td>
<td><input type="checkbox" data-one="three" data-two="four" class="btn_addpath"/>Add</td>
<td><input type="checkbox" data-one="five" data-two="six" class="btn_addpath"/>Add</td>
<td><input type="checkbox" data-one="seven" data-two="eight" class="btn_addpath"/>Add</td>
function addToPath(p1, p2) {
console.log(p1, p2);
}
var checkboxes = document.getElementsByClassName('btn_addpath');
var checkboxArr = [].slice.call(checkboxes);
checkboxArr.forEach(function (el) {
var p1 = el.getAttribute('data-one');
var p2 = el.getAttribute('data-two');
el.onchange = function () {
if (this.checked) { addToPath(p1, p2); }
};
});
If you use jQuery you can use the following code:
$("input[type=checkbox]:checked").siblings('a').click();
Test it at http://jsfiddle.net/tMe46/
This should emulate onClick event at all links in checked boxes
$("input[type=checkbox]:checked + a").click();
I am trying to figure out how to add on the value of the selected input button into the textarea.
This is my input button to call the action:
<input type="button" id="scorebutton" value="TD">
<input type="button" id="scorebutton" value="PAT" name="PAT">
<input type="button" id="scorebutton" value="SFTY" name="Safety">
When each of the button is selected, the following javascript runs, respectively:
function addHTD(){document.getElementById("HScore").innerHTML=parseInt(document.getElementById("HScore").innerHTML,10) +6;}
function addHPT(){document.getElementById("HScore").innerHTML ++;}
function addHSF(){document.getElementById("HScore").innerHTML=parseInt(document.getElementById("HScore").innerHTML,10) +2;}
Then the score is recorded, adding 6, 1, and 2. But it is recorded in a textarea:
<td width="220px"><textarea class="lap" id="Hlapdetails"></textarea></td>
With this javascript running:
function marklapH()
{
if(runningstate == 1)
{
if(lapdate != '')
{
var lapold = lapdate.split(':');
var lapnow = stopwatch.value.split(':');
var lapcount = new Array();
var x = 0
for(x; x < lapold.length; x++)
{
lapcount[x] = new Array();
lapcount[x][0] = lapold[x]*1;
lapcount[x][1] = lapnow[x]*1;
}
if(lapcount[1][1] < lapcount[1][0])
{
lapcount[1][1] += 60;
lapcount[0][1] -= 1;
}
if(lapcount[2][1] < lapcount[2][0])
{
lapcount[2][1] += 10;
lapcount[1][1] -= 1;
}
}
lapdate = stopwatch.value;
Hlapdetails.value += (++lapcounter) + '. ' + stopwatch.value + '\n';
}
}
My question is how can I get the TD, PAT, and SFTY to be recorded with the marking of time in the textarea. To look like so:
0:24 TD
0:35 PAT
etc.
Any help would be greatly appreciated.
Thanks
do you want this
function addHTD(element)
{
document.getElementById("HScore").innerHTML=(parseInt(document.getElementById("HScore").innerHTML,10) +6)+element.value;
}
function addHPT(element)
{
document.getElementById("HScore").innerHTML= (document.getElementById("HScore").innerHTML+1)+element.value;
}
function addHSF(element)
{
document.getElementById("HScore").innerHTML=(parseInt(document.getElementById("HScore").innerHTML,10) +2)+element.value;
}
to make above work you will need to modify html like this
<input type="button" id="scorebutton" value="TD">
<input type="button" id="scorebutton" value="PAT" name="PAT">
<input type="button" id="scorebutton" value="SFTY" name="Safety">
I bascially did the next best thing. I copied the marklap three times and then changed the function names and the outcome to match each selection. and this works.
Thanks for all of your help.