Adding and removing dom sections with javascript - javascript

I want to be able to add new sections (via the 'add' link) and remove them (via the 'x' button) like seen in the image.
The HTML for the image:
<fieldset>
<legend>Legend</legend>
<div id="section0">
<input type="text" name="text1" value="Text1" />
<input type="text" name="text2" value="Text2" size='40' />
<input type="button" value="x" style="width: 26px" /><br />
</div>
add<br />
</fieldset>
I guess I could add new sections as needed (i.e. section1, section2) and delete those sections according to which button was pressed. There would be a javascript function that would inject sections in the DOM everytime the 'add' link was clicked and another for deleting a section everytime the 'x' button was clicked.
Since I have so little experience in HTML and Javascript I have no idea if this is a good/bad solution. So, my question is exactly that: Is this the right way to do it or is there a simpler/better one? Thanks.
P.S.: Feel free to answer with some sample code

Here's one way to do it:
<script type="text/javascript">
function newrow() {
document.getElementById("customTable").innerHTML += "<tr><td><input type='text'></td><td><input type='text'></td><td><button onclick='del(this)'>X</button></td></tr>";
}
function del(field) {
field.parentNode.parentNode.outerHTML = "";
}
</script>
<body onload="newrow()">
<fieldset>
<legend>Legend</legend>
<table>
<tbody id="customTable">
</tbody>
</table>
<button onclick="newrow()">Add</button>
</fieldset>
</body>
You could add IDs to them if you wanted, or you could call them by their position document.getElementsByTagName("input")[x].value The inputs would start at 0, so the left one is 0, right is 1, add row: left is 2, right is 3, etc.
If you delete one, the sequence isn't messed up (it re-evaluates each time), which is better than hard-coded IDs.

I just answered a nearly identical question only a few minutes ago here using jQuery: https://stackoverflow.com/a/10038635/816620 if you want to see how it worked there.
If you want plain javascript, that can be done like this.
HTML:
<div id="section0">
<input type="text" name="text1" value="Text1" />
<input type="text" name="text2" value="Text2" size='40' />
<input type="button" value="x" style="width: 26px" /><br />
</div>
add<br />
Javascript:
function addSection(where) {
var main = document.getElementById("section0");
var cntr = (main.datacntr || 0) + 1;
main.datacntr = cntr;
var clone = main.cloneNode(true);
clone.id = "section" + cntr;
where.parentNode.insertBefore(clone, where);
}​
Working demo: http://jsfiddle.net/jfriend00/TaNFz/

http://pastebin.com/QBMEJ2pq is a slightly longer but robust answer.

Related

JavaScript change value and data from value in a span

