Cloning form fields using jquery - javascript

I am attempting to clone fields in a form using Jquery.
I'm trying to achieve the following in terms of display:
SELECT SELECT TEXT INPUT
RADIO RADIO RADIO
Clone 1
SELECT SELECT TEXT INPUT
RADIO RADIO RADIO
Clone2
SELECT SELECT TEXT INPUT
RADIO RADIO RADIO
What I end up getting is:
RADIO RADIO RADIO
RADIO RADIO RADIO
RADIO RADIO RADIO
SELECT SELECT TEXT INPUT
SELECT SELECT TEXT INPUT
SELECT SELECT TEXT INPUT
In my code below, I have used the .after function to follow the Select options, but it still displays it above
$('#condition' + num).after(newElem);
// insert the new element after the last "duplicatable" input field
$('#logical' + num1).after(newElem);
A demo is on Jsfiddle http://jsfiddle.net/noscirre/ATzBA/
HTML
<table width="100%" cellspacing="4" cellpadding="5" border="0">
<tbody><tr id="logical1" class="clonedInput1">
<td class="first-column"> </td>
<td><input type="radio" name="logicalOperator" default>
AND
<input type="radio" name="logicalOperator" >
OR
<input type="radio" name="logicalOperator" >
NOT
</td>
</tr>
<tr id="condition1" class="clonedInput">
<td class="first-column">Condition #2</td>
<td><span style="float:left; padding-right: 10px;">
<select id="firstname" name="firstname" class="standard_select" style="width:147px; background:#fff;">
<option>Blah Name</option>
<option>Blah list</option>
<option>Blah Type</option>
<option>Blah Id</option>
<option>Blah Name</option>
</select> <select id="firstname" name="firstname" class="standard_select" style="width:147px;">
<option>Equals =</option>
<option>Not Equal <></option>
<option>Greater ></option>
<option>Less <</option>
<option>Contains</option>
<option>In</option>
<option>Not In</option>
</select> <input type="text" id="conValue" name="conValue" class="short_input" value="" style="width:147px;">
</span>
</td>
</tr>
<tr>
<td class="first-column"> </td>
<td>
<div>
<input type="button" id="btnAdd" value="Add" />
<input type="button" id="btnDele" value="Del" />
</div>
</td>
</tr></tbody>
</table>
JAVASCRIPT
​` $('#btnAdd').click(function() {
var num = $('.clonedInput').length; // how many "duplicatable" input fields we currently have
var num1 = $('.clonedInput1').length; // how many "duplicatable" input fields we currently have
var newNum = new Number(num + 1); // the numeric ID of the new input field being added
var newNum1 = new Number(num1 + 1); // the numeric ID of the new input field being added
// create the new element via clone(), and manipulate it's ID using newNum value
var newElem = $('#condition' + num).clone().attr('id', 'condition' + newNum);
// create the new element via clone(), and manipulate it's ID using newNum value
var newElem1 = $('#logical' + num1).clone().attr('id', 'logical' + newNum1);
// manipulate the name/id values of the input inside the new element
newElem.children(':first').attr('id', 'name' + newNum).attr('name', 'name' + newNum);
// manipulate the name/id values of the input inside the new element
newElem.children(':first').attr('id', 'name' + newNum1).attr('name', 'name' + newNum1);
// insert the new element after the last "duplicatable" input field
$('#condition' + num).after(newElem);
// insert the new element after the last "duplicatable" input field
$('#logical' + num1).after(newElem1);
// enable the "remove" button
$('#btnDele').attr('disabled','');
// business rule: you can only add 5 names
if (newNum == 5)
$('#btnAdd').attr('disabled','disabled');
// business rule: you can only add 5 names
if (newNum1 == 5)
$('#btnAdd').attr('disabled','disabled');
});
$('#btnDele').click(function() {
var num = $('.clonedInput').length; // how many "duplicatable" input fields we currently have
var num1 = $('.clonedInput1').length; // how many "duplicatable" input fields we currently have
$('#condition' + num).remove(); // remove the last element
$('#logical' + num).remove(); // remove the last element
// enable the "add" button
$('#btnAdd').attr('disabled','');
// if only one element remains, disable the "remove" button
if (num-1 == 1)
$('#btnDele').attr('disabled','disabled');
if (num1-1 == 1)
$('#btnDele').attr('disabled','disabled');
});
$('#btnDele').attr('disabled','disabled');
​`

