Need help to remove items dynamically using pure javascript - javascript

Requirements:
A new text box should appear with a delete button at closing after clicking '+Add Stop'.
If a delete(x) button is clicked, the respective text box should be removed and Stop #(sequence numbering) should be changed as well.
Need help on:
I have tried to achieve the both above requirements. I get results for #1. But for #2, After adding more items, the delete button works/removes only the last added item only but it should work the same for all items.
Stop # sequence number should be maintained after the removal of an item(s). I need help with this logic also.
HTML:
<form action="https://www.example.com" method="POST">
<label for="stype">Service Type:</label>
<select id="stype" name="service-type">
<option disabled="disabled" selected="selected">Choose Service</option>
<option value="From Airport">From Airport</option>
<option value="To Airport">To Airport</option>
</select><br/><br/>
<label for="fullname">Name: </label><input id="fullname" name="name" size="20" type="text" maxlength="20" placeholder="John Doe" required /><br/><br/>
<label for="phone">Phone: </label><input id="phone" name="phone" maxlength="12" type="tel" placeholder="012-345-6789" required /><br/><br/>
<label for="email">Email: </label><input id="email" name="email" size="30" type="email" maxlength="30" placeholder="contact#example.com" required /><br/><br/>
<label for="ptime">Pickup time </label><input id="ptime" name="pickup-time" type="time" required /><br/><br/>
<label for="pdate">Pickup Date </label><input id="pdate" name="pickup-date" type="date" required /><br/><br/>
<div id="add_stop_here">
</div>
<input type="button" id="add" value="+Add Stop" onclick="test();" />
</form>
JavaScript:
var counter = 0;
function test () {
counter += 1;
var addHtml = '\
<div class="input-box">\
<label for="stop'+counter+'">Stop '+counter+':</label>\
<input type="text" id="stop'+counter+'" name="stop"/ > <a id="rmv'+counter+'" class="remove_stop" href="#">x</a>\
</div>';
var add_hre = document.getElementById("add_stop_here");
add_hre.innerHTML += addHtml;
document.querySelector("#rmv"+counter)
.addEventListener('click', function(){
var removeEl = this.parentNode;
add_hre.removeChild(removeEl);
});
}

Some issues to take care of:
To make this work, I would refrain from using id attributes that have a sequential number. It is not best practice.
Instead, in order to link a label element with its input element, make the input element a child of the corresponding label element. Now the id and for attributes are no longer needed.
Don't use innerHTML += as that will reset the values of the inputs that are already in the document, and will remove the event listeners. Instead use insertAdjacentHTML.
To keep the numbering in pace, use a span element that only has that number, and renumber all those span elements after every change. You can also use it after an insert, just to keep the code clean, and avoid that you need to maintain a counter.
To avoid that you need to attach a new event handler for every new element, listen to click events on the container element, and then check in that single handler which element was clicked. This is called event delegation.
Don't name your function test. Give it a useful name, like insertBusStop.
Instead of binding that handler via HTML attribute, bind it via code.
For multi-line strings you can use back tick delimiters (template literals)
I'd suggest that after clicking the Add button, the focus is put on the newly created input element. This facilitates the input procedure for the user.
Here is how that would work:
var add_hre = document.getElementById("add_stop_here");
document.getElementById("add").addEventListener("click", addBusStop);
function addBusStop() {
var addHtml = `
<div class="input-box">
<label>
Stop <span class="stop_number"></span>
<input type="text" name="stop"/> <a class="remove_stop" href="#">x</a>
</label>
</div>`;
add_hre.insertAdjacentHTML("beforeend", addHtml);
renumber();
add_hre.querySelector(".input-box:last-child input").focus();
}
function renumber() {
let i = 1;
for (let labelSpan of add_hre.querySelectorAll(".stop_number")) {
labelSpan.textContent = i++;
}
}
// Use event delegation
add_hre.addEventListener('click', function(e) {
if (!e.target.classList.contains("remove_stop")) return;
var removeEl = e.target.parentNode.parentNode; // need one more level now
add_hre.removeChild(removeEl);
renumber();
});
<div id="add_stop_here"></div>
<input type="button" id="add" value="+Add Stop"/>

