cloning template Jquery - javascript

I have a rather long complicated form to be used to record field data. One section of the form requires the ability to add a "Field Blank" section with no data recorded AND the ability to add a duplicate section where everything (including the data from the field blank section) is duplicated. The only different thing that would change on the duplicate would be the SampleID
The field blank script
<script>
var counter = 0;
function moreFields() {
counter++;
var newFields = document.getElementById('readroot').cloneNode(true);
newFields.id = '';
newFields.style.display = 'block';
var newField = newFields.childNodes;
for (var i=0;i<newField.length;i++) {
var theName = newField[i].name
if (theName)
newField[i].name = theName + counter;
}
var insertHere = document.getElementById('writeroot');
insertHere.parentNode.insertBefore(newFields,insertHere);
}
</script>
The duplicate script
<script>
$(document).ready(function(){
var template_index=0;
$("#add_FieldDup").click(function(){
template_index++;
$(this).parent().before($("#template").clone().attr("id","template" + template_index));
$("#template" + template_index).css("display","inline");
$("#template" + template_index + " :input").each(function(){
$(this).attr("name",$(this).attr("name") + template_index);
$(this).attr("id",$(this).attr("id") + template_index);
});
$("#remove_Dup" + template_index).click(function(){
$(this).closest("fieldset").remove();
});
});
});
</script>
My form
<h3>Water Samples</h3>
<fieldset id="template"> <!--for the duplicate-->
<div id="template"> <!--for the duplicate-->
Sample ID: <input type="text" id="SampleID" name="SampleID"></div>
<div class="_40" data-role="controlgroup" data-mini="true" data-type="horizontal">
<label> Collection Method</label><br />
<input type="radio" id="radGrab" value="grab" name="Collection" />
<label for="radGrab">Grab</label>
<input type="radio" id="radEWI" value="EWI" name="Collection" />
<label for="radEWI">EWI</label>
</div>
<fieldset> <!--For the field blank-->
<div id="readroot" class="hidden"> <!--For the field blank-->
QA Sample ID:<input type="text" id="QASampleID" name="QASampleID">
<div class="_30" data-role="controlgroup" data-mini="true" data-type="horizontal">
<label>Collection Method</label><br />
<input type="radio" id="radGrab1" value="Grab" name="Collection1" />
<label for="radGrab1">Grab</label>
<input type="radio" id="radEWI1" value="EWI" name="Collection1" />
<label for="radEWI1">EWI</label></div>
</div>
<label class="analysis-label" for="analysis">Analyte:</label>
<select class="analysis" id="analysis" name="analysis" data-iconpos="left" data-icon="grid">
<option>Select</option>
<option value = "TN">TN</option>
<option value = "TP,NO2+3">TP,NO2+3</option>
</select>
<label class="preserve-label" for="preserve">Preserved</label>
<select class="select_preserve" id="preserve" name="preserve" data-iconpos="left" data-icon="grid">
<option>Select</option>
<option value = "HNO3">HNO₃</option>
<option value = "H2SO4">H₂SO₄</option>
</select>
<label class="cool-label" for="cool">Cooled</label>
<select class="select_cool" id="cool" name="cool" data-iconpos="left" data-icon="grid">
<option>Select</option>
<option value = "Ice">Ice</option>
<option value = "Frozen">Frozen</option>
<option value = "None">None</option>
</select>
</div> <!--Fieldblank-->
</fieldset> <!--Fieldblank -->
<hr /><span id="writeroot"></span>
</div> <!--duplicate template-->
</fieldset> <!--duplicate template-->
<button type="button" data-theme="b" data-icon="plus" id="moreFields" onclick="moreFields()">ADD FIELD BLANK</button>
<button type="button" data-theme="b" data-icon="plus" id="add_FieldDup">ADD FIELD DUP</button>
I got the duplicate to work (when the field blank wasn't hidden) but I cannot get the field blank to work. Any assistance would be greatly appreciated!

You should extract your javascript from your dom, put it in separate js and make function work in any of this blocks, create class="template" block and inside give any needed interaction buttons and inputs classes so there can exist multiple parent elements with same inside structure... then cloning does not get in a way of your interaction logic.
In js go like:
$(document).ready(function() {
$(".template .interaction_button_one").on('click', function(){
//... here you go traversing like
$(this).parents('.template').find('.some_important_div').show();
})
});
Notice .on(), this is delegation, and it will give same interaction bindings to all of your elements.

Related

dynamically add and removing div with javascript

presently stuck in situation. trying to create a form where one can dynamically add and remove div elements where necessary,so far have been a to DYNAMICALLY ADD, problem is if i try to REMOVE div,only the last created gets to delete whilst others remain(excluding the parent div)KINDLY ASSIST.
<!doctype html>
<html lang="en">
<head>
</head>
<body>
<div id="box">
<div id='div' style="background: #99CCFF; height: 100px; width:300px" >
<p>Degree Level: <select id="dropdown">
<option value="Doctorate Degree">Doctorate Degree</option>
<option value="Masters">Masters</option>
<option value="Bachelors Degree">Bachelors Degree</option>
<option value="SSCE">SSCE</option>
</select></p>
<label for="firstname">School Name</label>
<input type="text" placeholder="Your Role"">
<label for="from">From</label>
<input type="text" id="from" name="from">
<br>
<label for="to">to</label>
<input type="text" id="to" name="to">
</div>
</div>
<div>
<button id="submit1">Add new div</button>
<input type="button" value="Remove Element"
onClick="removeElement('box','div');">
</div>
</body>
<script>
var box = document.getElementById('box'),
template = box.getElementsByTagName('div'),
template = template[0];
var counter = 1;
submit1.onclick = function () {
var new_field = template.cloneNode(true);
new_field.id = new_field.id + counter++
console.log(new_field.id)
box.appendChild(new_field);
return false;
};
</script>
<script>
function removeElement(boxDiv, divDiv){
if (divDiv == boxDiv) {
alert("The parent div cannot be removed.");
}
else if (document.getElementById(divDiv)) {
var div = document.getElementById(divDiv);
var box = document.getElementById(boxDiv);
box.removeChild(div);
}
else {
alert("Child div has already been removed or does not exist.");
return false;
}
}
You are passing the string div to your remove element function which will only remove the first div.
You can find all the children elements and then remove the last child
Building on your previous code, see the snippet below
var box = document.getElementById('box'),
template = box.getElementsByTagName('div'),
template = template[0];
console.log(template);
var counter = 1;
submit1=document.getElementById("submit1");
submit1.onclick = function () {
var new_field = template.cloneNode(true);
new_field.id = new_field.id + counter++
console.log(new_field.id)
box.appendChild(new_field);
return false;
};
function removeElement(boxDiv){
var box = document.getElementById(boxDiv);
if(box.children){
console.log(box.children);
box.children[box.children.length-1].outerHTML="";
}
}
<div id="box">
<div id='div' style="background: #99CCFF; height: 100px; width:300px" >
<p>Degree Level: <select id="dropdown">
<option value="Doctorate Degree">Doctorate Degree</option>
<option value="Masters">Masters</option>
<option value="Bachelors Degree">Bachelors Degree</option>
<option value="SSCE">SSCE</option>
</select></p>
<label for="firstname">School Name</label>
<input type="text" placeholder="Your Role"">
<label for="from">From</label>
<input type="text" id="from" name="from">
<br>
<label for="to">to</label>
<input type="text" id="to" name="to">
</div>
</div>
<div>
<button id="submit1">Add new div</button>
<input type="button" value="Remove Element"
onClick="removeElement('box');">
</div>
It might be because js thinks you're only selecting the last one when doing
var div = document.getElementById(divDiv);
Try doing a loop until document.getElementById(divDiv) is undefined

New element not added to dynamic form

I downloaded this multistep form http://codepen.io/atakan/pen/gqbIz but whenever I try to use the dynamic form code, it fails to add the new element and instead submits the form.
The code that I use for the dynamic form is
var lastAdded;
var counter = 1;
var limit = 12;
function addFp(spanName){
if (counter == limit) {
alert("You have reached the limit of adding " + counter + " inputs");
}
else {
var newspan = document.createElement('span');
newspan.innerHTML = "<br><select name='w_1_imp"+(counter+1)+"' class=''><option value='imp1'>Animal - Desi Plough</option><option value='imp2'>Animal - Mouldboard Plough</option><option value='imp3'>Animal - Disc Harrow</option><option value='imp4'>Bakhar Blade</option><option value='imp5'>MB Plough</option><option value='imp6'>Puddler</option><option value='imp7'>Disc Plough</option><option value='imp8'>Disc Harrow</option><option value='imp9'>Paddy Harrow</option><option value='imp10'>Rotavator</option><option value='imp11'>Ridger</option><option value='imp12'>Power Tiller</option><option value='imp13'>Animal - Three tyne cultivator</option><option value='imp14'>Cultivator</option></select> <input type='text' name='w_1_h"+(counter+1)+"' placeholder='Hours' class='' size='2'> <input type='text' name='w_1_t"+(counter+1)+"' placeholder='Times' class='' size='3'>"
document.getElementById(spanName).appendChild(newspan);
counter++;
lastAdded = newspan;
}
}
function deleteLastAdded () {
if (lastAdded) {
lastAdded.remove();
counter--;
}
}
The page from where I am calling and using the javascript:
<script src="./assets/js/field_preparation.js"></script>
<div class="form-top">
<div class="form-top-left">
<h3>Field preparation:</h3>
<p>Step 2 / 10</p>
</div>
<div class="form-top-right">
<i class="fa fa-user"></i>
</div>
</div>
<div class="form-bottom">
<div class="form-group">
<table>
<tr><td><b>Tractor Horse Power </b></td><td><b> :</b> </td><td><input type="text" name="tractor1" placeholder="HP" class="" size="8"></td></tr>
<tr><td><b>Bullocks </td><td> <b>:</b></td></b></td><td><input type="text" name="bullock1" placeholder="How many" class="" size="8"></td></tr>
<tr><td><b>No. of Man Hours </b></td><td> <b> : </b></td><td><input type="text" name="human1" placeholder="Men" class="" size="8"></td></tr>
</table>
<span id="dynamicFp">
<select name="w_1_imp1" class="" width="8">
<option value="imp1">Animal - Desi Plough</option>
<option value="imp2">Animal - Mouldboard Plough</option>
<option value="imp3">Animal - Disc Harrow</option>
<option value="imp4">Bakhar Blade</option>
<option value="imp5">Animal - Three tyne cultivator</option>
<option value="imp6">Puddler</option>
<option value="imp7">Disc Plough</option>
<option value="imp8">Disc Harrow</option>
<option value="imp9">Paddy Harrow</option>
<option value="imp10">Rotavator</option>
<option value="imp11">Ridger</option>
<option value="imp12">Power Tiller</option>
<option value="imp13">MB Plough</option>
<option value="imp14">Cultivator</option>
</select>
<input type="text" name="w_1_h1" placeholder="Hrs" class="" size="2">
<input type="text" name="w_1_t1" placeholder="Times" class="" size="3">
</span>
<br><center>
<input type="image" src="./assets/img/plus.png" border="0" width="30px" value="Add Implement" onClick="addFp('dynamicFp');">
<input type="image" src="./assets/img/cancel.png" border="0" width="30px value="Delete last added" onClick="deleteLastAdded();">
<center></center>
<div></div>
<button type="button" class="btn btn-previous">Previous</button>
<button type="button" class="btn btn-next">Next</button>
</div>
can you please help me?
Screenshot
the thing I want is an add remove button next to the implement dropdown field, and then use the same fields to process the results. Thanks
Also, in the above form, I need to have dynamic fields at each step. So, can anyone provide me the code. Thanks
The 'image' input type is actually a submit button...
Reference: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/image
So that explains why it is submitting the form. Consider using a button, link (a) or other element type instead and it should work okay!

How to increment the input field names in the middle of them

http://www.quirksmode.org/dom/domform.html
I am trying to implement this extend form function in my project. Since I am compiling with CakePHP naming convention, in my extend form I have 2 field names:
[Student][0][age]
[Student][0][grade]
The script doesn't work because it is appending the counter only at the end of a field name all alike like this: fieldName + counter, whereas I am trying to increment, as you might have guessed it, like this:
[Student][1][age]
[Student][1][grade]
[Student][2][age]
[Student][2][grade]
I am new to Javascript and hopefully someone can advise how to work this out.
HTML:
<span id="readroot" style="display: none">
<input class="btn btn-default" type="button" value="Remove review" onclick="this.parentNode.parentNode.removeChild(this.parentNode);" />
<br /><br />
<div class="row">
<div class="col-lg-3">
<div class="form-group required"><label for="Student1Age">Age</label><input name="data[Student][0][age]" class="form-control" placeholder="Age" maxlength="11" type="text" id="Student1Age" required="required"/></div>
</div>
<div class="col-lg-3">
<div class="form-group required">
<label for="Student1Grade">級別</label>
<select name="data[Student][0][grade]" class="form-control" id="Student1Grade" required="required">
<option value="">Please Select</option>
<option value="1">Grade 1</option>
<option value="2">Grade 2</option>
</select>
</div>
</div>
</div></span>
<span id="writeroot"></span><input class="btn btn-default" type="button" onclick="moreFields()" value="Give me more fields!" />
Javascript:
var counter = 0;
function moreFields() {
counter++;
var newFields = document.getElementById('readroot').cloneNode(true);
newFields.id = '';
newFields.style.display = 'block';
var newField = newFields.childNodes;
for (var i=0;i<newField.length;i++) {
var theName = newField[i].name
if (theName)
newField[i].name = theName + counter;
}
var insertHere = document.getElementById('writeroot');
insertHere.parentNode.insertBefore(newFields,insertHere);
}
You have to replace this one line like follows.
Yours:
newField[i].name = theName + counter;
New one:
newField[i].name = "[Student][" + counter + "][" + theName + "]";
I made a working sample page out of your script. Check the following link.
http://sugunan.net/demo/extend_form.php

How to remember a form is extended?

I have a multistep form in my project, the first step of which has a javascript extend field function where a user can add additional fields. If the user goes to the next step, the data is of course stored in Session until final submission. However, the extended form will not be remembered. If the user goes back from next step the additional field and its data is not displayed, worse still, if the data in the additional field is invalid, the user won't see it, as the message is displayed underneath the disappeared field (I'm using Cakephp default validation).
Is there a way, like storing the setting in session, to make it stay?
var counter = 0;
function moreFields(val1, val2, val3) {
counter++;
var newField = document.getElementById(val1).cloneNode(true);
newField.id = '';
newField.style.display = 'block';
var newFields = newField.querySelectorAll('[name], [id], [for], [data-display]');
for (var i=0;i<newFields.length;i++) {
var theNames = newFields[i].name
if (theNames)
newFields[i].name = "data[" + val3 + "][" + counter + "][" + theNames + "]";
var theNames2 = newFields[i].id;
if (theNames2)
newFields[i].id = theNames2 + counter;
console.log(newFields[i].id);
var theNames3 = newFields[i].htmlFor;
if (theNames3)
newFields[i].htmlFor = theNames3 + counter;
//console.log(newFields[i].htmlFor);
var theNames4 = newFields[i].dataset.display;
if (theNames4)
newFields[i].dataset.display = theNames4 + counter;
console.log(newFields[i].dataset.display);
}
var insertHere = document.getElementById(val2);
insertHere.parentNode.insertBefore(newField,insertHere);
}
<span id="readroot" style="display: none">
<div class="row">
<div class="col-lg-6">
<div class="form-group required">
<label for="Student1Grade">Grade</label>
<select name="grade" data-display="#display_student_1_grade" class="form-control" id="Student1Grade" required="required">
<option value="">Please Select</option>
<option value="1">Grade 1</option>
<option value="1">Grade 2</option>
</select>
</div>
</div>
<div class="col-lg-6">
<div class="form-group">
<label for="Student1Gender">Gender</label>
<select name="gender" data-display="#display_student_1_gender" class="form-control" id="Student1Gender">
<option value="1">Male</option>
<option value="2">Female</option>
</select>
</div>
</div>
</div>
<input class="btn btn-default" type="button" value="Remove" onclick="this.parentNode.parentNode.removeChild(this.parentNode);" /><br /><br />
</span>
<span id="writeroot"></span>
<input class="btn btn-default" type="button" onclick="moreFields('readroot', 'writeroot', 'Student')" value="Add Field" />
You need to implement either sessionStorage or localStorage for your page.
localStorage - stores data with no expiration date
sessionStorage - stores data for one session (data is lost when the browser tab is closed)
Here I am just posting sample code for your help through which u can do your desire task. You just need to follow the logical concept from below code and implement in your code.
There is a sample also which is only containing id but you can implement it in other way which can full fill your task.
click here

