The fieldset in now cloning without retaining data from the previous fieldset as I intended. Thank you RobG and ATOzTOA for all your help.
The only problem I'm having now is the calendar is nonfunctional in the cloned fieldsets.
I have looked through several threads where people have had the same problem as me and I apologize for creating another thread on the subject.
Script for calendar dropdown.
<!-- calendar dropdown -->
<script>
$(document).ready(function() {
$("#datepicker").datepicker();
});
</script>
Script to clone the fieldset.
<!-- clone fieldset -->
<script>
var _counter = 0;
function Add() {
_counter++;
var oClone = document.getElementById("template").cloneNode(true);
oClone.id += (_counter + "");
document.getElementById("placeholder").appendChild(oClone);
var inputs = oClone.getElementsByTagName('input');
for (var i=0, iLen=inputs.length;
i<iLen; i++) {
inputs[i].value = '';
}
}
</script>
Fieldset to be cloned.
<div id="placeholder">
<!-- template -->
<div id="template">
<!-- event fieldset -->
<fieldset>
<label class="field-first" required>Event: *<input type="text" name="event" value="" /></label>
<label class="field-first" required>Date: *<input type="text" id="datepicker" name="date" value="" /></label>
<label class="field-first" required>Net Request Amount: *<input type="text" name="request" value="" /></label>
<div class="description"><p>Please type a <strong><em>DETAILED</em></strong> description of the item/event/activity:<br /></p></div>
<textarea name="describe" cols="60" rows="10" required></textarea>
<!-- event fieldset -->
</fieldset>
<!-- template -->
</div>
<!-- placeholder -->
</div>
<!-- buttons -->
<button class="right-button" type="submit" name="submit" value="Submit">Submit</button>
<button class="left-button" "btn" type="button" name="Submit" onclick="Add();">Add New Event</button>
Presumably you are adding content to the labels. You can use getElementsByTagName to get the labels from the clone, then set their innerHTML to '' (empty string) to remove any child nodes (or loop over the child nodes and remove them, but setting the innerHTML property is simpler). While looping over the labels, you can modify any other properties that might need it.
If you just want to clear the value of the input elements, same strategy only use getElementsByTagName('input') and set their value property to `` (empty string).
Note that you have three input elements with a name of "first_name". It doesn't seem like a good idea to do that when none of them seems to be a first name. Use a name that represents the data they hold or the purpose to which it will be put. It also doesn't seem to be necessary to have one with an ID of "datepicker". Either remove the ID, or if you need it (unlikley), modify the value so it's unique to each cloned fragment.
Edit
To use getElementsByTagName to set the input values to "":
var inputs = oClone.getElementsByTagName('input');
for (var i=0, iLen=inputs.length; i<iLen; i++) {
inputs[i].value = '';
}
You will have to traverse through each element in the frameset and set text() to "".
var div = document.getElementById('template'):
var labels = div.getElementsByTagName('label');
for (var i = 0; i < divs.length; i += 1) {
code = labels[i].innerHTML;
// As there is a input element inside the label, we have to modify the HTML code
codeArray = code.split('<');
codeArray[0] = '';
code = codeArray.join('<');
labels[i] = code;
}
Related
I need to get the value of all elements with a certain attribute.
I have a lot elements like this one
<input data-ini="3" class="form-control" type="time">
The attribute is day_of_week_ini, where i'm going to receive a day of the week in a function like this one
function createNewPeriod(day_of_week){
//i should have all values inside an array
}
//EDIT
I need to do that with jquery
/*input[data-ini] is the css selector. second parameter of jQuery map function is DOM element, so we retrieved the attr value using jquery. $(element) convert the DOM element to jQuery object.*/
var a = $('input[data-ini]').map((index,element)=> $(element).attr('data-ini'));
console.log(a);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<body>
<!-- A series of html time controls with data attribute data-ini -->
<input data-ini="3" class="form-control" type="time" value="18:00">
<input data-ini="4" class="form-control" type="time" value="16:00">
<input data-ini="5" class="form-control" type="time" value="02:00">
<input data-ini="6" class="form-control" type="time" value="03:00">
</body>
You should use data attribute for cases like this as developer said and set value attribute for your elements as it is edited now.
Then you can use below jQuery code.
var allElements = jQuery("[data-ini]");
var myArray = [];
for(var i = 0; i < allElements.length; i++) {
myArray.push(allElements[i].val());
}
I'm not really sure the best way to go about this but I've laid the framework.
Basically, I would like to add the functionality so that when my #moreItems_add button is clicked and calls the moreItems function, I simply want to add a new Input field below it, and so on. I want to limit this to 10 fields though, so I show that in the function.
The only trick is, I will be submitting all fields via ajax to save to the database, so I need to try and keep track of an ID with each.
What's the best way to continue the javascript here so that I can append an input field on button press and keep track of IDs for each?
<div class="modal-body">
<form id="Items">
<label id="ItemLabel">Item 1:</label>
<input type="text" name="Items[]">
<button id="moreItems_add" onclick="moreItems()" id="moreItems">More Items</button>
</form>
</div>
<div class="modal-footer">
<input type="submit" name="saveItems" value="Save Items">
</div>
<!-- modal JS -->
<script type="text/javascript">
function moreItems(){
var MaxItems = 10;
//If less than 10, add another input field
}
</script>
You can use the jQuery .insertBefore() method to insert elements right before "more items" button. Below is the code representing this:
var maxItems = 1;
function moreItems() {
if (maxItems < 10) {
var label = document.createElement("label");
label.id="ItemLabel"+maxItems;
label.innerHTML = "Item "+(maxItems+1)+": ";
var input = document.createElement("input");
input.type='text';
input.name = 'item'+maxItems;
$('<br/>').insertBefore("#moreItems_add");
$(label).insertBefore("#moreItems_add");
$(input).insertBefore("#moreItems_add");
maxItems++;
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="modal-body">
<form id="Items">
<label id="ItemLabel">Item 1:</label>
<input type="text" name="Items[]">
<button type="button" id="moreItems_add" onclick="moreItems()" id="moreItems">More Items</button>
</form>
</div>
<div class="modal-footer">
<input type="submit" name="saveItems" value="Save Items">
</div>
Something like this should do the trick:
<!-- modal JS -->
<script type="text/javascript">
var MAX_ITEMS = 10,
added = 0;
function moreItems(){
if (added >= MAX_ITEMS) return;
var newField = document.createElement('input');
newField.type = 'text';
// TODO: Any field setup.
document.getElementById('items').appendChild(newField);
added++;
}
</script>
In terms of tracking each field with an ID, that should always be done by the back-end for data integrity and safety reasons.
some years ago I've wrote an article about making a repeated section using jQuery.
The live example is available on jsFiddle.
In the example you can find that both "add" and "remove" button are available, however you can set just the "add" button for your purpose.
The idea to limit to specific number of repeated boxes is to watch the number of repeatable elements just created in the context. The part of code to change in the live example is rows 13-18:
// Cloning the container with events
var clonedSection = $(theContainer).clone(true);
// And appending it just after the current container
$(clonedSection).insertAfter(theContainer);
There you should check if the number of repeated elements is less than <your desired number> then you will allow the item to be created, else you can do something else (like notice the user about limit reached).
Try this:
const maxItens = 10,
let itensCount = 0;
function moreItems() {
if (itensCount++ >= maxItens) {
return false;
}
let newInput = document.createElement('input');
// use the iterator to make an unique id and name (to submit multiples)
newInput.id = `Items[${itensCount}]`;
newInput.name = `Items[${itensCount}]`;
document.getElementById('items').appendChild(newInput);
return false;
}
Add type "button" to stop submiting the page (also, your button have two ID):
<button id="moreItems_add" onclick="moreItems();" type="button">More Items</button>
The submit button must be inside the form to work:
<form>
<div class="modal-body">
<div id="Items">
<label id="ItemLabel">Item 1:</label>
<input type="text" name="Items[]">
</div>
<button id="moreItems_add" onclick="moreItems()" id="moreItems">More Items</button>
</div>
<div class="modal-footer">
<button type="submit">Save Items</button>
</div>
</form>
To append itens in sequence the button must be outside of div "itens".
I want to be able to display the same piece of html code 10 times under the div called: <div id="add_remove_product_name"> By clicking on the button called: <button id="add_another_product_name">. I think I need some kind of a for loop for the job but are not sure. Any suggestion will be helpful, thanks.
My HTML code:
<div id="product_name">
<input id="skriv_produktnavn" placeholder="Skriv Produktnavn her" required></label>
<button id="add_another_product_name">Tilføj endnu et produktnavn</button>
<div id="add_remove_product_name">
<input id="added_product_name" placeholder="Skriv Produktnavn her" required></label>
<button id="remove_product_name">X</button>
</div>
Use a for loop to concatenate 10 copies of the HTML code. Then use .after() to put this after the DIV.
$("#add_another_product_name").click(function() {
var html = '';
for (var i = 0; i < 10; i++) {
html += 'html code that you want to repeat';
}
$("#add_remove_product_name").after(html);
}
You can use jQuery clone() however when cloning an element all the attributes will be the same. Fo example they will all have the same id attribute which will cause problems and it is not valid html
So in order to do the clone correctly you have fix the cloned element
DEMO: http://jsfiddle.net/rpyt445e/
var $tpl = $('#product_name').clone();
var num = 0
$('#clone').click(function () {
num++;
var $cloned = $tpl.clone();
$cloned.attr('id', $tpl.attr('id') + '_' + num);
$(':not([id=""])', $cloned).each(function(){
$(this).attr('id', $(this).attr('id') + '_'+num);
});
$cloned.appendTo('#wrapper');
});
HTML:
<div id="wrapper">
<div id="product_name">
<input id="skriv_produktnavn" placeholder="Skriv Produktnavn her" required />
<button id="add_another_product_name">Tilføj endnu et produktnavn</button>
<div id="add_remove_product_name">
<input id="added_product_name" placeholder="Skriv Produktnavn her" required />
<button id="remove_product_name">X</button>
</div>
</div>
</div>
<button id="clone">Clone</button>
A technique for adding the additional elements without having to create ugly strings of html in the JavaScript is to start with one hidden set of the elements in the html. At page load time, you remove that set, but keep a reference to it. Then when you want to add a set to the page, you clone the set you removed. All of this is easier if you add a container div around the additional inputs.
You also need to make sure id attribute values are unique. In the case of the remove buttons, you can replace the id with a class. As for the input id values, if you really need them, you can add an index value to them.
Since the remove buttons are dynamically added, I suggest using event delegation when binding the click-handler.
HTML:
<div id="product_name">
<input id="skriv_produktnavn" placeholder="Skriv Produktnavn her" required="required"/>
<button id="add_another_product_name">Tilføj endnu et produktnavn</button>
<div id="additional_product_names">
<div class="add_remove_product_name" style="display: none;">
<input id="added_product_name" placeholder="Skriv Produktnavn her" required="required"/>
<button class="remove_product_name">X</button>
</div>
</div>
</div>
JavaScript:
$(function() {
var MAX = 10;
var $addBtn = $('#add_another_product_name'),
$additionalContainer = $('#additional_product_names');
$TEMPLATE = $additionalContainer.children(':first').remove();
function update() {
var $additonalDivs = $additionalContainer.children();
// Enable/disable the add button.
$addBtn.prop('disabled', $additonalDivs.length >= MAX);
// Re-index the "id" attributes.
$additonalDivs.find('input').attr('id', function(i) {
return 'added_product_name[' + i + ']';
});
}
$addBtn.click(function() {
$TEMPLATE.clone().appendTo($additionalContainer).show();
update();
});
$('#product_name').on('click', '.remove_product_name', function() {
$(this).closest('.add_remove_product_name').remove();
update();
});
});
jsfiddle
I'm trying to add the rows dynamically plus auto-increment of a counter.I want to start with 1 then 2 then 3 and so on . I have added my code on plunker ,in which every time the max value is getting in first column like 4 then 1,1,2,3.Where am i going wrong ?i Want it to be 1,2,3,4.
Here is the plunker link http://plnkr.co/edit/GuDbJ3SHOPvWkHfNfd8E?p=preview
var _counter = 0;
function Add() {
_counter++;
var oClone = document.getElementById("template").cloneNode(true);
oClone.id += (_counter + "");
document.getElementById("placeholder1").appendChild(oClone);
document.getElementById("myVal").value=_counter;
}
<div id="placeholder1">
<div id="template">
<div>
Value:<input type="text" id="myVal" placeholder="1">
Quantity:<input type="text" placeholder="Qty">
<input type="button" onClick="Add()" value="Click! ">
</div>
</div>
I think it is because you have multiple divs with the id="myVal". The id attribute should be unique on the page. If not, your page will still load, but you may have unexpected behavior.
You are changing the id of the template div, but not the myVal div.
I assume you are looking for something like this:
var _counter = 0;
function Add() {
_counter++;
var oClone = document.getElementById("template").cloneNode(true);
oClone.id += (_counter + "");
document.getElementById("placeholder1").appendChild(oClone);
oClone.getElementsByClassName("myVal")[0].value = _counter;
}
<div id="placeholder1">
<div id="template">
<div>
Value:
<input type="text" class="myVal" placeholder="1">Quantity:
<input type="text" placeholder="Qty">
<input type="button" onClick="Add()" value="Click! ">
</div>
</div>
</div>
In your original you are cloning your template with the same id for the input. So when you do document.getElementById("myVal").value=_counter;, you only get the first input. I changed it to use class instead and get the input with the appropriate class that is a child of the cloned node.
I want the following functionality in my webpage :-
when the add button is clicked, an entire div should get appended to a span. To achieve this I have attempted the below, but it does not seem to be working. Please explain why and how can i get this done.
<html>
<head>
<script type="text/javascript">
function add()
{
var details=document.getElementById('education');
var eachDetail=document.getElementById('fdetails_edu_div');
alert(details.getAttribute('id'));
alert(eachDetail.getAttribute('id'));
var x=details.appendChild(eachDetail);
alert(x);
}
</script>
</head>
<body>
<span id="education">
<div id="fdetails_edu_div">
<label>EDUCATIONAL QUALIFICATION
<span class="small">Click on 'ADD' to add more qualifiaction details</span>
</label>
<button type="button" name="addqualifiaction" onclick="add()">ADD</button>
<br>
<br>
<br>
<label>Degree
<span class="small">School/Board</span>
</label>
<p>
<input type="text" name="school_board" id="fdegree" size="30" maxlength="30" value="none" class="fprjtit"/>
</p>
<br>
<br>
<br>
<label>Year
<span class="small">Year of Passing</span>
</label>
<p>
<input type="text" name="pass_year" id="fdegree" size="30" maxlength="30" value="none" class="fprjtit"/>
</p>
<br>
<br>
<br>
<label>Max Marks
<span class="small">maximum marks</span>
</label>
<p>
<input type="text" name="max_marks" id="fdegree" size="30" maxlength="30" value="none" class="fprjtit"/>
</p>
</div>
</span>
</body>
</html>
now when i click on the add button the div with the id "fdetails_edu_div" should get appended as a child, preferably to the bottom, of the span with the id "education".
What is wrong with the below and how can it be corrected?
I think you need to clone the div with id fdetails_edu_div
Use the following code
var x = 1;
function add() {
var container = document.getElementById('education');
var detail = document.getElementById('fdetails_edu_div');
var clone = detail.cloneNode(true);
clone.id = "fdetails_edu_div" + x;
x++;
container.appendChild(clone);
}
Notice, I create a new id for the newly created div.
Also note, I have removed the Add button from within the div fdetails_edu_div and placed it outside (you don't want the add button to repeat, do you?)
See working fiddle
The usage of appendChild() is move an element from one element to another,check this.
Based on your code, you move the 'eachDetail' to 'details', but 'eachDetail' is already there. It works like you remove the 'eachDetail' and then add it again in the 'details', so nothing happens.
You can replace 'details' with another element, a new span.
Try this code
function add()
{
var arr = [];
var n = 0;
var details=document.getElementById('education');
var eachDetail=document.getElementById('fdetails_edu_div');
alert(details.getAttribute('id'));
alert(eachDetail.getAttribute('id'));
node = document.getElementById("fdetails_edu_div");
while (node.firstChild) {
arr[n++] = node.firstChild;
node.removeChild(node.firstChild);
}
for(var i = 0; i < n; ++i) {
details.appendChild(arr[i]);
}
alert(eachDetail.parentNode.getAttribute('id'));
}
Above code first removes the child nodes of div with id fdetails_edu_div, saves them temporarily and later appends them to span with id education. You can check this with alert(eachDetail.parentNode.getAttribute('id'));