You can do this with each() and find() function easily.
var counter = 0;
$("#add").click(function () {
counter++;
$("#add_stop_here").append(
'<div class="input-box"><label for="stop' +
counter +
'">Stop' +
counter +
': <input type="text" id="stop' +
counter +
'" name="stop"/ ></label> <a id="rmv' +
counter +
'" class="remove_stop" href="#">X</a></div>'
);
});
$(document).on("click", ".remove_stop", function () {
$(this).closest("div").remove(); //use closest here
$("#add_stop_here .input-box").each(function (index) {
$(this)
.find("label:eq(0)")
.attr("id", "stop" + (index + 1));
$(this)
.find("label:eq(0)")
.html("Stop" + (index + 1) + '<input type="text" name="stop" />');
});
counter--;
});
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<form action="https://www.example.com" method="POST">
<label for="stype">Service Type:</label>
<select id="stype" name="service-type">
<option disabled="disabled" selected="selected">Choose Service</option>
<option value="From Airport">From Airport</option>
<option value="To Airport">To Airport</option></select
><br /><br />
<label for="fullname">Name: </label
><input
id="fullname"
name="name"
size="20"
type="text"
maxlength="20"
placeholder="John Doe"
required
/><br /><br />
<label for="phone">Phone: </label
><input
id="phone"
name="phone"
maxlength="12"
type="tel"
placeholder="012-345-6789"
required
/><br /><br />
<label for="email">Email: </label
><input
id="email"
name="email"
size="30"
type="email"
maxlength="30"
placeholder="contact#example.com"
required
/><br /><br />
<label for="ptime">Pickup time </label
><input id="ptime" name="pickup-time" type="time" required /><br /><br />
<label for="pdate">Pickup Date </label
><input id="pdate" name="pickup-date" type="date" required /><br /><br />
<div id="add_stop_here"></div>
<input type="button" id="add" value="+Add Stop" />
</form>

Related

Multiplication in jQuery dynamically

