How to add incremental number to ID when cloned - javascript

I have a form field that I am duplicating when one clicks on the "Add" button. When an ID is duplicated, I want to add an incremental number to it. My code below is appending a 0 to the end of each new ID instead of counting. So #mark-description becomes mark-description00 instead of #mark-description2. I've looked a couple other similar posts here but am unable to determine what I'm doing wrong. Any thoughts would be much appreciated.
NOTE: I'm using ids because a jQuery plugin I'm using requires them.
Javascript:
$('#add-character-button').on('click', function () {
var source = $('.mark:last'),
clone = source.clone();
var count = 0;
clone.find('.copyme').val($(this).attr('title')).attr('id', function(i, val) {
return val + count;
});
clone.insertAfter('.mark:last');
});
HTML:
<div>
<input class="checkbox" id="standard" name="mark-type" type="checkbox" value="Standard Character">
<label class="no-placeholder" for="standard-character"></label>
<div class="standard-mark-container">
<div class="mark" id="mark-details">
<div class="mark-name">
<label class="placeholder" for="mark-name"><span>text</span></label>
<input class="copyme" id="mark-name" name="mark-name" placeholder="" title="Enter your mark name" type="text">
</div>
<div class="description">
<label class="placeholder" for="mark-description"><span>text</span
</label>
<textarea class="copyme" id="mark-description" name="mark-description" placeholder="" title="Enter a description"></textarea>
</div>
<div class="remove"> <a class="remove-mark-button" href="#" id="remove-character-button"><span>Remove</span></a>
</div>
</div>
</div>
<div class="add-mark"><a class="add-mark-button" href="#" id="add-character-button"><span>+ Add</span></a></div>
</div>

You should probably not even be using id's on the items that you are cloning. And you SHOULD be using array access notation (i.e. mark-name[]) in your field names. Without this you are only going to get one of the duplicate fields with the same name posted.
Here is what I would suggest.
HTML:
<div>
<input class="checkbox" id="standard" name="mark-type" type="checkbox" value="Standard Character">
<label class="no-placeholder" for="standard-character"></label>
<div class="standard-mark-container">
<div class="mark">
<div class="mark-name">
<label class="placeholder"><span>text</span>
<input class="copyme" name="mark-name[]" placeholder="" title="Enter your mark name" type="text">
</label>
</div>
<div class="description">
<label class="placeholder"><span>text</span>
<textarea class="copyme" name="mark-description[]" placeholder="" title="Enter a description"></textarea>
</label>
</div>
<div class="remove"><a class="remove-mark-button" href="#"><span>Remove</span></a>
</div>
</div>
</div>
<div class="add-mark"><a class="add-mark-button" href="#" id="add-character-button"><span>+ Add</span></a></div>
</div>
javascript:
$('#add-character-button').on('click', function() {
// make clone
$template = $('.mark:last');
var $clone = $template.clone();
// set values to default in clone
$clone.find('.copyme').each(function() {
$(this).val($(this).attr('title'));
});
// insert into DOM
$clone.insertAfter($template);
});
$('.remove').on('click'), function() {
$(this).closest('.mark').remove();
});
This fully eliminates the need to modify id names and simplifies your code.

is this what you're looking for? i simplified the code so i wouldnt have to type all the ids and fors and stuff. http://jsfiddle.net/swm53ran/134/
$(document).ready(function() {
var count = 0;
$('.add').on('click', function() {
count++;
var clone = $('.template').clone('true').removeClass('template');
clone.find('textarea').attr('id', 'textarea' + count);
clone.find('textarea').html('Id: ' + clone.find('textarea').attr('id'));
clone.appendTo('.sections');
});
});
Add
<div class="sections">
<div class="template section">
<input type="checkbox" /><br/>
text <input type="text"/><br/>
textarea <textarea id="textarea">Id: textarea</textarea>
</div>
</div>
although, i would suggest not using id's, but if you're intent on using them, this should work for your purposes.

Related

addEventListener for input not working anymore after validation error is thrown