The newElem1 is inserted after the logicalxxx item, which is before the last inserted condition item. If you replace
// insert the new element after the last "duplicatable" input field
$('#condition' + num).after(newElem);
// insert the new element after the last "duplicatable" input field
$('#logical' + num1).after(newElem1);
with
$('#condition' + num).after(newElem).after(newElem1);
newelem1 is inserted directly after newelem and I think that gives the desired effect (updated fiddle: http://jsfiddle.net/ATzBA/2/ )

Related

how to reset hidden text fields when a form is duplicated

I have a form with dropdown select menus, and depending what you choose, it will show a hidden text fields that you have to full fill. When I click on the 'duplicate button', the javascript works fine and duplicates the entire form. The select dropdown menu and all the fields that are NOT hidden are reset, which is what I want. However, all the hidden fields end up duplicating the answers from the previous form.
The 2nd problem is, if I don't select a choice that does NOT contain a hidden field in my original form, on the duplicate form, the javascript to show the hidden fields for the dropdown menus will not work. For example, there's a dropdown with choices 1 and 2. If you choose 1, there's no hidden field that shows, and if you choose 2, there will be a hidden field that you have to answer. If I chose #1 in the previous form, then in the duplicate form, the dropdown shows both 1 and 2, but nothing will happen if I choose 2, and that's because in the previous form I had chosen #1 so I guess the javascript function didn't get duplicated? what if on the duplicate form I want to choose #2? I can't.
Here's my code
HTML
<div class="form-group">
<select class="selectDD" id="FHB_OrgEvent" onchange='showIfEvent();'>
<option value="1" >1</option>
<option value="2" >2</option>
</select>
<div style="display:none;" class="hidden" id="showFhbEventName">
<input type="text" id="FHBEventName" placeholder="Name of Event"/>
</div>
<div style="display:none;" class="hidden" id="showFhbEventDesc">
<input type="text" id="FHBEventDesc" placeholder="Please provide a brief description of the event or activity"/>
</div>
</div>
<div id="add-del-buttons" class="add-del-buttons">
<input type="button" id="btnAdd" value="duplicate">
</div>
Javascript for showing hidden fields
function showIfEvent() {
if (FHB_OrgEvent.value == "1") {
showFhbEventName.style.display = "block";
showFHBEventDesc.style.display = "block";
} else {
showFhbEventName.style.display = "none";
showFHBEventDesc.style.display = "none";
}
}
Javascript for Duplicate function
$('#btnAdd').click(function() {
var num = $('.clonedInput').length; // how many "duplicatable" input fields we currently have
var newNum = new Number(num + 1); // the numeric ID of the new input field being added
// create the new element via clone(), and manipulate it's ID using newNum value
var newElem = $('#input' + num).clone().attr('id', 'input' + newNum);
// manipulate the name/id values of the input inside the new element
newElem.children(':first').attr('id', 'name' + newNum).attr('name', 'name' + newNum);
// insert the new element after the last "duplicatable" input field
$('#input' + num).after(newElem);
});

Running clone n number of times

i'm currently using this code to clone a text input field when clicking on a button with the id btnAdd
$(document).ready(function() {
$('#btnAdd').click(function() {
var num = $('.clonedInput').length;
var newNum = new Number(num + 1);
var newElem = $('#input' + num).clone().attr('id', 'input' + newNum);
newElem.children(':first').attr('id', 'name' + newNum).attr('name', 'name' + newNum);
$('#input' + num).after(newElem);
$('#btnDel').attr('disabled','');
if (newNum == 25)
$('#btnAdd').attr('disabled','disabled');
});
What i want to do is be able to press another button and have it add a certain number of cloned text fields, while still renaming the ids to name + n
I want to do this so i can have a button create fx. 5 text fields and then populate them with predetermined values.
Right now i have to first create 4 textfields for 5 total, and then call the function with another button, to alter the text fields.
A point in the right direction would be appreciated.
Example i used in comments:
Let’s say that i want to have a site where you can input a list of names
I start with one input boxes
<div id="input1" style="margin-bottom:4px;" class="clonedInput">
<input type="text" name="name1" id="name1" placeholder="Port" />
</div>
Then i want the user to be able to add more input boxes. so i use the clone code in the OP
This enables the user to manually add all the names they want.
But i want to be able to have the user be able to choose from pre selected lists, lets say a list of all the names of the football team.
So i want the user to be able to press a button, which creates fx. 11 input boxes, and then fills out the boxes with all the 11 names of the football team.
To do this i have been using this code:
function Input() {
$('#name1').val(‘John’)
$('#name2').val(’Steve’)
$('#name3').val(‘Maria’)
$('#name4').val(‘Ida’)
}
But if the user has not created enough clones of the input boxes, this just fills out the created ones.
I hope I understood the behaviour you wanted. It basically adds inputs in the div block you want with some random names as value.
var names = ["Chris", "Jimmy", "George", "Martin", "Keith"];
function createInputs(numberOfInputs, blockId) {
var i = 0;
var inputBlock = $("#" + blockId);
inputBlock.empty();
while(i < numberOfInputs && i < names.length) {
inputBlock.append($('<input type="text" name="name" id="name'+ i + '"/>').val(names[i]));
i++;
}
}
input {
display: block;
margin: 5px 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<button onclick="createInputs(3, 'input1')">Create 3 random inputs</button>
<div id="input1" style="margin-bottom:4px;" class="clonedInput">
<input type="text" name="name1" id="name1" placeholder="Port" />
</div>
<button onclick="createInputs(5, 'input2')">Create 5 random inputs</button>
<div id="input2" style="margin-bottom:4px;" class="clonedInput">
<input type="text" name="name1" id="name1" placeholder="Port" />
</div>

JQuery - dynamically selecting inputs with "nth"

I have a question that I've been stuck on. I have a form and want to dynamically be able to call upon the n-th set of input fields in a form to use them in equations that will output the n-th set of answers. For example "footage2" should be plugged into an equation that will give me "postQuantity2" and then "footage3" should be used to determine "postQuantity3". The problem is that the form can add input areas dynamically so I can't just hard code it to do what I want. Any ideas of how to get the nth set of numbers to be used for an equation and then give me the nth set of answers? If anyone can explain how this would work, or just point out how it wouldn't it'd be very much appreciated! Thanks!
Here is a snippet - http://jsfiddle.net/gv0029/QGW7R/ - to give you a basic idea of what I'm working with and here is some html and js.
HTML
<fieldset id="fence">
<div id="inputFence1" class="clonedInputFence">
<fieldset id="fenceDescripton">
<legend><strong>Fence Description</strong>
</legend>
<label>Footage:
<input type="number" id="footage" name="footage" value="" /></label>
<select name="fenceHeight" id="fenceHeight">
<option value="select">Select Fence Height</option>
<option value="6" id="fH6">6 Ft.</option>
<option value="8" id="fH8">8 Ft.</option>
</select>
</fieldset>
<fieldset id="post">
<legend><strong>Post Type</strong>
</legend>
<label>Post Quantity:
<input type="postQuantity" name="postQuantity" id="postQuantity" value="" />
</label>
<select name="postMeasurements" id="postMeasurements">
<option value="select">Select Post Measurements</option>
<option value="23/8 x .065 x 8" id="23/8 x .065 x 8">2 3/8 x .065 x 8</option>
<option value="23/8 x .095 x 8" id="23/8 x .095 x 8">23/8 x .095 x 8</option>
</select>
</fieldset>
</div>
</fieldset>
<div>
<input type="button" id="btnAddFence" value="Add Another Fence" />
<input type="button" id="btnDelFence" value="Remove Fence" />
</div>
JS
//Quantity for Posts
$('#footage, #manualOverrideNo').bind('keypress keydown keyup change', function(){
var footage = parseFloat($(':input[name="footage"]').val(),10);
var total = '';
if(!isNaN(footage)){
total = Math.ceil(footage /7);
$(':input[name="postQuantity"]').val(total.toString());
} else {
$(':input[name="postQuantity"]').val("");
}
});
//Dynamic Fence Input Fields
$('#btnAddFence').click(function() {
var num = $('.clonedInputFence').length; // how many "duplicatable" input fields we currently have
var newNum = new Number(num + 1); // the numeric ID of the new input field being added
// create the new element via clone(), and manipulate it's ID using newNum value
var newElem = $('#inputFence' + num).clone().attr('id', 'inputFence' + newNum);
//Fieldset creation
newElem.find('fieldset').attr('id', 'fence' + newNum);
//Fence Description
newElem.find("select[name=fenceHeight]").attr('id', 'fenceHeight' + newNum).attr('name', 'fenceHeight' + newNum);
newElem.find(':input[name="footage"]').attr('id', 'footage' + newNum).attr('name', 'footage' + newNum);
//Post Type
newElem.find(':input[name="postQuantity"]').attr('id', 'postQuantity' + newNum).attr('name', 'postQuantity' + newNum);
newElem.find("select[name=postMeasurements]").attr('id', 'postMeasurements' + newNum).attr('name', 'postMeasurements' + newNum);
// insert the new element after the last "duplicable" input field
$('#inputFence' + num).after(newElem);
// enable the "remove" button
//$('#btnDel').attr('disabled','');
$('#btnDelFence').removeAttr('disabled');
});
$('#btnDelFence').click(function() {
var num = $('.clonedInputFence').length; // how many "duplicatable" input fields we currently have
$('#inputFence' + num).remove(); // remove the last element
// enable the "add" button
//$('#btnAdd').attr('disabled','');
$('#btnAddFence').removeAttr('disabled');
// if only one element remains, disable the "remove" button
if (num-1 == 1)
$('#btnDelFence').attr('disabled','disabled');
});
$('#btnDelFence').attr('disabled','disabled');
I don't think nth-child will work in this case since there are multiple child elements and the op wants to match them up.
On your footage elements, add a data attribute of, let's say, data-which-pair with a pattern like
id = n data-which-pair = n
$("#footage"+n).click(function(){
var n = $(this).attr("data-which-pair");
Do something cool with $("#postQuantity"+n);
}
You might be able to just do a function(n) but I usually follow this longer-winded approach because it is easier to see what's going on. Keep in mind, obviously, that the above is pseudocode that you will need to adapt.

JQuery - New name based off of old name

I'm building a form that can add extra fieldsets and inputs. I am trying to get the fieldsets and inputs to have an individual ids and names (such as fenceDescription2, fenceDescription3) but I can't figure out how to have the new element (for either the fieldset or the inputs) call on its own name so that it can add a new number to it. I got it to work with just one field but cant get the names to and the newNum correctly when I have multiple fieldsets. Ideally every time you clicked "add new fence" a clone of the elements would pop up underneath, each with a matching newNumber that corresponds to their order in the form (fenceHeight2 with postQuantity2 and postMeasurement2, and then 3 with 3, etc). Any help explaining how this is done would be greatly appreciated! Thanks! Here is a JSFiddle - http://jsfiddle.net/gv0029/3dnNP/1/
HTML :
<fieldset id="fence">
<div id="inputFence1" class="clonedInputFence">
<fieldset id="fenceDescripton">
<legend><strong>Fence Description</strong>
</legend>Fence Description:
<select name="fenceHeight" id="fenceHeight">
<option value="select">Select Fence Height</option>
<option value="6" id="fH6">6 Ft.</option>
<option value="8" id="fH8">8 Ft.</option>
</select>
</fieldset>
<fieldset id="post">
<legend><strong>Post Type</strong>
</legend>
<label>Post Quantity:
<input type="postQuantity" name="postQuantity" id="postQuantity" value="" />
</label>
<select name="postMeasurements" id="postMeasurements">
<option value="select">Select Post Measurements</option>
<option value="23/8 x .065 x 8" id="23/8 x .065 x 8">2 3/8 x .065 x 8</option>
<option value="23/8 x .095 x 8" id="23/8 x .095 x 8">23/8 x .095 x 8</option>
</select>
</fieldset>
</div>
</fieldset>
<div>
<input type="button" id="btnAddFence" value="Add Another Fence" />
<input type="button" id="btnDelFence" value="Remove Fence" />
</div>
JS:
//Dynamic Fence Input Fields
$('#btnAddFence').click(function() {
var num = $('.clonedInputFence').length; // how many "duplicatable" input fields we currently have
var newNum = new Number(num + 1); // the numeric ID of the new input field being added
// create the new element via clone(), and manipulate it's ID using newNum value
var newElem = $('#inputFence' + num).clone().attr('id', 'inputFence' + newNum);
//Fieldset creation
newElem.find('fieldset').attr('id', 'name' + newNum);
//Fence Description
newElem.find($("select[name=fenceHeight]")).attr('id', 'fenceHeight' + newNum).attr('name', 'fenceHeight' + newNum);
//Post Type
newElem.find($(':input[name="postQuantity"]')).attr('id', 'postQuantity' + newNum).attr('name', 'postQuantity' + newNum);
newElem.find($("select[name=postMeasurements]")).attr('id', 'postMeasurements' + newNum).attr('name', 'postMeasurements' + newNum);
// insert the new element after the last "duplicable" input field
$('#inputFence' + num).after(newElem);
// enable the "remove" button
$('#btnDelFence').removeAttr('disabled');
// business rule: you can only add 5 names
//if (newNum == 5)
//$('#btnAdd').attr('disabled','disabled');
});
$('#btnDelFence').click(function() {
var num = $('.clonedInputFence').length; // how many "duplicatable" input fields we currently have
$('#inputFence' + num).remove(); // remove the last element
// enable the "add" button
//$('#btnAdd').attr('disabled','');
$('#btnAddFence').removeAttr('disabled');
// if only one element remains, disable the "remove" button
if (num-1 == 1)
$('#btnDelFence').attr('disabled','disabled');
});
$('#btnDelFence').attr('disabled','disabled');

JS works in one place but not another

I'm stumped on something that is a little odd. I was tinkering with some code in an html file that had js and html on it until I got it to work like I wanted then I copied and pasted it to the php file that is linked to a JS page. The trouble is that in the php page I get the error message unrecognized expression: select[name=gateHeight] option: selected. If anyone could explain what I messed up I would appreciate it very much!
Here is the html file with JS and HTML:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title></title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$('#btnAdd').click(function() {
var num = $('.clonedInput').length; // how many "duplicatable" input fields we currently have
var newNum = new Number(num + 1); // the numeric ID of the new input field being added
// create the new element via clone(), and manipulate it's ID using newNum value
var newElem = $('#input' + num).clone().attr('id', 'input' + newNum);
// manipulate the name/id values of the input inside the new element
newElem.children($("select[name=gateHeight] option: selected")).attr('id', 'gateHeight' + newNum).attr('name', 'gateHeight' + newNum);
//newElem.children('input[type=text]:first').attr('id', 'name' + newNum).attr('name', 'name' + newNum);
newElem.children('input[type=checkbox]:first').attr('id', 'chk' + newNum).attr('name', 'chk' + newNum);
// insert the new element after the last "duplicatable" input field
$('#input' + num).after(newElem);
// enable the "remove" button
//$('#btnDel').attr('disabled','');
$('#btnDel').removeAttr('disabled');
// business rule: you can only add 5 names
if (newNum == 5)
$('#btnAdd').attr('disabled','disabled');
});
$('#btnDel').click(function() {
var num = $('.clonedInput').length; // how many "duplicatable" input fields we currently have
$('#input' + num).remove(); // remove the last element
// enable the "add" button
//$('#btnAdd').attr('disabled','');
$('#btnAdd').removeAttr('disabled');
// if only one element remains, disable the "remove" button
if (num-1 == 1)
$('#btnDel').attr('disabled','disabled');
});
$('#btnDel').attr('disabled','disabled');
});
</script>
</head>
<body>
<form id="myForm">
<div id="input1" style="margin-bottom:4px;" class="clonedInput">
<!-- <input type="text" name="name1" id="name1" /> -->
<select name="gateHeight" id="gateHeight">
<option value="select">Select Gate Height</option>
<option value="4fg">4 Ft. Gate</option>
<option value="6fg">6 Ft. Gate</option>
<option value="8fg">8 Ft. Gate</option>
</select>
Include Spring Pool Latch: <input type="checkbox" name="chk1" id="chk1" />
</div>
<div>
<input type="button" id="btnAdd" value="add another name" />
<input type="button" id="btnDel" value="remove name" />
</div>
</form>
</body>
And here is the JS and HTML of the other file:
JS:
//Dynamic Gate Input Fields
$('#btnAdd').click(function() {
var num = $('.clonedInput').length; // how many "duplicatable" input fields we currently have
var newNum = new Number(num + 1); // the numeric ID of the new input field being added
// create the new element via clone(), and manipulate it's ID using newNum value
var newElem = $('#input' + num).clone().attr('id', 'input' + newNum);
// manipulate the name/id values of the input inside the new element
newElem.children($("select[name=gateHeight] option: selected")).attr('id', 'gateHeight' + newNum).attr('name', 'gateHeight' + newNum);
//newElem.children('input[type=text]:first').attr('id', 'name' + newNum).attr('name', 'name' + newNum);
newElem.children('input[type=checkbox]:first').attr('id', 'chk' + newNum).attr('name', 'chk' + newNum);
// insert the new element after the last "duplicatable" input field
$('#input' + num).after(newElem);
// enable the "remove" button
//$('#btnDel').attr('disabled','');
$('#btnDel').removeAttr('disabled');
// business rule: you can only add 5 names
if (newNum == 5)
$('#btnAdd').attr('disabled','disabled');
});
$('#btnDel').click(function() {
var num = $('.clonedInput').length; // how many "duplicatable" input fields we currently have
$('#input' + num).remove(); // remove the last element
// enable the "add" button
//$('#btnAdd').attr('disabled','');
$('#btnAdd').removeAttr('disabled');
// if only one element remains, disable the "remove" button
if (num-1 == 1)
$('#btnDel').attr('disabled','disabled');
});
$('#btnDel').attr('disabled','disabled');
HTML:
<div id="input1" style="margin-bottom:4px;" class="clonedInput">
<select name="gateHeight" id="gateHeight">
<option value="select">Select Gate Height</option>
<option value="4fg">4 Ft. Gate</option>
<option value="6fg">6 Ft. Gate</option>
<option value="8fg">8 Ft. Gate</option>
</select>
Include Spring Pool Latch: <input type="checkbox" name="chk1" id="chk1" />
</div>
<div>
<input type="button" id="btnAdd" value="Add Another Gate" />
<input type="button" id="btnDel" value="Remove Gate" />
</div>
You are missing the document ready wrapper function your code is called before the element exist therefore fail.
Try with
$("select[name=gateHeight] option :selected")
:selected is the right one not : selected (no space)
OR
$("select[name=gateHeight] option").filter(":selected")
This will work
You need to get rid of the space after the colon in option: selected. Just change that to option:selected.
First you should use the updated version of jquery like jquery-1.9 or higher.
Second you should use newElem.children("select[name=gateHeight]") in place of
newElem.children($("select[name=gateHeight] option: selected"))
like
newElem.find("select[name='gateHeight']")
.attr({'id': 'gateHeight'+newNum, 'name': 'gateHeight' + newNum});// combine attr() using json
Demo

Categories