I am trying to make a multiplication function in jquery where which helps change the default value-based output.
For example - if I type the input#mainInput value then it will change all the inputs value base own his default value * input#mainInput and if the value == 'NaN' it will do dirent funcion.
Please help me how to I make this function in jQuery.
$(document).on('keyup', 'input#mainInput', function() {
thisParentQtyValueBox = $(this).val();
daughtersBoxValueAttr = $("input.input__bom").attr("inputid");
daughtersBoxValue = $("input#daughterInput_" + daughtersBoxValueAttr).val();
$("input#daughterInput_" + daughtersBoxValueAttr).val(thisParentQtyValueBox * daughtersBoxValue);
if ($("input#daughterInput_" + daughtersBoxValueAttr) == 'Nan') {
$("input#daughterInput_" + daughtersBoxValueAttr).val('3' * daughtersBoxValue)
}
});
//If
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input id="mainInput" type="text" placeholder="Number" />
<br><br>
<input class="input__bom" id="daughterInput_1" type="text" placeholder="value" inputid="1" value="5" /><br/>
<input class="input__bom" id="daughterInput_2" type="text" placeholder="value" inputid="2" value="10" /><br/>
<input class="input__bom" id="daughterInput_3" type="text" placeholder="value" inputid="3" value="15" /><br/>
<input class="input__bom" id="daughterInput_4" type="text" placeholder="value" inputid="4" value="20" /><br/>
<input class="input__bom" id="daughterInput_5" type="text" placeholder="value" inputid="5" value="25" /><br/>
If I understand correctly, when the input is not a number, you want to do as if the input was 3.
Some issues in your code:
$("input.input__bom").attr("inputid") is always going to evaluate to 1, as only the first matching element is used. And it is strange to use this attribute value to then retrieve that element again via its id property.
You would need a loop somewhere so to visit each of the "input__bom" elements.
== 'Nan is never going to be true. You should in fact test the main input itself to see if it represents a valid number. For that you can use isNaN.
It is a bad idea to give these elements a unique id attribute. You can use jQuery to visit them each and deal with them. There is no need for such id attribute.
Don't use the keyup event for this, as input can be given in other ways than pressing keys (e.g. dragging text with mouse, or using the context menu to paste). Use the input event instead.
There is no good reason to use event delegation here on $(document). Just bind your listener directly the main input element.
Declare your variables with var (or let, const). It is bad practice to no do that (it makes your variables global).
It seems like the 5 "bom" input elements are not really intended for input, but for output. In that case the placeholder attribute makes no sense, and they should better be marked with the readonly attribute.
$("#mainInput").on('input', function() {
var mainInput = $(this).val();
var multiplier = +mainInput; // convert to number with unary +
// default value in case input is not a valid number, or is empty
if (Number.isNaN(multiplier) || !mainInput) {
multiplier = 3;
}
$('.input__bom').each(function() {
$(this).val( multiplier * $(this).data('value') );
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input id="mainInput" type="text" placeholder="Number" />
<br><br>
<input class="input__bom" type="text" readonly data-value="5" value="5"><br/>
<input class="input__bom" type="text" readonly data-value="10" value="10"><br/>
<input class="input__bom" type="text" readonly data-value="15" value="15"><br/>
<input class="input__bom" type="text" readonly data-value="20" value="20"><br/>
<input class="input__bom" type="text" readonly data-value="25" value="25" /><br/>
You have to store the default value in the data attr so then it will not multiple by result value and it will multiple by your default value. for dynamic multiplication, you can use jquery each. check below code.
$(document).on('input', 'input#mainInput', function() {
thisParentQtyValueBox = parseInt( $(this).val() );
if( Number.isNaN( thisParentQtyValueBox ) ){
thisParentQtyValueBox = 3;
}
$('.input__bom').each(function(){
$(this).val( thisParentQtyValueBox * $(this).data('value') );
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input id="mainInput" type="text" placeholder="Number" />
<br><br>
<input class="input__bom" id="daughterInput_1" type="text" placeholder="value" inputid="1" data-value ="5" value="5" /><br/>
<input class="input__bom" id="daughterInput_2" type="text" placeholder="value" inputid="2" data-value ="10" value="10" /><br/>
<input class="input__bom" id="daughterInput_3" type="text" placeholder="value" inputid="3" data-value ="15" value="15" /><br/>
<input class="input__bom" id="daughterInput_4" type="text" placeholder="value" inputid="4" data-value ="20" value="20" /><br/>
<input class="input__bom" id="daughterInput_5" type="text" placeholder="value" inputid="5" data-value ="25" value="25" /><br/>

how do i clone a multiple html input field with jquery

i have a complex div with input field somewhat like this
<input type="text" name="firstname">
<input type="text" name="lastname">
<input type="text" name="email">
<input type="text" name="address">
<div id="section_toClone">
<input type="text" name="tree[tree1][fruit]">
<input type="text" name="tree[tree1][height]">
<input type="checkbox name tree[tree1][color] value="green">Green </input>
<input type="checkbox name tree[tree1][color] value="yellow">yellow </input>
</div>
<button id="add_more"> Add </button>
now when someone click on add i want something like this to happen
<input type="text" name="tree[tree1][fruit]">
<input type="text" name="tree[tree1][height]">
<input type="checkbox name tree[tree1][color] value="green">Green </input>
<input type="checkbox name tree[tree1][color] value="yellow">yellow </input>
<input type="text" name="tree[tree2][fruit]">
<input type="text" name="tree[tree2][height]">
<input type="checkbox name tree[tree2][color] value="green">Green </input>
<input type="checkbox name tree[tree2][color] value="yellow">yellow </input>
<input type="text" name="tree[tree3][fruit]">
<input type="text" name="tree[tree3][height]">
<input type="checkbox name tree[tree3][color] value="green">Green </input>
<input type="checkbox name tree[tree3][color] value="yellow">yellow </input>
and so on..... but my script only clone doesnt change the value of tree from tree1 to tree2 to tree3 and so on.... here is my jquery script
$('#add_more').click(function(){
$("#section_toClone").clone(true).insertBefore("#add_more").find('input').val("").val('');
});
how do i increment that automatically?? i want to mention one more thing in actual html code. it has more then 3 input and 3 checkbox field
Don't even bother putting the numbers into the array keys. Just let PHP take care of it itself:
<input name="tree[fruit][]" value="foo" />
<input name="tree[fruit][]" value="bar" />
<input name="tree[fruit][]" value="baz" />
Any [] set which DOESN'T have an explicitly specified key will have one generated/assigned by PHP, and you'll end up with
$_POST['tree'] = array(
0 => 'foo',
1 => 'bar',
2 => 'baz'
);
As long as your form is generated consistently, browsers will submit the fields in the same order they appear in the HTML, so something like this will work:
<p>#1</p>
<input name="foo[color][]" value="red"/>
<input name="foo[size][]" value="large" />
<p>#2</p>
<input name="foo[color][]" value="puce" />
<input namke="foo[size][]" value="minuscule" />
and produce:
$_POST['color'] = array('red', 'puce');
| |
$_POST['size'] = array('large', 'minuscule');
But if you start mixing the order of the fields:
<p>#3</p>
<input name="foo[color][]" value="red"/>
<input name="foo[size][] value="large" />
<p>#4</p>
<input namke="foo[size][] value="minuscule" />
<input name="foo[color][] value="puce" />
$_POST['color'] = array('red', 'puce');
/
/
$_POST['size'] = array('minuscule', 'large');
Note how they're reversed.
I wouldn't post this without feeling a bit ashamed of how bad it is written, but the following solution does the trick. Badly.
var treeCount = 1;
$('#add_more').click(function(){
$("#section_toClone")
.clone(true)
.insertBefore("#add_more")
.find('input')
.val('')
.each(function(key,element){
var $element = $(element),
oldName = $element.attr('name'),
newName;
if(oldName){
newName = oldName.replace(/tree[0-9]+/, 'tree'+(treeCount+1));
$element.attr('name', newName);
}
else {
treeCount--;
}
})
.promise().done(function(){
treeCount++;
});
});
(please don't shoot me)

Dynamically add set of inputs to html form

I am currently creating a HTML form, I have a section in which contains 8 text inputs. This is the section so far:
<div class="form-title"><h3>Clinical Information</h3></div>
<div class="form-title">Time Assesed:</div>
<input class="form-field" type="time" name="timeassessd" /><br />
<div class="form-title">Blood Pressure:</div>
<input class="form-field" type="text" name="bp" /><br />
<div class="form-title">Pulse:</div>
<input class="form-field" type="date" name="pulse" /><br />
<div class="form-title">Resp. Rate:</div>
<input class="form-field" type="text" name="breathing" /><br />
<div class="form-title">Temp:</div>
<input class="form-field" type="text" name="temp" /><br />
<div class="form-title">SPO2:</div>
<input class="form-field" type="text" name="spo2" /><br />
<div class="form-title">GCS:</div>
<input class="form-field" type="text" name="gcs" /><br />
<div class="form-title">AVPU:</div>
<input class="form-field" type="text" name="avpu" /><br />
What I need is to have a button that when the user presses the button it will create another section identical to the one above adding the fields to the form. Each form will also need a number on the end of the name. I have looked around at different forums but I cant find one with a whole section to add in just individual inputs which doesn't help me here. Thanks.
You need to make a JS function to add the section. the function would look something like this:
function add_section() {
new_row = "";
new_row += "";
new_row += '<div class="form-title"><h3>Clinical Information</h3></div>';
new_row += '<div class="form-title">Time Assesed:</div>';
new_row += '<input class="form-field" type="time" name="timeassessd" /><br />';
new_row += '<div class="form-title">Blood Pressure:</div>';
new_row += '<input class="form-field" type="text" name="bp" /><br />';
new_row += '<div class="form-title">Pulse:</div>';
new_row += '<input class="form-field" type="date" name="pulse" /><br />';
new_row += '<div class="form-title">Resp. Rate:</div>';
new_row += '<input class="form-field" type="text" name="breathing" /><br />';
new_row += '<div class="form-title">Temp:</div>';
new_row += '<input class="form-field" type="text" name="temp" /><br />';
new_row += '<div class="form-title">SPO2:</div>';
new_row += '<input class="form-field" type="text" name="spo2" /><br />';
new_row += '<div class="form-title">GCS:</div>';
new_row += '<input class="form-field" type="text" name="gcs" /><br />';
new_row += '<div class="form-title">AVPU:</div>';
new_row += '<input class="form-field" type="text" name="avpu" /><br />';
var pos = $("selecter"); //element selecter after which you need to add the section
$(pos).after(new_row);
}
And then on the click of the button, call this function. It will work.
Also the name of input fields should be an array ex: name="avpu[]"
If not using array, the post method would only get the value of the last input element having same names.
Could you post the whole form?
What you can do, if you're using jQuery, is, that you clone the jQuery node of the form and than manipulate the input names, and than append the content to your form.
Something like that:
var num = 1;
function add_form_elements(num) {
var clonedForm = $('#id_of_the_form').clone();
clonedForm.find('input').each(function(id, elm) {
elm.attr("name",elm.attr("name") + num);
});
$('#id_of_the_form').append(clonedForm.innerHTML);
num++;
});
Than you need to add an EventListener to your button and bind the add_form_elements function to it.
Make new div, which content all you want to duplicate and is invisible.
<div class="copyable" style="display: none;">
<div class="form-title"><h3>Clinical Information</h3></div>
<div class="form-title">Time Assesed:</div>
<input class="form-field" type="time" name="timeassessd" /><br />
<div class="form-title">Blood Pressure:</div>
<input class="form-field" type="text" name="bp" /><br />
<div class="form-title">Pulse:</div>
<input class="form-field" type="date" name="pulse" /><br />
<div class="form-title">Resp. Rate:</div>
<input class="form-field" type="text" name="breathing" /><br />
<div class="form-title">Temp:</div>
<input class="form-field" type="text" name="temp" /><br />
<div class="form-title">SPO2:</div>
<input class="form-field" type="text" name="spo2" /><br />
<div class="form-title">GCS:</div>
<input class="form-field" type="text" name="gcs" /><br />
<div class="form-title">AVPU:</div>
<input class="form-field" type="text" name="avpu" /><br />
</div>
In JS file:
function add_elm(){
var content = $('.copyable').html(),
$elm = $('.elm'); //element where you want to add copyable content
$elm.append(content);
}
Note: append use for appending html inside parent node. If you want add html exactly after other elm, just use after(content) at the end of code above.
One approach to your problem, using plain JavaScript is the following (bear in mind that this does require a change to your HTML, in that the section containing the <input> elements you wish to duplicate requires a class-name (here it's "clinicalInformation", but adjust to your own requirements - remembering to change the selector held in the <button> elements' data-duplicates attribute):
// the event is passed automagically from the addEventListener()
// method:
function duplicate(event) {
// preventing the clicked-element's default behaviour
// (which in many cases could cause a page reload):
event.preventDefault();
// using Array.prototype.slice, with Function.prototype.call,
// on the NodeList returned by document.querySelectorAll(),
// to create an array of element nodes;
// 'this.dataset.duplicates' retrieves the attribute-value from
// the 'data-duplicates' attribute of the clicked element:
var allCurrent = Array.prototype.slice.call(document.querySelectorAll(this.dataset.duplicates), 0),
// getting the last element from the array of nodes:
toClone = allCurrent[allCurrent.length - 1],
// cloning that node, including its child elements:
clone = toClone.cloneNode(true),
// creating a RegExp (regular expression) literal,
// to match a sequence of one, or more, numbers (\d+)
// followed by the end of the string ($):
reg = /\d+$/,
// creating an 'empty'/unitialised variable for use
// within the (later) loop:
childElems;
// adding the created clone to the allCurrent array:
allCurrent.push(clone);
// using Array.prototype.forEach() to iterate over the
// array, the arguments (names are user-defined):
// - first (here 'fieldset') is the current array element
// over which we're iterating,
// - second (here 'index') is the index of the current
// array element in the array:
allCurrent.forEach(function(fieldset, index) {
// finding all descendant elements contained within
// the current array-element that have a 'name' attribute,
// using a CSS attribute-selector within
// document.querySelectorAll():
childElems = fieldset.querySelectorAll('[name]');
// iterating over those descendant elements in the
// array-like NodeList:
Array.prototype.forEach.call(childElems, function(elem) {
// if the regular expression matches the name (
// RegExp.prototype.test() returning a Boolean true/false
// based on the string matching, or not matching, the
// regular expression) we replace that match with the index
// (from the outer loop), or if not we simply append the
// index to the current name property-value:
elem.name = reg.test(elem.name) ? elem.name.replace(reg, index) : elem.name + index;
});
// navigating from the cloned node to its parent and, using
// Node.insertBefore(), we insert the created clone before
// the nextSibling of that cloned node:
toClone.parentNode.insertBefore(clone, toClone.nextSibling);
});
}
// getting a reference to the element that should trigger
// the duplication:
var addMore = document.getElementById('duplicate');
// adding an event-handler for the 'click' event
// (note the lack of parentheses):
addMore.addEventListener('click', duplicate)
function duplicate(event) {
event.preventDefault();
var allCurrent = Array.prototype.slice.call(document.querySelectorAll(this.dataset.duplicates), 0),
toClone = allCurrent[allCurrent.length - 1],
clone = toClone.cloneNode(true),
reg = /\d+$/,
childElems;
allCurrent.push(clone);
allCurrent.forEach(function(fieldset, index) {
childElems = fieldset.querySelectorAll('[name]');
Array.prototype.forEach.call(childElems, function(elem) {
elem.name = reg.test(elem.name) ? elem.name.replace(reg, index) : elem.name + index;
});
toClone.parentNode.insertBefore(clone, toClone.nextSibling);
});
}
var addMore = document.getElementById('duplicate');
addMore.addEventListener('click', duplicate)
label {
display: block;
}
<!-- here we're using an actual <form> element -->
<form action="#" method="post">
<!-- using a fieldset to group the related fields together -->
<fieldset class="clinicalInformation">
<!-- the <legend> element semantically titles that group
of related fields -->
<legend class="form-title">
Clinical Information
</legend>
<!-- the <label> semantically associates a text-label
with a specific form-element; that form-element
(<input />, <textarea>, <select>) can appear within
the <label>, or the <label> can have a 'for' attribute
equal to the 'id' of the associated element. -->
<label class="form-title">Time Assesed:
<input class="form-field" type="time" name="timeassessd" />
</label>
<label class="form-title">Blood Pressure:
<input class="form-field" type="text" name="bp" />
</label>
<label class="form-title">Pulse:
<input class="form-field" type="date" name="pulse" />
</label>
<label class="form-title">Resp. Rate:
<input class="form-field" type="text" name="breathing" />
</label>
<label class="form-title">Temp:
<input class="form-field" type="text" name="temp" />
</label>
<label class="form-title">SPO<sub>2</sub>:
<input class="form-field" type="text" name="spo2" />
</label>
<label class="form-title">GCS:
<input class="form-field" type="text" name="gcs" />
</label>
<label class="form-title">AVPU:
<input class="form-field" type="text" name="avpu" />
</label>
</fieldset>
<fieldset>
<button id="duplicate" data-duplicates=".clinicalInformation">Add more</button>
</fieldset>
</form>
Using jQuery, however, since you've used that tag for your question:
// binding an anonymous click event-handler, using on():
$('#duplicate').on('click', function(event) {
// preventing the default action:
event.preventDefault();
// finding all elements that match the selector from
// the clicked-element's 'data-duplicates' attribute:
var allCurrent = $(this.dataset.duplicates),
// finding the last of those elements:
toClone = allCurrent.last(),
// creating the clone, including the child elements:
clone = toClone.clone(true),
// the regular expression (as above):
reg = /\d+$/;
// adding the clone to the 'allCurrent' collection,
// then iterating over them with each(), getting a
// reference to the index of each element in the collection:
allCurrent.add(clone).each(function(index) {
// finding all descendant elements that have a name attribute,
// updating the 'name' property of each of those found
// elements using prop():
$(this).find('[name]').prop('name', function(i, n) {
// the first argument (here: 'i') is the index of the
// current element in the collection,
// the second (here: 'n') is the current value of the
// current element's property.
// exactly the same as above:
return reg.test(n) ? n.replace(reg, index) : n + index;
});
});
// inserting the clone into the document
// after the toClone element:
clone.insertAfter(toClone);
});
$('#duplicate').on('click', function(event) {
event.preventDefault();
var allCurrent = $(this.dataset.duplicates),
toClone = allCurrent.last(),
clone = toClone.clone(true),
reg = /\d+$/;
allCurrent.add(clone).each(function(index) {
$(this).find('[name]').prop('name', function(i, n) {
return reg.test(n) ? n.replace(reg, index) : n + index;
});
});
clone.insertAfter(toClone);
});
label {
display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form action="#" method="post">
<fieldset class="clinicalInformation">
<legend class="form-title">
Clinical Information
</legend>
<label class="form-title">Time Assesed:
<input class="form-field" type="time" name="timeassessd" />
</label>
<label class="form-title">Blood Pressure:
<input class="form-field" type="text" name="bp" />
</label>
<label class="form-title">Pulse:
<input class="form-field" type="date" name="pulse" />
</label>
<label class="form-title">Resp. Rate:
<input class="form-field" type="text" name="breathing" />
</label>
<label class="form-title">Temp:
<input class="form-field" type="text" name="temp" />
</label>
<label class="form-title">SPO<sub>2</sub>:
<input class="form-field" type="text" name="spo2" />
</label>
<label class="form-title">GCS:
<input class="form-field" type="text" name="gcs" />
</label>
<label class="form-title">AVPU:
<input class="form-field" type="text" name="avpu" />
</label>
</fieldset>
<fieldset>
<button id="duplicate" data-duplicates=".clinicalInformation">Add more</button>
</fieldset>
</form>
References:
CSS:
Attribute-selectors.
HTML:
Embedding custom non-visible data with the data-* attributes.
<fieldset>.
<label>.
<legend>.
Using data attributes.
JavaScript:
Array.prototype.forEach().
Array.prototype.slice().
document.querySelectorAll().
Event.preventDefault().
EventTarget.addEventListener().
Function.prototype.call().
Guide to JavaScript regular expressions.
HTMLElement.dataset.
Node.cloneNode.
Node.insertBefore.
Node.parentNode.
RegExp.
RegExp.prototype.test().
String.prototype.replace().
jQuery:
add().
clone().
each().
find().
insertAfter().
last().
on().
prop().

Trying to set an html attribute to a javascript variable

I have a variable "count" in javascript and a radio button that I want to depend on that variable. There is a button to generate more radio buttons, which is why I need their name attributes to differ.
My code:
var count = 1;
function newForm(){
...<input name=count type="radio" value="Website" />...
}
But it's just setting the name of each additional radio button to "count" rather than the number "count" represents.
Here's the whole code:
var count = 1;
function newForm(){
var newdiv = document.createElement('div');
newdiv.innerHTML = '<div class="line"></div><br><input type="text" name="Name"
class="field" placeholder="Full Event Name" /><br><input type="text" name="Location"
placeholder="Event Location" class="field" /><br> <input type="text" name="Date"
placeholder="Event Date" class="field" /> <br> <input type="text" name="End"
placeholder="Event End Date (If Applicable)" class="field" /> <br> <input type="text"
name="Time" placeholder="Event Time" class="field" /> <br> <input type="text"
name="Tags"
placeholder="Relevant Tags" class="field" /> <br> The info is from: <input name=count
type="radio" value="Tweet" checked="" />Tweet <input name=count type="radio"
value="Website"
/>Website <input name=count type="radio" value="Tweet and Website" /> Tweet and
Website';
if(count < 10) {
document.getElementById('formSpace').appendChild(newdiv);
count++;
}
}
That newdiv.innerHTML string above is all on one line in the code, by the way.
If you're trying to create an element, use createElement() :
var count = 1;
function newForm(){
var input = document.createElement('input');
input.name = count;
input.type = 'radio';
input.value = 'Website';
}
in your long string of innerHTML you need to escape your "count" variable... otherwise it's just a string... i.e.
'<input name='+count+' type="radio" value="Tweet and Website" />';
That will make it work but as everyone else is mentioning - you really shouldn't embed long html strings like this.

Switch DIV elements up/down with jQuery/JS

I'm trying to move div elements of a dynamic form up or down:
Here is my form:
<form name="f_form">
Order name <input type="text" name="ord" id="order" />
<div id="fields">
<div id="hid1"><a href="#" id="did1">
<img src="d.jpg" /></a><a href="#" id="uid1">
<img src="u.jpg" /></a><input type="text" name="p_name[]" id="names" />
<input type="text" name="quant[]" id="quant" size="3" />
<input type="text" name="pr[]" id="price" size="10" />
<input type="text" name="sum_a" id="sum" size="10" disabled="disabled"/>
</div>
<input type="button" name="nauj" id="nau" value="Add item"/><br />
</div>
</form>
When I click "add item" button JS is called:
$("#nau").click(function () {
(newdiv = document.createElement('div')).id = "hid"+ (counter + 1) +"";
newdiv.innerHTML = '<img src="d.jpg" /><img src="u.jpg" /><input type="text" name="p_name[]" id="names" />
<input type="text" name="quant[]" id="quant" size="3" />
<input type="text" name="pr[]" id="price" size="10" />
<input type="text" name="sum_a" id="sum" size="10" disabled="disabled"/>X';
document.getElementById('fields').appendChild(newdiv);
counter++;
});
Each form fields row has two arrow (up and down) images: <img src="d.jpg" /><img src="u.jpg" />
when I click on arrow I need to move all row of form fields up or down (move <DIV id=hid..>) tried like this but it didint worked.. (move up function)
$("a[id^='uid']").on('click', function() {
var numrow = $(this).attr("id");
numrow = numrow.substr(3);
var nr = 1;
sumrow = numrow - nr;
var eil = 'id=' + numrow;
numrowas = "#hid"+numrow;
srowas = "#hid"+sumrow;
$(numrowas).before($(srowas));
});
Thanks for advices.
Same sort of solution as #WTK, using .prev(), but different approach. And oh, I couldn't resist and did some cleanup ;)
See http://jsfiddle.net/WmbmF/4/
First of all you're not using on() correctly - the event handler isn't binded as you would expect. The correct syntax would be:
// "watch for" elements matching selector "a[id^='did']" created inside #fields
$("#fields").on('click', "a[id^='did']", function(e) {...})
Second of all, you are trying to operate on id attributes to deremine after/before what div to append your current element. That's messy, a cleaner approach is using .next() and .prev() to determine what is the next or previous node in relation to the clicked one.
I've created a fiddle as an example: http://jsfiddle.net/SPgax/22/
Just as a side note: your code is messy, I didn't act on it because it's beyond scope of your question. No offence :)

Categories