The problem
I use a form on a webpage where users fill in all sorts of details. There are 3 fields which generate the input for another field. That field gets generated like this: Firstname + Lastname + Date of birth. However, when a validation error is thrown on the form and the page reloads, the generated input isn't the expected format anymore. Only the Date of birth is then in that input.
It looks like it isn't initializing the Firstname + Lastname field anymore after a validation error is thrown on the page. Any suggestions on how to make it so that the fields gets initialized constantly? Or is there maybe a better way to handle this?
This is the code I use for the generated input
window.onload = function() {
let studentNoField = document.getElementById('input_7_9');
let enteredDetails = {
name: '',
lastname: '',
date: ''
};
/* set value in the third input: Studentnummer */
function generateInput() {
let studentNumber = Object.values(enteredDetails).join('').toLowerCase();
studentNoField.value = studentNumber;
}
/* event listener for first input: Voornaam */
document.getElementById('input_7_1').addEventListener('input', function(event) {
enteredDetails.name = event.target.value.replace(/\s/g, '').slice(0, 8);
generateInput();
});
/* event listener for second input: Achternaam */
document.getElementById('input_7_25').addEventListener('input', function(event) {
enteredDetails.lastname = event.target.value.replace(/\s/g, '').slice(0, 8);
generateInput();
});
/* event listener for second input: Date */
document.getElementById('input_7_3').addEventListener('input', function(event) {
enteredDetails.date = event.target.value.replace(/-/g, '').slice(0, 4);
generateInput();
});
/* Get selected training and format it properly for the PDF */
jQuery('#input_7_23').change(function(e) {
var optionChange = jQuery('#input_7_23 option:selected').text().toUpperCase();
jQuery('#input_7_58').val(optionChange);
});
}
<html>
<body>
<form method="post" enctype="multipart/form-data" id="gform_7" action="/budget/" _lpchecked="1">
<div>
<div id="gform_fields_7">
<div id="field_7_9">
<label for="input_7_9">Studentnummer
<input name="input_9" id="input_7_9" type="text" value="" maxlength="20" aria-required="true" aria-invalid="false">
</div>
</div>
<div id="field_7_1">
<label for="input_7_1">Voornaam</label>
<div><input name="input_1" id="input_7_1" type="text" value="" aria-required="true" aria-invalid="false"> </div>
</div>
<div id="field_7_25">
<label for="input_7_25">Achternaam</label>
<div><input name="input_25" id="input_7_25" type="text" value="" aria-required="true" aria-invalid="false"> </div>
</div>
<div id="field_7_3">
<label for="input_7_3">Geboortedatum</label>
<div>
<input name="input_3" id="input_7_3" type="text" value="" placeholder="dd-mm-yyyy" aria-describedby="input_7_3_date_format" aria-invalid="false" aria-required="true">
<span id="input_7_3_date_format">DD dash MM dash JJJJ</span>
</div>
</div>
</div>
</div>
<div>
<input type="submit" id="gform_submit_button_7" value="Versturen" onclick="if(window["gf_submitting_7"]){return false;} window["gf_submitting_7"]=true; " onkeypress="if( event.keyCode == 13 ){ if(window["gf_submitting_7"]){return false;} window["gf_submitting_7"]=true; jQuery("#gform_7").trigger("submit",[true]); }">
</div>
</form>
</body>
</html>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Any help or suggestions is appreciated.
There were a few non-existing ids referenced in your code. In the following snippet I have tried to "correct" these errors, but I also went further: I removed all repetitions, thereby following the DRY principle "Don't repeat yourself". The "input"-event listener now works for all elements of the inps array. There is, however one differentiation: the first two elements are limited to 8 characters while the date is limited to 4: .slice(0,i<2?8:4).
const [stNr, ...inps]=[9, 1, 25, 3].map(n=> document.getElementById(`input_7_${n}`));
inps.forEach(inp=>inp.addEventListener("input",()=>
stNr.value=inps.map((el,i)=>
el.value.replace(/[\s-]/g,"").slice(0,i<2?8:4).toLowerCase()
).join(""))
)
<form method="post" enctype="multipart/form-data" id="gform_7" action="/budget/" _lpchecked="1">
<div>
<div id="gform_fields_7">
<div id="field_7_9">
<label for="input_7_9">Studentnummer</label>
<input name="input_9" id="input_7_9" type="text" value="" maxlength="20" aria-required="true" aria-invalid="false">
</div>
</div>
<div id="field_7_1">
<label for="input_7_1">Voornaam</label>
<div><input name="input_1" id="input_7_1" type="text" value="" aria-required="true" aria-invalid="false"> </div>
</div>
<div id="field_7_25">
<label for="input_7_25">Achternaam</label>
<div><input name="input_25" id="input_7_25" type="text" value="" aria-required="true" aria-invalid="false"> </div>
</div>
<div id="field_7_3">
<label for="input_7_3">Geboortedatum</label>
<div>
<input name="input_3" id="input_7_3" type="text" value="" placeholder="dd-mm-yyyy" aria-describedby="input_7_3_date_format" aria-invalid="false" aria-required="true">
<span id="input_7_3_date_format">DD dash MM dash JJJJ</span>
</div>
</div>
</div>
</div>
<div>
<input type="submit" id="gform_submit_button_7" value="Versturen">
</div>
</form>
I removed your jQuery statements at the end of your script, as they referred to non-existent ids. These statements can definitely also be re-written in Vanilla JS, if necessary.
And, as #CherryDT already mentioned: there is no validation code visible here. If it happens on the server then it is the server's responsibility to produce a suitable response that allows the client to render the page with the previously (possibly annotated) content.

