JS: prevent reseting of form fields after adding new form - javascript

I have below code where I add new form after clicking button. If I put some values into the fields everything is reseted. I would like to prevent that.
I tried e.preventDefault() and return false but it's not working as I would like to.
Additionally after clicking 'add button' I am taking data from json file.
Please see my code here. Any help will be appreciated.
// add new product to the list
const newLocal = document.querySelector('.add-product-button');
const addNewProduct = newLocal;
const listProduct = document.querySelector('.products-list');
const changeVisibility = document.getElementById('change-visibility');
let productCounter = 1;
addNewProduct.addEventListener('click', e => {
e.preventDefault();
productCounter++;
generateTemplate();
changeVisibility.style.display = 'block';
});
const generateTemplate = (e) => {
const html = `
<li>
<div class="first-product-indicator">
<div class="first-product-border-line"></div>
<div class="product-number">${productCounter}</div>
</div>
<form action="" method="get" class="form-product">
<select name="product-type" id="product-type" class="" required>
<option value="" disabled selected hidden>Typ Produktu</option>
<option value="produkt" >PRODUKT GOTOWY</option>
<option value="materiały" >MATERIAŁY POMOCNICZE</option>
<option value="surowce" >SUROWCE</option>
</select>
<div class="product-container">
<select name="product" id="product" class="option-field product-list" required>
<option value="" disabled selected hidden>Produkt</option>
</select>
<i class="fas fa-plus-circle add-product"></i>
</div>
<div class="form-price">
<input type="number" id="quantity" name="quantity" placeholder="Ilość">
<input type="number" id="netto" name="netto" placeholder="Netto">
<input type="number" id="brutto" name="brutto" placeholder="Brutto">
</div>
<div class="form-total-price">
<input type="number" id="netto-total" name="netto-total" placeholder="Wartość netto">
<input type="number" id="brutto-total" name="brutto-total" placeholder="Wartość brutto">
</div>
</form>
</li>
`;
listProduct.innerHTML += html;
// populate product select field with values from json file (finished_good.json)
let newProductElement = document.querySelector('.products-list').lastElementChild;
let dropdownProductAdd = newProductElement.querySelector('.product-list');
dropdownProductAdd.length = 0;
let defaultOptionProductAdd = document.createElement('option');
defaultOptionProductAdd.text = 'Produkt';
dropdownProductAdd.add(defaultOptionProductAdd);
dropdownProductAdd.removeIndex = 0;
const urlProductAdd = 'finished_good.json';
const requestProductAdd = new XMLHttpRequest();
requestProductAdd.open('GET', urlProductAdd, true);
requestProductAdd.onload = function() {
if (requestProductAdd.status === 200) {
const dataProductAdd = JSON.parse(requestProductAdd.responseText);
let optionProductAdd;
for (let i = 0; i < dataProductAdd.length; i++) {
optionProductAdd = document.createElement('option');
optionProductAdd.text = dataProductAdd[i].name;
dropdownProductAdd.add(optionProductAdd);
}
} else {
// Reached the server, but it returned an error
}
}
requestProductAdd.onerror = function() {
console.error('An error occurred fetching the JSON from ' + urlProductAdd);
};
requestProductAdd.send();
e.preventDefault();
};

Related

JS Function is not defined but it is