I need help with this. I need to make the value in the other place change all the time while user session is active. How can I get the value from a span and make other value in a data change?
Look at there!
1 <div class="pt-uea-container">
2 <span class="pt-uea-currency pt-uea-currency-before"> € </span>
3 <input type="text" class="pt-field pt-uea-custom-amount" autocomplete="off" name="pt_items[1][amount]" id="pt_uea_custom_amount_1" value="199" placeholder="" data-parsley-errors-container="#pt_uea_custom_amount_errors_1">
4 <input type="hidden" class="pt-field pt-uea-custom-amount-formatted" name="pt_items[1][amount]" value="199" data-pt-price="199">
5 <input type="hidden" name="pt_items[1][label]" value="Amount:">
6 <input type="hidden" name="pt_items[1][tax_percentage]" value="0">
7 <input type="hidden" name="pt_items[1][type]" value="open">
8 <div id="pt_uea_custom_amount_errors_1"></div>
9 <span class="form-price-value">85</span>
10 </div>
The value in row 9 needs to constantly change values in row 3 and 4 on the same session. Don't mind the value in row 6.
Let me know how I can get this done. Or maybe a different approach?
Greetings!
========
So this is what I got for now from you guys:
jQuery(document).ready(function($) {
var checkViewport = setInterval(function() {
var spanVal = $('.form-price-value').text();
$('#pt_uea_custom_amount_1').val(spanVal);
$('#pt_uea_custom_amount_formatted_1').val(spanVal);
$('#pt_uea_custom_amount_formatted_1').attr('data-pt-price', spanVal);
}, 1000);
});
This code works, but it only affects my needs when I put my mouse in pt-field pt-uea-custom-amount and add a space in it. Then it does apply to the page source. But this is not correct. The source needs to get changed too without touching that class or a space or something!
You can easily do this with the help of jQuery.
With the help of jQuery I would do like this.
Understanding what input field needs to be tracked for changes. I will give all this field a class (track-me).
In the document ready, I will look for changes for that tracked field.
On change of that field I will get the value and put in other input fields (class copy-to - or you can do whatever you like).
See an example below,
HTML
<form>
<div class="">
<input type="text" class="track-me" value=""/>
</div>
<div class="">
<input type="text" class="copy-to" value=""/>
</div>
<div class="">
<input type="text" class="copy-to" value=""/>
</div>
<div class="">
<input type="text" class="copy-to" value=""/>
</div>
<div class="">
<div class="">Please type anything in the first input box</div>
</div>
</form>
jQuery
$(document).ready(function(){
$('.track-me').change(function (){
$('.copy-to').val($(this).val())
});
});
I made comments in the above jQuery code so you can understand. Also, I have made a fiddle so you can play and have a look. In this fiddle, I am using Bootstrap4 just for the purpose of styling, you don't have to worry about that.
Link to fiddle
https://jsfiddle.net/anjanasilva/r21u4fmh/21/
I hope this helps. Feel free to ask me any questions if you have. Cheers.
This is not an ideal solution. I'm not sure there is a verified way of listening for when the innerHTML of a span element changes. This sort of stuff is usually based on user interaction, and the value of the span will be modified by your page. The best solution would be to use the same method that updates the span element to update the values of you hidden input fields.
However, I've placed an interval that will run every second, that takes the text value of the span element and gives it to the values of the 2 input fields:
function start() {
setInterval(function() {
document.getElementById("pt_uea_custom_amount_1").value = document.getElementById("price_value").innerHTML;
document.getElementById("pt_uea_custom_amount_2").value = document.getElementById("price_value").innerHTML;
}, 1000);
}
window.onload = start();
<div class="pt-uea-container">
<span class="pt-uea-currency pt-uea-currency-before"> € </span>
<input type="text" class="pt-field pt-uea-custom-amount" autocomplete="off" name="pt_items[1][amount]" id="pt_uea_custom_amount_1" value="199" placeholder="" data-parsley-errors-container="#pt_uea_custom_amount_errors_1">
<input type="hidden" class="pt-field pt-uea-custom-amount-formatted" name="pt_items[1][amount]" value="199" data-pt-price="199" id="pt_uea_custom_amount_2">
<input type="hidden" name="pt_items[1][label]" value="Amount:">
<input type="hidden" name="pt_items[1][tax_percentage]" value="0">
<input type="hidden" name="pt_items[1][type]" value="open">
<div id="pt_uea_custom_amount_errors_1"></div>
<span id="price_value" class="form-price-value">85</span>
</div>
MutationObserver should work here..
const formValuePrice = document.querySelector( '.form-price-value' );
const inputText = document.querySelector( 'input[type="text"]' );
// timer to change values
window.setInterval( () => {
formValuePrice.textContent = Math.round( Math.random() * 100 );
}, 1000 );
// mutation observer
const observer = new MutationObserver( ( mutationsList ) => {
inputText.value = formValuePrice.textContent;
} );
observer.observe( formValuePrice, { childList: true } );
https://codepen.io/anon/pen/LgWXrz?editors=1111
try this, simple using jquery, you can check in inspect element for value attribute data-pt-price
Update: you can using jquery event .on() like change, click, keyup or else to Attach an event handler function for one or more events to the selected elements,
you can read the doc here.
here the updated code
$(function() {
var spanVal = $('#price_value').text();
$('#pt_uea_custom_amount_1').val(spanVal);
$('#pt_uea_custom_amount_formatted_1').val(spanVal);
$('#pt_uea_custom_amount_formatted_1').attr('data-pt-price', spanVal);
$('#pt_uea_custom_amount_1').on('change click keyup', function() {
$('#pt_uea_custom_amount_formatted_1').val($(this).val());
$('#price_value').text($(this).val());
$('#pt_uea_custom_amount_formatted_1').attr('data-pt-price', $(this).val());
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="pt-uea-container">
<span class="pt-uea-currency pt-uea-currency-before"> € </span>
<input type="text" class="pt-field pt-uea-custom-amount" autocomplete="off" name="pt_items[1][amount]" id="pt_uea_custom_amount_1" value="199" placeholder="" data-parsley-errors-container="#pt_uea_custom_amount_errors_1">
<input type="hidden" class="pt-field pt-uea-custom-amount-formatted" name="pt_items[1][amount]" value="199" data-pt-price="199" id="pt_uea_custom_amount_2">
<input type="hidden" name="pt_items[1][label]" value="Amount:">
<input type="hidden" name="pt_items[1][tax_percentage]" value="0">
<input type="hidden" name="pt_items[1][type]" value="open">
<div id="pt_uea_custom_amount_errors_1"></div>
<span id="price_value" class="form-price-value">85</span>
</div>

Javascript Add Row to HTML Table & Increment ID

This is my first post on this site so hopefully you will go easy on me. I'm trying to create an HTML / PHP form and use a small piece of Javascript to add additional rows to a table when a button is clicked and increment the ID for the two fields.
The button works in adding the rows however it doesn't seem to increment the ID, just use the same ID as the previous row. Hopefully someone could help?
$(window).load(function(){
var table = $('#productanddates')[0];
var newIDSuffix = 2;
$(table).delegate('#button2', 'click', function () {
var thisRow = $(this).closest('tr')[0];
var cloned = $(thisRow).clone();
cloned.find('input, select').each(function () {
var id = $(this).attr('id');
id = id.substring(0, id.length - 1) + newIDSuffix;
$(this).attr('id', id);
});
cloned.insertAfter(thisRow).find('input:date').val('');
newIDSuffix++;
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="blue-bar ta-l">
<div class="container">
<h1>Submit Your Insurance Renewal Date(s)</h1>
</div>
</div>
<div class="grey-bar">
<div class="container">
<div class="rounded-box">
<div>
<label for="name">Name</label>
<input type="text" id="name" name="name" autocomplete="off" required />
</div>
<div>
<label for="name">Renewal Dates</label>
</div>
<table width="100%" border="0" cellspacing="0" cellpadding="5" id="productanddates" class="border">
<tr>
<td>
<select name="insurance_type1" id="insurance_type1">
<option></option>
<option>Car</option>
<option>Home</option>
<option>Van</option>
<option>Business</option>
<option>GAP</option>
<option>Travel</option>
</select>
</td>
<td>
<input type="date" name="renewal_date1" id="renewal_date1" />
</td>
<td>
<input type="button" name="button2" id="button2" value="+" />
</td>
</tr>
</table>
<div>
<label for="telephone_number">Contact Number</label>
<input type="tel" id="telephone_number" name="telephone_number" pattern="\d{11}" autocomplete="off" required />
</div>
<div>
<label for="email">Email Address</label>
<input type="email" id="email" name="email" autocomplete="off" required />
</div>
<div>
<input name="submit" type="submit" value="Submit" class="btn">
</div>
</div>
cloned.insertAfter(thisRow).find('input:date').val('');
This line isn't correct. It will throw an invalid selector error.
You need to change it to:
cloned.insertAfter(thisRow).find('input[type="date"]').val('');
jQuery actually does support the :INPUT-TYPE format in selectors, but not the new HTML5 input types (yet): so using input[type="date"] here is the correct way for now to select an element with an HTML5 type. Please notice the quotes around the value. If you want to select an attribute with a certain value.
A selector overview of css selectors here: W3schools.
Because this line is throwing an error your newIDSuffix never gets updated, because the script halts at the line before that because of the script error.
#Charlietfl raises a valid point about learning more about classes and DOM traversal. However that will not fix this code. Or explain why your code isn't working. Nevertheless it's a good tip.
I've gone ahead an taken a stab at a cleaner version of what I think that you are trying to accomplish. I'll walk through the major updates:
Updated the button id and name from "button2" to "button1" - I assumed that you would want to keep the indices in sync across the inputs in each row.
Changing $(window).load(function() { to $("document").ready(function() { - While either will work, the former will wait until all images have finished loading, while the latter while fire once the DOM has completed building. Unless you REALLY want the images to load first, I'd recommend $("document").ready(), for faster triggering of the code.
Removing the [0] references - the primary reason to use [0] after a jQuery selector collection is to reference the DOM version of the selected jQuery element, in order to us a "vanilla" JavaScript method on it. In all cases, you were re-rwapping the variables in $(...), which just converted the DOM element back into a jQuery object, so that extra step was not needed.
Changed the .delegate() method to .on() - as Howard Renollet noted, that is the correct method to use for modern versions of jQuery. Note that the "event" and "target" parameters have swapped places in on, from where they were in delegate.
Changed the event target from #button2 to :button - this will make sure that all of the buttons in the new rows will also allow you to add additional rows, not just the first one.
Switched the clone target from the clicked row to the last row in the table - this will help keep your row numbering consistant and in ascending order. The cloned row will always be the last one, regardless of which one was clicked, and the new row will always be placed at the end, after it.
Changed the indexing to use the last row's index as the base for the new row and use a regular expression to determine it - with the table being ordered now, you can always count on the last row to have the highest index. By using the regular expression /^(.+)(\d+)$/i, you can split up the index value into "everything before the index" and "the index (i.e., on or more numbers, at the end of the value)". Then, you simply increment the index by 1 and reattach it, for the new value. Using the regex approach also allows you to easily adapt, it there ever get to be more than 9 rows (i.e., double-digit indices).
Updated both the id and name attributes for each input - I assumed that you would want the id and name attributes to be the same for each individual element, based on the initial row, and, you were only updating the id in your code, which would have caused problems when sending the data.
Changed $("input:date") to $("input[type='date']) - as Mouser pointed out, this was really the core reason why your code was failing, initially. All of the other changes will help you avoid additional issues in the future or were simply "code quality"-related changes.
So . . . those were the major updates. :) Let me know if I misunderstood what you were trying to do or if you have any questions.
$("document").ready(function() {
$('#productanddates').on('click', ':button', function () {
var lastRow = $(this).closest('table').find("tr:last-child");
var cloned = lastRow.clone();
cloned.find('input, select').each(function () {
var id = $(this).attr('id');
var regIdMatch = /^(.+)(\d+)$/;
var aIdParts = id.match(regIdMatch);
var newId = aIdParts[1] + (parseInt(aIdParts[2], 10) + 1);
$(this).attr('id', newId);
$(this).attr('name', newId);
});
cloned.find("input[type='date']").val('');
cloned.insertAfter(lastRow);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="blue-bar ta-l">
<div class="container">
<h1>Submit Your Insurance Renewal Date(s)</h1>
</div>
</div>
<div class="grey-bar">
<div class="container">
<div class="rounded-box">
<div>
<label for="name">Name</label>
<input type="text" id="name" name="name" autocomplete="off" required />
</div>
<div>
<label for="name">Renewal Dates</label>
</div>
<table width="100%" border="0" cellspacing="0" cellpadding="5" id="productanddates" class="border">
<tr>
<td>
<select name="insurance_type1" id="insurance_type1">
<option></option>
<option>Car</option>
<option>Home</option>
<option>Van</option>
<option>Business</option>
<option>GAP</option>
<option>Travel</option>
</select>
</td>
<td>
<input type="date" name="renewal_date1" id="renewal_date1" />
</td>
<td>
<input type="button" name="button1" id="button1" value="+" />
</td>
</tr>
</table>
<div>
<label for="telephone_number">Contact Number</label>
<input type="tel" id="telephone_number" name="telephone_number" pattern="\d{11}" autocomplete="off" required />
</div>
<div>
<label for="email">Email Address</label>
<input type="email" id="email" name="email" autocomplete="off" required />
</div>
<div>
<input name="submit" type="submit" value="Submit" class="btn">
</div>
</div>
cloned.insertAfter(thisRow).find('input[type="date"]').val('');

Issue with creating clones of HTML div using JQuery

I am trying to create clones of a HTML div. The div has a label and two text boxes inside it. I need to change the label value of the newly created div. Here is my code.
<body>
<div id="PayDiv2">
<label id="PayLbl2">Payment No 2: </label>
<input type="text" />
<input type="text" />
</div>
<div id ="totPayForm" >
<label id="totPayLbl">Total Payment: </label>
<input type="text" />
<input type="text" />
<input type="submit" value="Add new one" onclick="addNewField();
return false;">
</div>
<input type="button" value="Clone box" id="btn" />
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script>
var i=3;
//When DOM loaded we attach click event to button
$(document).ready(function() {
$('#btn').click(function() {
var cloned = $('#PayDiv2').clone();
cloned.insertBefore("#totPayForm");
$('#PayLbl2').html("Payment No "+ i++ + ':');
});
});
</script>
</body>
The problem is the place the newly created clones placed. First clone get placed before everything(even though I need to place it after the original div which I used to create divs. )
divs generated after that also get placed at first and, early divs goes down. It is hard to describe here. If you can be kind enough to run my code you will see what the issue is.
I have an another requirement to generate unique ids to cloned divs. Since I am new in JQuery, I found it difficult to generate id's.
I am pleased if you can help me in this case. Thank you all.
The problem is $('#PayLbl2').html("Payment No "+ i++ + ':'); it always changes the first element's label instead of the clone(because of the duplicated ids)...
so use class instead of id
<div class="PayDiv2">
<label class="PayLbl2">Payment No 2:</label>
<input type="text" />
<input type="text" />
</div>
then
var i = 3;
//When DOM loaded we attach click event to button
$(document).ready(function () {
$('#btn').click(function () {
var cloned = $('.PayDiv2').first().clone();
cloned.insertBefore("#totPayForm");
cloned.find('.PayLbl2').html("Payment No " + i+++':');
});
});
Demo: Fiddle
Here it is.
Demo
Make your HTML like below
<div id="PayDiv0" class="PayDiv0">
<label id="PayLbl0" class="PayLbl2">Payment No 2:</label>
<input type="text" />
<input type="text" />
</div>
<div id="totPayForm">
<label id="totPayLbl">Total Payment:</label>
<input type="text" />
<input type="text" />
<input type="submit" value="Add new one" onclick="addNewField();
return false;">
</div>
<input type="button" value="Clone box" id="btn" />
And JS should be like this
var i = 3;
$(document).ready(function () {
$('#btn').click(function () {
var cloned = $('.PayDiv0').first().clone();
var noOfDivs = $('.PayDiv0').length;
cloned.insertBefore("#totPayForm");
cloned.attr('id', 'PayDiv' + noOfDivs);
cloned.find('label').attr('id', 'PayLbl' + noOfDivs);
cloned.find('.PayLbl2').html("Payment No " + i+++':');
});
});
As mentioned in the answer by #Arun P Johny, set the div id PayDiv0
$('#btn').click(function () {
var cloned = $('.PayDiv2').first().clone();
// find total divs with class PayDiv2
var noOfDivs = $('.PayDiv2').length;
cloned.insertBefore("#totPayForm");
// add new id to the cloned div
cloned.attr('id', 'PayDiv' + noOfDivs);
// find the label element inside new div and add the new id to it
cloned.find('label').attr('id', 'PayLbl' + noOfDivs);
cloned.find('.PayLbl2').html("Payment No " + i+++':');
});
this way you can add the dynamic ids to your elements.

How to remove a particular div tag and reset its content using javascript

Code below contains certain tags in all four.
Image-1
here is the code :
<div style='background-color:YellowGreen;height:20px;width:100%;margin-top:15px;font-weight: bold;'>
Delegate(s) details: </div>
<div style="border:1px solid black;"><br/>
<div id="delegates">
<div id="0">
Name of the Delegate:
<input name='contact_person[]' type='text' size="50" maxlength="50" />
Designation:
<select name='delegate_type_name[]' class='delegate_type'>
<option value='select'>Select</option>
<option value='Main'>Main</option>
</select>
</div><br/>
</div>
<div>
<input type="button" name="more" value="Add More Delegates" id="add_more" />
<br />
<br />
</div>
</div>
In the above code on line 5 where <div id="0"> changes to value 1 in script that I mentioned in "add_more"
And the javascript for "add_more" is given below
jQuery('#add_more').click(function(){
var id = jQuery('#delegates > div:last').attr('id');
var temp = "<div id='"+(parseInt(id)+parseInt('1'))+"'> Name of the Delegate: <input type='text' size='50' maxlength='50' name='contact_person[]' /> Designation:";
temp += "<select name='delegate_type_name[]' class='delegate_type additional_delegate'><option value='select'>Select</option><option value='Additional'>Additional</option><option value='Spouse'>Spouse</option></select> <input type='button' name='rem' value='Remove' id='remove' /></div><br/>";
jQuery('#delegates').append(temp);
});
In the javascript code above I have added a remove button in the temp+ variable
<input type='button' name='rem' value='Remove' id='remove' />
Image-2 shows the remove button every time I click on "Add more Delegates" button.
In the image-2 I click on Add More Delegates button it shows the "remove" button on the right of drop down select list.
I want a jQuery function for remove button, so that when I click on remove it should remove <div id="1"> and also reset content before removing the div tag. Below image-3 is the output that I want when I click on remove button.
code that I tried was this from some reference is this
jQuery('#remove').click(function(){
var id = jQuery('#delegates > div:last').attr('id').remove();
});
but no luck.
Thanks.
You can't give an element id that is only a number, it must be #mydiv1, #mydiv2 or something similar, i.e. beginning with a letter not a number.
For starters your markup is a total mess. There is no way you should be using for layout purposes. Read up on tableless layouts and css.
The first thing you need to change is the id's of your div. An id cannot start with a numeric. I suggest naming the first div delegate0. Secondly, you are adding a remove button on every new row with the same id - all id's on a page should be unique so i suggest you change this to class="remove".
As for your question, it really boils down to needing to add a jQuery handler to the remove buttons using the .livedocs method.
This is as simple as:
jQuery('.remove').live('click',function(){
$(this).closest('div').remove();
});
Also, you need to keep a running counter of the id of the items added, and increment this every time a new row is added.
var nextDelegate = 1;
jQuery('#add_more').click(function(){
... your code here
nextDelegate++;
});
Also, I removed the superfluous <br/> after each div.
Live example: http://jsfiddle.net/cb4xQ/

How can I concatenate value in HTML and JavaScript?

For example
<input type="text" name="disp">
<input type="button" name="but0" value="0" onclick=""+"calc.disp.value=0"+"">
Here if I click the button 0 means it should display the 0 in text box. If I click the button it should concatenate in that box. But it replaces that is the code is wrong.
As far as I understand it, you want each button click to add 0 to the text box contents. So it starts out empty, and when you push the button the first time, the contents changes to 0. Pushing it a second time changes the contents to 00.
Assuming that's correct, try this:
<input type="text" name="disp">
<input type="button" name="but0" value="0" onclick="calc.disp.value=calc.disp.value + '0';">
If you are allowed to use jQuery I would suggest that as the code needed then becomes a lot easier to see what is going on:
First add an id attribute to each input.
<input type="text" name="disp" id="textBox">
<input id="button0" type="button" name="but0" value="0">
you want to add 0s? so if you entered 1 then you hit the 0 button it will show 10 then again will change to 100:
<script type="text/ecmascript">
$(document).ready(function()
{
$("#button0").click(function()
{
var textVal = $("#textBox").val();
$("#textBox").val(textVal + 0);
});
});
</script>
Example here
Hi you can do it by following way
<input type="text" name="tst" id="tst">
<input type="button" value="0" onclick="javascript:document.getElementById('tst').value = document.getElementById('tst').value + this.value "
var sum = document.getElementById("id1").value
+ document.getElementById("id2").value
+ document.getElementById("id3").value;

Categories

Resources