Change the value of Input file (Don't work)

I have a little script which create a new div block if the user click on button. To count how many are created I have an hidden input. Everytime a new block is created the value of this hidden input should get updated.
Thats my script:
$(function () {
$("#addBtn3").on("click", function () {
imageBlockCount++;
document.getElementById("counter").value = imageBlockCount;
$(
$.parseHTML(
`<div class="form-group" id="gallery-${imageBlockCount}" >
<label for="new-content-${imageBlockCount}">New Content</label>
<input type="text" name="content-${imageBlockCount}" class="form-control" id="new-content-${imageBlockCount} test-${imageBlockCount}" placeholder="new content" required>
</div>`
)
).appendTo("#newElements");
});
});
This is my html code:
<div style="flex:auto;text-align:right;">
<button id="addBtn3" type="button">Content +</button>
</div>
<input name="counter" type="text" id="counter" value="0" hidden>
<div id="newElements">
</div>
But in the script where it should update the value don't work, but I don't know why, I don't find any other methods which are so different.
Your code works fine. place console.log($("#counter").val()) after appendTo.
A webpage's HTML doesn't automatically update when an input field's value changes.
If you want such functionality, you could place this after updating value of #counter:
$('#counter').attr('value', $('#counter').val());
$(function () {
let imageBlockCount = 0
$("#addBtn3").on("click", function () {
imageBlockCount++;
document.getElementById("counter").value = imageBlockCount;
$('#counter').attr('value', $('#counter').val());
$(
$.parseHTML(
`<div class="form-group" id="gallery-${imageBlockCount}" <label for="new-content-${imageBlockCount}">New Content</label>
<input type="text" name="content-${imageBlockCount}" class="form-control" id="new-content-${imageBlockCount} test-${imageBlockCount}" placeholder="new content" required>
</div>`
)
).appendTo("#newElements");
console.log($('#counter').val())
});
});
<div style="flex:auto;text-align:right;">
<button id="addBtn3" type="button">Content +</button>
</div>
<input name="counter" type="text" id="counter" value="0" hidden>
<div id="newElements">
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

Custom javascript to check if fields are required

I have a some custom validation for a small input form, that checks if a field is required. If it is a required field it alerts the user, if there is no value. At the moment it will validate all inputs other than check boxes.
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form>
<div class="ss-item-required">
<label>Question: What is your name?</label>
<input type="text" name="name" id="name"></input>
</div>
<div class="ss-item-required">
<label>Question: What is your email?</label>
<input type="text" name="email" id="email"></input>
</div>
<div class="ss-item-required">
<label>Question: What is your address?</label>
<textarea name="address" rows="8" cols="75" id="address"></textarea>
</div>
<div class="ss-item-required">
<label>Do you agree to out terms?</label>
<input type="checkbox" name="Check_0">
</div>
Submit
</form>
<script>
function formcheck() {
var fields = $(".ss-item-required")
.find("select, textarea, input").serializeArray();
$.each(fields, function(i, field) {
if (!field.value)
alert(field.name + ' is required');
});
console.log(fields);
}
</script>
If anyone can work out how to include validation of check boxes, it would be much appreciated.
Even though some answers already provide a solution, I've decided to give mine, that will validate every required input in your form, regardless of being a checkbox (maintaining your each loop).
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form>
<div class="ss-item-required">
<label>Question: What is your name?</label>
<input type="text" name="name" id="name">
</div>
<div class="ss-item-required">
<label>Question: What is your email?</label>
<input type="text" name="email" id="email">
</div>
<div class="ss-item-required">
<label>Question: What is your address?</label>
<textarea name="address" rows="8" cols="75" id="address"></textarea>
</div>
<div class="ss-item-required">
<label>Do you agree to out terms?</label>
<input type="checkbox" name="Check_0">
</div>
Submit
</form>
<script>
function formcheck() {
var fields = $(".ss-item-required")
$.each(fields, function(i, field) {
field=$(field).find('input, select, textarea')[0]
if (!field.value || (field.type=='checkbox' && !field.checked))
alert(field.name + ' is required');
});
}
</script>
The problems were:
serializeArray() would try to get the value from your checkbox, and because it returned nothing, the checkbox input was never added to fields!
Checkboxes don't have a property value, instead they are checked
There is more than one way to determine this:
Check the length of the JQuery wrapped set that queries for only checked checkboxes and see if it is 1:
if($("input[name='Check_0']:checked").length === 1)
Check the checked property of the DOM element itself (which is what I'm showing below) for false. To extract the DOM element from the JQuery wrapped set, you can pass an index to the wrapped set ([0] in this case), which extracts just that one item as a DOM element and then you can use the standard DOM API.
if(!$("input[type='checkbox']")[0].checked)
NOTE: It's important to understand that all client-side validation can be easily bypassed by anyone who really wants to. As such, you
should always do a second round of validation on the server that will
be receiving the data.
FYI: You have some invalid HTML: There is no closing tag for input elements and for label elements, you must either nest the element that the label is "for" inside of the label or you must add the for attribute to the label and give it a value of the id of the element that the label is "for". I've corrected both of these things below:
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form>
<div class="ss-item-required">
<label for="userName">Question: What is your name?</label>
<input type="text" name="userName" id="userName">
</div>
<div class="ss-item-required">
<label for="email">Question: What is your email?</label>
<input type="text" name="email" id="email">
</div>
<div class="ss-item-required">
<label for="address">Question: What is your address?</label>
<textarea name="address" rows="8" cols="75" id="address"></textarea>
</div>
<div class="ss-item-required">
<label for="Check_0">Do you agree to out terms?
<input type="checkbox" name="Check_0">
</label>
</div>
Submit
</form>
<script>
function formcheck() {
var fields = $(".ss-item-required")
.find("select, textarea, input").serializeArray();
$.each(fields, function(i, field) {
if (!field.value){
alert(field.name + ' is required');
}
});
// Check to see if the input is a checkbox and if it's checked
if(!$("input[type='checkbox']")[0].checked){
alert("You must agree to the terms to continue.");
}
}
</script>
Personally (and I'm far from alone on this), the use of JQuery is way overused in today's world. When it came out, the standard DOM API wasn't as mature as it is now and JQuery made DOM element selection and manipulation very simple. Back then, JQuery was a Godsend.
Today, the DOM API has matured and much of what we use to rely on JQuery to make easy, can be done just as easily without JQuery. This means you don't have to reference the JQuery library at all (faster page loading) and you're code follows standards.
If you're interested, here's your code without JQuery:
<form>
<div class="ss-item-required">
<label for="userName">Question: What is your name?</label>
<input type="text" name="name" id="userName">
</div>
<div class="ss-item-required">
<label for="email">Question: What is your email?</label>
<input type="text" name="email" id="email">
</div>
<div class="ss-item-required">
<label for="address">Question: What is your address?</label>
<textarea name="address" rows="8" cols="75" id="address"></textarea>
</div>
<div class="ss-item-required">
<label for="Check_0">Do you agree to out terms?
<input type="checkbox" name="Check_0">
</label>
</div>
Submit
</form>
<script>
function formcheck() {
// Get all the required elements into an Array
var fields = [].slice.call(document.querySelectorAll(".ss-item-required > *"));
// Loop over the array:
fields.forEach(function(field) {
// Check for text boxes or textareas that have no value
if ((field.type === "text" || field.nodeName.toLowerCase() === "textarea")
&& !field.value){
alert(field.name + ' is required');
// Then check for checkboxes that aren't checked
} else if(field.type === "checkbox" && !field.checked){
alert("You must agree to the terms to continue.");
}
});
}
</script>

jQuery - Taking user input and inserting it into a multiple divs that have a class

I am trying to use jQuery to take the user input and insert it into multiple divs with the class of userInput. I was able to use vanilla JavaScript but i don't want to keep repeating my code using ID's.
So far i can take the user input and display it as an alert so i know its being read. So can i take this input from the input field and place it into a class?
<form>
<input class="userInput" type="text" maxlength="10" onclick="insertInput()" placeholder="Username" required><br>
<a href="#chapter-1">
<div id="submitbutton" class="button">Continue</div>
</a>
</form>
$(function() {
$("#submitbutton").click(function() {
alert($(".userInput").val());
});
});
$(function() {
$("#submitbutton").click(function() {
$('.userInput').text($(".userInput").val());
});
});
check this fiddle
Define number of divs having same class.Then just set the input value to class as text.
$(function() {
$("#submitbutton").click(function() {
var value = $(".userInput").val();
$(".insert").text(value);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form>
<input class="userInput" type="text" maxlength="10" placeholder="Username" required><br>
<a href="#chapter-1">
<div id="submitbutton" class="button"> Continue</div>
</a>
</form>
<div class="insert">
</div>
<div class="insert">
</div>
<div class="insert">
</div>
Something like so:
var elements = document.querySelectorAll('p.userInput');
var doAction = function(event) {
var inputValue = document.querySelector('input.userInput').value;
for(var i=0; i < elements.length; i++) {
elements[i].innerHTML = inputValue;
}
}
var element = document.querySelector('#submitbutton');
element.addEventListener('click', doAction);
<form>
<input class="userInput" type="text" maxlength="10" placeholder="Username" required><br>
<a href="#chapter-1">
<div id="submitbutton" class="button"> Continue</div>
</a>
</form>
<p class="userInput"> </p>
<p class="userInput"> </p>
<p class="userInput"> </p>
No reason to use jQuery.

I have two radio button but the the form only can get one radio value even we choose different radio

I want to get the value from radio button that we have choose then multiple with the number in grossSalary. The result will be display on a textbox called epf. There are an error happening, the form only get 0.09 value even we choose 11% radio button.
Here is my javascript
<script>
function get(percent)
{
var percent = document.getElementById('percent').value;
var grossSalary= document.getElementById('grossSalary').value;
var epf = parseFloat(percent)*parseFloat(grossSalary);
epf = epf.toFixed(2);
document.getElementById('epf').value = epf;
}
</script>
Here is my form coding:
<div class="form-group">
<label>Gross Salary</label>
<input type="text" class="form-control" id="grossSalary" name="gross_salary">
</div>
<div class="form-group">
<label>EPF</label>
<input type="radio" id="percent" name="percent" value="0.09" onclick="get(this.value)">9%
<input type="radio" id="percent" name="percent" value="0.11" onclick="get(this.value)">11%
<input type="text" id ="epf" class="form-control" name="epf" >
</div>
</form>
You could use the name instead of the id (because id has to be unique). Also, with jQuery, you could use the change event.
i.e. :
HTML :
<div class="form-group">
<label>Gross Salary</label>
<input type="text" class="form-control" id="grossSalary" name="gross_salary">
</div>
<div class="form-group">
<label>EPF</label>
<input type="radio" name="percent" value="0.09">9%
<input type="radio" name="percent" value="0.11">11%
<input type="text" id ="epf" class="form-control" name="epf" >
</div>
JS :
$("input[name=percent]").change(function() {
var percent = $(this).val();
var grossSalary= $("#grossSalary").val();
var epf = parseFloat(percent)*parseFloat(grossSalary);
$("#epf").val(epf.toFixed(2));
});
Here is the working example on JSFiddle.
Hope it helps.
EDIT Don't forget to include jQuery source in your html file :
One file template :
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<div class="form-group">
<label>Gross Salary</label>
<input type="text" class="form-control" id="grossSalary" name="gross_salary">
</div>
<div class="form-group">
<label>EPF</label>
<input type="radio" name="percent" value="0.09">9%
<input type="radio" name="percent" value="0.11">11%
<input type="text" id ="epf" class="form-control" name="epf" >
</div>
<script>
$("input[name=percent]").change(function() {
var percent = $(this).val();
var grossSalary= $("#grossSalary").val();
var epf = parseFloat(percent)*parseFloat(grossSalary);
$("#epf").val(epf.toFixed(2));
});
</script>
When you are using JS or Jquery than always remember one key point that:
id: used for single selection
class: used for multiple selection
In your case you are using same id for different tags, in that case it returns the first matching html value.
So to get rid of this, you have to use class and iterate over them and get the values.

Categories