Hey guys I have this js snippet:
<script type="text/javascript">
function displayDeliveryOptions() {
var deliveryType = document.querySelector('input[name="deliveryType"]:checked').value;
if (deliveryType === "homedelivery") {
document.getElementById("pickupOptions").style.display = "none";
document.getElementById("deliveryOptions").style.display = "block";
} else {
document.getElementById("pickupOptions").style.display = "block";
document.getElementById("deliveryOptions").style.display = "none";
}
}
function updateDeliveryPrice() {
var selectedOption = document.querySelector('[name="deliveryTime"] option:checked');
document.querySelector('#deliveryPrice').value = selectedOption.dataset.price;
document.getElementById('priceLbl').innerHTML = selectedOption.dataset.price + '€';
var total = #Model.Total + parseInt(selectedOption.dataset.price);
totalLbl.textContent = total;
}
function submitForm() {
var formData = new FormData(document.getElementById("deliveryForm"));
fetch("/checkout", {
method: "POST",
body: formData
})
.then(response => response.json())
.then(data => {
console.log(data);
})
.catch(error => {
console.error(error);
});
}
</script>
That applies to the following HTML:
<div><form id="deliveryForm" method="post">
<label>
<input type="radio" name="deliveryType" value="homedelivery" onchange="displayDeliveryOptions()"> Home Delivery
</label>
<br>
<label>
<input type="radio" name="deliveryType" value="pickup" onchange="displayDeliveryOptions()"> Pickup
</label>
<br>
<div id="pickupOptions" style="display:none">
<label for="pickupLocation">Pickup Location:</label><br>
<select name="pickupLocation">
#foreach (PickUp x in Model.PickUpList.DistinctBy(x => x.Location))
{
<option value="#x.Location">#x.Location</option>
}
</select>
<br>
<label for="pickupDate">Pickup Date:</label><br>
<select name="pickupDate">
#foreach (PickUp x in Model.PickUpList.DistinctBy(x => x.Timeslot.Date))
{
if (x.DeliveryStatus == DeliveryStatus.AVAILABLE)
{
<option value="#x.Timeslot.Date">#x.Timeslot.Date.ToShortDateString()</option>
}
}
</select>
<br>
<label for="pickupTime">Pickup Time:</label><br>
<select name="pickupTime">
#foreach (PickUp x in Model.PickUpList.DistinctBy(x => x.Timeslot.Time))
{
if (x.DeliveryStatus == DeliveryStatus.AVAILABLE)
{
<option value="#x.Timeslot.Time">#x.Timeslot.Time</option>
}
}
</select>
</div>
<div id="deliveryOptions" style="display:none">
<label for="deliveryDate">Delivery Date:</label><br>
<select name="deliveryDate">
#foreach (HomeDelivery x in Model.DeliveryList.DistinctBy(x => x.Timeslot.Date))
{
if (x.DeliveryStatus == DeliveryStatus.AVAILABLE)
{
<option value="#x.Timeslot.Date">#x.Timeslot.Date.ToShortDateString()</option>
}
}
</select>
<br>
<label for="deliveryTime">Delivery Time and Price:</label><br>
<select name="deliveryTime" onchange="updateDeliveryPrice()">
#foreach (HomeDelivery x in Model.DeliveryList.DistinctBy(x => x.Timeslot.Time))
{
if (x.DeliveryStatus == DeliveryStatus.AVAILABLE)
{
<option value="#x.Timeslot.Time" data-price="#x.Price">#x.Timeslot.Time - #x.Price</option>
}
}
</select>
<input type="hidden" name="deliveryPrice" id="deliveryPrice">
</div>
</form> <input class="btn btn-dark rounded-pill py-2 btn-block" type="button" value="Pay!" onclick="submitForm()" />
</div>
I get the error Uncaught ReferenceError: function is not defined on displayDeliveryOptions but it doesn't make any sense because it is defined.
Any ideas? I've been stuck on it for hours and I'm in an absolute deadlock.
Thank you in advance
EDIT: So apparently the JS snippets work, displayDeliveryOptions and submitForm work but only if updateDeliveryPrice is removed from the code, what is going on here?
EDI2: Fixed by changing the updateDeliveryPrice to
function updateDeliveryPrice() {
const deliveryTimeOption = document.querySelector('select[name="deliveryTime"] option:checked');
const deliveryPrice = deliveryTimeOption.getAttribute('data-price');
document.getElementById('deliveryPrice').value = deliveryPrice;
}
Fixed by changing the updateDeliveryPrice to
function updateDeliveryPrice() {
const deliveryTimeOption = document.querySelector('select[name="deliveryTime"] option:checked');
const deliveryPrice = deliveryTimeOption.getAttribute('data-price');
document.getElementById('deliveryPrice').value = deliveryPrice;
}
not sure where the error was but it works now! Yay!

Fields Added Via Javascript not posting Data into $POST