Cloning empty form fields

I am still attempting to create blank fields that users can add on the fly. I am attempting to clone the following hidden template but I can't get it to add.
My HTML
<div class="_100">
<fieldset id="FieldBlank">
<div id="readroot" class="hidden">
<div class="_100">
<div class="_50"> QA Sample ID:<input type="text" id="QASampleID" name="QASampleID"></div>
<div class="_50" data-role="controlgroup" data-mini="true" data-type="horizontal">
<label>Collection Method</label><br />
<input type="radio" id="radGrab1" value="Grab" name="Collection1" />
<label for="radGrab1">Grab</label>
<input type="radio" id="radEWI1" value="EWI" name="Collection1" />
<label for="radEWI1">EWI</label></div>
</div>
<div class="_100">
<div class="_40">
<label class="analysis-label" for="analysis">Analyte:</label>
<select class="analysis" id="analysis" name="analysis" data-iconpos="left" data-icon="grid">
<option>Select</option>
<option value = "TN">TN</option>
<option value = "TP,NO2+3">TP,NO2+3</option>
</select></div>
<div class="_30">
<label class="preserve-label" for="preserve">Preserved</label>
<select class="select_preserve" id="preserve" name="preserve" data-iconpos="left" data-icon="grid">
<option>Select</option>
<option value = "HNO3">HNO₃</option>
<option value = "H2SO4">H₂SO₄</option>
</select></div>
<div class="_30">
<label class="cool-label" for="cool">Cooled</label>
<select class="select_cool" id="cool" name="cool" data-iconpos="left" data-icon="grid">
<option>Select</option>
<option value = "Ice">Ice</option>
<option value = "Frozen">Frozen</option>
<option value = "None">None</option>
</select></div>
</div>
</div>
</fieldset>
</div>
<button type="button" data-theme="b" data-icon="plus" id="moreFields" onclick="moreFields()">ADD FIELD BLANK</button>
<hr /><div id="writeroot"> </div>
My javascript
var counter = 0;
function moreFields() {
counter++;
var newFields = document.getElementById('readroot').cloneNode(true);
newFields.id = '';
newFields.style.display = 'block';
var newField = newFields.childNodes;
for (var i = 0; i < newField.length; i++) {
var theName = newField[i].name
if (theName)
newField[i].name = theName + counter;
}
var insertHere = document.getElementById('writeroot');
insertHere.parentNode.insertBefore(newFields,insertHere);
}
I just cannot get it to work! Is it because this script is not jquery? It doesn't seem to be because it is hidden because when I unhide it the button still doesn't work to add the clones? I am so pulling my hair out right now. I need you help!
Have you tried something like:
$("#readroot input").clone().appendTo("body"); // Or wherever you want to append them to
And, yeah, don't hide stuff manually. Use jQuery's toggle function instead:
$("#readroot").toggle(); // Or hide()

Categories

Resources