I have created a form which can be dynamically changed using the buttons included. These buttons allow for more input fields to be added/removed. The issue is that the input fields created are not posting any data/ Values in those fields not being added to the $POST array on the submit of the form.
The main functions below resposible for adding and removing rows is RemoveRows() and addRows()
What should happen is that on submit all values in the form should be "posted" then I can access all of those fields via $_POST["nameOfField"].
The way I have currently approached this is to create an input fields with the relevant id's and names then append that field to where the "hard coded" fields exists.
From my initial debugging none of the fields that have been added via javascript are in $Post which I have checked via var_dump($_REQUEST);
I have also seen that the nodes that are added are not elements of the form tag even though the nodes are added between the opening and closing tag. This can be seen in the doBeforeSubmit() Function where we can see all elements that are children of the and this never changes as rows are added/removed.
function showPlatforms() {
let nacellesOptions = ["Option1", "option2", "Option3"];
let milOptions = ["Option1", "option2", "Option3"]
let highOptions = ["Option1", "option2", "Option3"]
let entry = document.getElementById("vs")
let platfom = document.getElementById("platform")
if (platform.hasChildNodes()) {
var lastChild = platfom.lastElementChild
while (lastChild) {
platfom.removeChild(lastChild)
lastChild = platform.lastElementChild
}
}
if (entry.value == "Nacelles") {
for (var i = 0; i < 2; i++) {
var option = document.createElement("option");
option.value = nacellesOptions[i]
option.innerHTML = nacellesOptions[i]
platform.appendChild(option)
}
} else if (entry.value == "Military") {
for (var i = 0; i < 2; i++) {
var option = document.createElement("option");
option.value = milOptions[i]
option.innerHTML = milOptions[i]
platform.appendChild(option)
}
} else {
for (var i = 0; i < 2; i++) {
var option = document.createElement("option");
option.value = highOptions[i]
option.innerHTML = highOptions[i]
platform.appendChild(option)
}
}
}
function formOptions() {
let entry = document.getElementById("type")
if (entry.value == "Engineering MAM") {
document.getElementById("WBS").disabled = false
document.getElementById("Desc").disabled = false
document.getElementById("ProName").disabled = false
} else {
document.getElementById("WBS").disabled = true
document.getElementById("Desc").disabled = true
document.getElementById("ProName").disabled = true
}
}
function formoptions2() {
let entry2 = document.getElementById("organisation")
if (entry2.value == "Aftermarket") {
document.getElementById("COT").disabled = false
document.getElementById("COC").disabled = false
} else {
document.getElementById("COT").disabled = true
document.getElementById("COC").disabled = true
}
}
count = document.getElementById("partNum").childElementCount
function addRows() {
rowNames = ["partNum", "partDesc", "leadTime", "quantity", "dateReq", "unitCost", "unitExtention", "unitSaleValue", "estSalesValue"]
rowNames.forEach(addRow, count)
count = document.getElementById("partNum").childElementCount
//doBeforeSubmit()
}
function doBeforeSubmit() {
var es = document.getElementById("form").elements;
var l = es.length;
var msgs = [];
for (var idx = 0; idx < l; idx++) {
var e = es[idx];
msgs.push('name=' + e.name + ', type=' + e.type + ', value=' + e.value);
}
alert(msgs.join('\n'));
return false;
}
function addRow(id) {
let col = document.getElementById(id)
var box = document.createElement("INPUT")
box.setAttribute("type", "text")
box.setAttribute("id", id + count)
box.setAttribute("name", id + count)
box.setAttribute("class", "form-control")
col.appendChild(box)
}
function RemoveRows() {
rowNames = ["partNum", "partDesc", "leadTime", "quantity", "dateReq", "unitCost", "unitExtention", "unitSaleValue", "estSalesValue"]
rowNames.forEach(removeBoxes)
count = document.getElementById("partNum").childElementCount
}
function removeBoxes(item) {
let box = document.getElementById(item)
let last = box.lastChild
box.removeChild(last)
}
function checkData() {
// if all stuff is correct do this:
document.getElementById("submit").disabled = false
// else dont activate the submit button.
}
<form method="post" id="form" action="SubmitMAM.php">
<div class="row" id="productRow" style="width:95%; margin:auto">
<div id="partNo" class="col-2">
<h3>Part Number:</h3>
</div>
<div class="col-2">
<h3>Part Description:</h3>
</div>
<div class="col-1">
<h3>Lead Time:</h3>
</div>
<div class="col-1">
<h3>Quantity:</h3>
</div>
<div class="col-1">
<h3>Date Required:</h3>
</div>
<div class="col-1">
<h3>Unit Cost:</h3>
</div>
<div class="col-2">
<h3>Unit Cost Extension:</h3>
</div>
<div class="col-1">
<h3>Unit Sale Value:</h3>
</div>
<div class="col-1">
<h3>Est Sales Value:</h3>
</div>
</div>
<div class="row" id="productRow" style="width:95%; margin:auto">
<div id="partNum" class="col-2">
<input type="text" id="partNum0" class="form-control" name="partNum0">
</div>
<div id="partDesc" class="col-2">
<input type="text" id="partDesc0" class="form-control" name="partDesc0">
</div>
<div id="leadTime" class="col-1">
<input type="text" id="leadTime0" class="form-control" name="leadTime0">
</div>
<div id="quantity" class="col-1">
<input type="text" id="quanitity0" class="form-control" name="quantity0">
</div>
<div id="dateReq" class="col-1">
<input type="text" id="dateReq0" class="form-control" name="dateReq0">
</div>
<div id="unitCost" class="col-1">
<input type="text" id="unitCost0" class="form-control" name="unitCost0">
</div>
<div id="unitExtention" class="col-2">
<input type="text" id="unitExtention0" class="form-control" name="unitExtention0">
</div>
<div id="unitSaleValue" class="col-1">
<input type="text" id="unitSaleValue0" class="form-control" name="unitSaleValue0">
</div>
<div id="estSalesValue" class="col-1">
<input type="text" id="estSalesValue0" class="form-control" name="estSalesValue0">
</div>
<button onclick="addRows()" class="btn btn-primary" type="button">Add a Product</button>
<button onclick="RemoveRows()" class="btn btn-primary" type="button">Remove Row</button>
<button onclick="checkData()" class="btn btn-primary" type="button">Check Data</button>
<br>
<button type="submit" name="submit" id="submit" class="btn btn-primary" disabled>Submit</button>
</form>
PHP:
<?php
var_dump($_REQUEST)
?>
UPDATE:
The code has been changed to use a php array by adding square brackets into the name which produces the following html:
<input type="text" id="partNum0" class="form-control" name="partNum[]">
<input type="text" id="partNum1" name="partNum[]" class="form-control">
<input type="text" id="partNum2" name="partNum[]" class="form-control">
You just need to use the name property of the input and add [] at the end, as GrumpyCrouton said. PHP parse it as an array, and you can access it as:
$partNum = $_POST["partNum"];
FIXED: It turns out the above code did not have any issues with the logic or the way it should work, in the source code in visual studio the indentation of some of the Divs was off causing the browser to have issues in rendering the form correctly hence why the added boxes were not included in the form and their values not POSTED.
As a heads up to anyone with maybe a similar issue, it pays to have your code neat.

Form validation not working with vanilla js

I'm trying to do my first form validation with only Vanilla JS.
I have a form, that has two selects in which you have to select your department and depending on this it will allow you to select another location. I made a script for this.
Now, when I relate another script which is formValidation, it doesn't work and I guess I'm doing the form validation well. I'm starting doing it so it only has one validation but it isn't working.
What could be the problem? When i wrote the form validation in the script file, it override the function or the selects so it didn't work. I don't know how to else doing a form validation because I'm new to JS and I'm not allowed to use jquery or anything.
Thanks
Here is the code pen:
https://codepen.io/yomiram/pen/abNMaMy
HTML :
<section id="formSection">
<span class="textForm">Formulario</span>
<hr>
<form action="/" id="form" action="GET">
<div class="form-group">
<input type="text" placeholder="Nombre" id="name" class="input-control" required/>
<input type="text" placeholder="Apellido" id="lastName" class="input-control" />
</div>
<div class="form-group">
<input type="email" placeholder="E-mail" id="email" class="input-control" required/>
</div>
<div class="form-group">
<select class="input-control" style="flex: 6" id="dpto" required>
<option selected="selected" class="department">Departamento</option>
</select>
<select class="input-control" placeholder="Localidad" id="location" style="flex:6" required>
<option selected="selected" class="department">Localidad</option>
</select>
</div>
<div class="form-group">
<input type="number" id="ci" class="input-control" placeholder="C.I" style="flex:6" required/>
</div>
<div class="form-group">
<input type="checkbox" name="conditions" id="conditions" required>
<label for="conditions" id="conditions"> Acepto las bases y condiciones</label><br>
</div>
<div class="form-group">
<input type="submit" id="formButton" class="formButton" value="Enviar">
</div>
</form>
</section>
SCRIPT JS (SELECT FUNCTION):
// DISPLAYING DATA IN SELECT
var dptosLocs = {
"Artigas":["Artigas"," Bella Unión"],
"Canelones":["Canelones"," Santa Lucía"],
"Montevideo":["Montevideo"],
"Salto":["Salto"," Daymán"," Arapey"]
};
var sel = document.getElementById('dpto');
var fragment = document.createDocumentFragment();
Object.keys(dptosLocs).forEach(function(dptosLoc, index) {
var opt = document.createElement('option');
opt.innerHTML = dptosLoc;
opt.value = dptosLoc;
fragment.appendChild(opt);
});
sel.appendChild(fragment);
document.getElementById("dpto").onchange = function() {defineDpto()};
function defineDpto() {
var dpto = document.getElementById("dpto").value;
if (dpto == "Artigas" ) {
var sel = document.getElementById('location');
var fragment = document.createDocumentFragment();
Object.values(dptosLocs["Artigas"]).forEach(function(dptosLoc, index) {
var opt = document.createElement('option');
opt.innerHTML = dptosLoc;
opt.value = dptosLoc;
fragment.appendChild(opt)
sel.appendChild(fragment);
});
} else if (dpto == "Canelones") {
document.getElementById('location').options.length = 0;
var sel = document.getElementById('location');
var fragment = document.createDocumentFragment();
Object.values(dptosLocs["Canelones"]).forEach(function(dptosLoc, index) {
var opt = document.createElement('option');
opt.innerHTML = dptosLoc;
opt.value = dptosLoc;
fragment.appendChild(opt)
sel.appendChild(fragment);
});
} else if (dpto == "Montevideo") {
document.getElementById('location').options.length = 0;
var sel = document.getElementById('location');
var fragment = document.createDocumentFragment();
Object.values(dptosLocs["Montevideo"]).forEach(function(dptosLoc, index) {
var opt = document.createElement('option');
opt.innerHTML = dptosLoc;
opt.value = dptosLoc;
fragment.appendChild(opt)
sel.appendChild(fragment);
});
} else if (dpto == "Salto") {
document.getElementById('location').options.length = 0;
var sel = document.getElementById('location');
var fragment = document.createDocumentFragment();
Object.values(dptosLocs["Salto"]).forEach(function(dptosLoc, index) {
var opt = document.createElement('option');
opt.innerHTML = dptosLoc;
opt.value = dptosLoc;
fragment.appendChild(opt)
sel.appendChild(fragment);
});
}
}
FORM VALIDATION:
function validar (){
var name, lastName, email, dpto, location, ci, condictions, expresion;
name = document.getElementById('name').value;
lastName = document.getElementById('lastName').value;
email = document.getElementById('email').value;
dpto = document.getElementById('dpto').value;
location = document.getElementById('location').value;
ci = document.getElementById('ci').value;
conditions = document.getElementById('conditions').value;
if (name === ""){
alert("El campo nombre está vacío");
}
}
The problem with your script is that the validar() function is never called.
Please, remember, if you write a function and you never call it in your code, it will never be executed.
What you have to do is to add the call to your validar() function in the onsubmit event of the form.
<form action="/" id="form" action="GET" onsubmit="return validar();">
And your validar() function should return false if the validation is not verified for the form.
if (name === ""){
alert("El campo nombre está vacío");
return false;
}
return true;
You should take a look at how events are called in javascript when dealing with forms.
You're missing the call to the validar function
<form .... onsubmit="return validar()">
Also validar should return false if the validation fails and true if it passes

Clone div not being removed, just the original one

I have a div being cloned and I would like the button remove to remove the selected div. It's only removing the html div that is used to clone the field.
See my code below:
JS
// Clones Schedule Field
function cloneField(){
const newFieldContainer = document.querySelector(".schedule-item").cloneNode(true)
console.log(newFieldContainer)
let fields = newFieldContainer.querySelectorAll('input')
fields.forEach(function(field){
field.value = ""
})
document.querySelector("#schedule-items").appendChild(newFieldContainer)
}
// Adds new field
function addButton(){
let button = document.querySelector("#add-time")
const selected = document.getElementById('select').selected
let scheduleItems = document.querySelector('#schedule-items')
let inputs = scheduleItems.querySelectorAll('input')
if(selected == true || [...inputs].some(input=>input.value === "")){
alert('Tem o dia ou a hora faltando nos Horários Disponíveis.')
button.removeEventListener('click',cloneField)
}else{
button.addEventListener('click',cloneField)
}
}
// Removed field added if needed
let buttonRemove = document.querySelector('.remove-schedule-item')
buttonRemove.addEventListener('click',removeField)
function removeField(){
let scheduleItem = document.querySelector('.schedule-item')
scheduleItem.parentNode.removeChild(scheduleItem);
console.log('hey')
}
HTML
<fieldset id="schedule-items">
<legend>Horários disponíveis
<button type="button" id="add-time" onclick="addButton()">+Novo horário</button>
</legend>
<div class="schedule-item">
<div class="select-block">
<label for="weekday">Dia da semana</label>
<select name="weekday[]" required="true">
<option id="select" value="select" selected>Selecione uma opção</option>
{%for weekday in weekdays %}
<option value="{{loop.index0}}">{{weekday}}</option>
{%endfor%}
</select>
</div>
<div class="input-block">
<label for="time_from">Das</label>
<input type="time" name="time_from[]" required>
</div>
<div class="input-block">
<label for="time_to">Ate</label>
<input type="time" name="time_to[]" required>
</div>
<div class="remove-schedule-item">
<button>remove</button>
</div>
</div>
</fieldset>
</form>
Thanks in advance
when you try to remove the item
function removeField(){
let scheduleItem = document.querySelector('.schedule-item')
scheduleItem.parentNode.removeChild(scheduleItem);
console.log('hey')
}
you are always selecting the first .schedule-item and then delete the first item
edit:
when you clone you element you need to add event listener to the new element
function cloneField(){
const newFieldContainer = document.querySelector(".schedule-item").cloneNode(true);
let fields = newFieldContainer.querySelectorAll('input')
fields.forEach(function(field){
field.value = ""
});
document.querySelector("#schedule-items").appendChild(newFieldContainer);
const removeBtn = newFieldContainer.querySelector('.remove-schedule-item');
if(removeBtn){
removeBtn.addEventListener('click',function(){
newFieldContainer.remove();
});
}
}

add element add two place in html

document.querySelector('#submit').onclick = () => {
document.querySelectorAll('.merge').forEach((select) => {
const option = document.createElement('option');
option.innerHTML = document.querySelector('#text-get').value;
document.querySelector('.merge').append(option);
})
return false;
};
<select id="task" class="merge">
</select>
<select id="task2" class="merge">
</select>
<form>
<input type="text" id="text-get">
<input type="submit" id="submit">
</form>
I would like to add option in both the drop down but with same input tag
value.
There is something wrong with JavaScript code.it is not adding to any.
You are close. Try this way :
const selects = document.querySelectorAll('.merge'), // Caching elements so the DOM won't be queried constantly
input = document.querySelector('#text-get');
document.querySelector('#submit').onclick = () => {
selects.forEach(select => {
let option = document.createElement('option');
option.innerHTML = input.value;
select.append(option)
});
return false;
};
<select id="task" class="merge">
</select>
<select id="task2" class="merge">
</select>
<form>
<input type="text" id="text-get">
<input type="submit" id="submit">
</form>

Categories