Dynamically added input fields aren't being submitted in request.form - javascript

I have a form in my input.html page and I have a set of input fields that is both programmatically generated by jinja2 and dynamically generated with Javascript. The inputs that are generated by jinja2 all show up in my request.form when I hit submit (i.e. into my POST function), but the dynamically created fields (with the + button next to a given element) aren't showing up. Which is strange, because if I inspect the page after adding a few new inputs, they... should?
Any ideas?
HTML
(explanation: this iterates through a ~dict and x has two text fields called question and tech-key (ex// "int"). This should print out the question with a 'plus sign' to allow the user to add new input fields dynamically. I include one by default (ex// name="{{x['tech_key']}}1" means name="int1". Every new input field that gets added increments (int1, int2, int3, etc...)
<div class="col-md-9">
{% for k,v in inps['sheet'].items() %}
{% for x in v %}
<div class="{{x['tech_key']}}">
<b>{{x['question']}}</b>
<button class="add_form_field" data-key="{{x['tech_key']}}"><b>+</b></button><br>
<div><input type="text" name="{{x['tech_key']}}1" size="80px"></div>
</div>
{% endfor %}
{% endfor %}
</div><br>
JavaScript
(explanation: This allows me for each individual named div (ex: the <div class="int"> above), to add new input fields when I click the + sign next to my product. I have them connected to the original form. They aren't pushing when I hit submit.
// adds new input fields when the + is clicked on a given question
$(document).ready(function() {
var max_fields = 10;
var add_button = $(".add_form_field");
var x = 1;
$(add_button).click(function(e){
use = $(this).attr("data-key")
var wrapper = "."+use
e.preventDefault();
if(x < max_fields){
x++;
var field_name = use + x
$(wrapper).append('<div><br><input type="text" form="input_form" name="'+field_name+'"/ size=80px><a class="'+field_name+'"><button><b>-</b></button></a></div>'); //add input box
}
$("."+field_name).click(function(){
$(this).closest('div').remove(); x--;
})
});
});
HTML copied directly from my page when I add two new input fields:
<div class="int">
<b>Did you conduct any interviews this quarter?</b>
<button class="add_form_field" data-key="int" data-ol-has-click-handler=""><b>+</b></button>
<div>
<br><input type="text" name="int1" size="80px">
</div>
<div>
<br><input type="text" form="input_form" name="int2" size="80px">
<a class="int2"><button><b>-</b></button></a>
</div>
<div>
<br><input type="text" form="input_form" name="int3" size="80px">
<a class="int3"><button><b>-</b></button></a>
</div>
</div>

Related

How to Remove Input text after submit HTML JavaScript

I have a dialog that contains inputs,
User should complete dialog inputs then click send,
After that, user can open the same dialog again and complete dialog inputs.
But when the user open the dialog again, input values remain as same from previous inputs,
How can I remove previous input values?
My Dialog:
<dialog id="main-customers">
<h2>العملاء الرئيسيون</h2>
<div>
<label for="main-customers-name">الاسم</label>
<input type="text" id="main-customers-name" placeholder="الاسم" required>
<label for="main-customers-country">الدولة</label>
<input type="text" id="main-customers-country" placeholder="الدولة" required>
<label for="main-customers-goods">سلع / بضائع</label>
<input type="text" id="main-customers-goods" placeholder="سلع / بضائع" required>
</div>
<div class="center">
<button id="main-customers-send">إرسال</button>
<button id="main-customers-cancel" onclick="closeDialog('main-customers')">إلغاء</button>
</div>
</dialog>
My JS:
document.getElementById("main-customers-send").addEventListener("click", function(){
// to remove initial value
var no_data= document.getElementById("main-customers-table-no-data");
if(no_data){
no_data.remove()
}
// END to remove initial value
var name= document.getElementById("main-customers-name");
var country= document.getElementById("main-customers-country");
var goods= document.getElementById("main-customers-goods");
document.getElementById("main-customers-table").innerHTML+=
`<tr>
<td>${name.value}</td>
<td>${country.value}</td>
<td>${goods.value}</td>
</tr>`;
let itms = document.querySelectorAll("#main-customers");
for (let itm of itms) {
if(itm.value != ""){
itm.value= ""; //it does not do the job
}
}
closeDialog("main-customers")
})
-
values remain the same as shown below:
The line let itms = document.querySelectorAll("#main-customers"); doesn't do what you think it does. It selects all the elements with the id "main-customers" (which per spec a page could only have one of).
Try let itms = document.querySelectorAll("#main-customers input[type=text]"); instead of that which will select all the children of the #main-customers element that is an input whose type is text.

Shopify validation for custom attribute fields in cart page

We have a Shopify website (Dawn theme) and we added some custom attribute fields on cart page which is associated with the product added to cart.
For showing the attribute fields, below is the code I'm using in the cart page file:
{% for variable in (1..item.quantity) %}
<div class="user_web_info">
<div class="cart-attribute__field">
<label for="website-name{{variable}}">Website Name*</label>
{% capture attributename %}Website Name{{variable}}{% endcapture %}
<input type="text" aria-required="true" required="required" class="required" data-name="Website Name{{variable}}" id="website-name{{variable}}" name="attributes[Website Name{{variable}}]" value="{{ cart.attributes[attributename] }}">
</div>
<div class="cart-attribute__field">
<label for="website-url{{variable}}">Website URL*</label>
{% capture attributeurl %}Website URL{{variable}}{% endcapture %}
<input type="text" aria-required="true" required="required" class="required" data-name="Website URL{{variable}}" id="website-url{{variable}}" name="attributes[Website URL{{variable}}]" value="{{ cart.attributes[attributeurl] }}">
</div>
</div>
{% endfor %}
I got the code for fields from this article:
https://community.shopify.com/c/online-store-2-0/dawn-theme-add-custom-fields-in-cart-page-and-show-results-in/td-p/1410437
I'm facing an issue with the validation of these fields when clicking checkout button on the cart page. Default HTML validation is showing in the field when clicking checkout without filling the fields, but the user is immediately redirecting to checkout page after that.
I tried to use simple jquery / javascript code as mentioned in these articles for preventing the form submission when validation happens. But it is not working:
https://community.shopify.com/c/technical-q-a/how-to-prevent-login-form-submit/td-p/1787161
https://community.shopify.com/c/shopify-apis-and-sdks/help-needed-validation-function-for-add-to-cart-form-submission/td-p/261161
I implemented the validation code in a separate js file and included it in theme.liquid file.
I searched a lot for finding a solution, but couldn't find it yet. I even used an App here: https://apps.shopify.com/customized-attribute
I need the validation for the checkbox also.
I figured out the issue here
I changed the checkout button from type="submit" to type="button" and changed the name attribute of checkout button to "checkout1". I'm not sure how these things affecting the form submission, but i had to do these.
Then I commented out these default form submission code in the cart page footer file:
document.querySelector('#checkout').addEventListener('click', function(event) {
document.querySelector('#cart').submit();
});
Also implemented the below validation code in custom js file:
document.querySelector('#checkout').addEventListener('click', function(event) {
event.preventDefault();
let errors = 0;
document.querySelectorAll('input.required').forEach((input) => {
let val = input.value;
console.info(val.length);
if(val.length == 0){
errors = errors + 1;
}
});
if(errors > 0){
alert("Please fill all the required fields.");
return false;
}
else if(!document.querySelector('#disclmr-chk').checked) {
alert("Please check the checkbox.");
return false;
}else{
document.querySelector('#checkout').setAttribute('name', 'checkout');
document.querySelector('form#cart').submit(); }});

Adding Plus minus button in form with POST and scrf_tocken

With Django I generate a list of items, with the number of them.
To be more convenient, I would like to add a plus and a minus button.
I found a simple solution, but when I try to put this in my form with the POST method, if click the page refresh or POST ?
I don't want to refresh the page every time, I have a validate button and all the value will be treat in one time.
<form class"form-inline" action="{% url 'stock:stock' %}"method="post" >{% csrf_token %}
{% for stock in stocks %}
<div>
<button id="minusButton">-</button>
<input type="number" name="stock" id="stock" value="{{stock.stock}}" >
<button id="plusButton">+</button>
</div>
{% endfor %}
</form>
<script>
textInput = document.querySelector('#numberInput');
plusButton = document.querySelector('#plusButton');
minusButton = document.querySelector('#minusButton');
plusButton.onclick = () => textInput.value = parseInt(textInput.value) + 1;
minusButton.onclick = () => textInput.value = parseInt(textInput.value) - 1;
</script>
If anyone know how to manage?

Add additional fields to form after click - the node before which the new node is to be inserted is not a child of this node

I have a form in which I need to add a button that will allow the user to add a new field.
I'm trying to do it with JavaScript, but since I don't know much this language I'm lost with some concepts.
The form I use is one where the data is completed in steps, and the fields I want to add are the following
<div class="job-form row mb-3">
{% for form in add_trabajo %}
<div class="col-md-6">
<label for="ref" class="">Nombre</label>
{% render_field form.trabajo class="form-control" type="text" placeholder="Ej: Reparación de envolvente delantero" %}
</div>
<div class="col-md-2">
<label for="ref" class="">Descuento</label>
{% render_field form.descuento class="form-control" type="text" %}
</div>
<div class=" col-md-2">
<label for="ref" class="">Precio</label>
{% render_field form.precio class="form-control" type="text" %}
</div>
<div class="col-md-2 d-flex align-items-end">
<button id="addButton" type="button" class="btn-icon btn-icon-only btn btn-success p-2"><i class="pe-7s-plus btn-icon-wrapper"> </i></button>
</div>
{% endfor %}
</div>
I'm trying to add these fields after existing ones that are identical
I already have the button and some code in javascript but it indicates the following error
Uncaught DOMException: Failed to execute 'insertBefore' on 'Node': The node before
which the new node is to be inserted is not a child of this node.
at HTMLButtonElement.addForm
This is my JavaScript code
let jobForm = document.querySelectorAll(".job-form")
let container = document.querySelector("#presupuestoForm")
let addButton = document.querySelector("#addButton")
let totalForms = document.querySelector("#id_trabajosarealizar_set-TOTAL_FORMS")
let formNum = jobForm.length-1 // Get the number of the last form on the page with zero-based indexing
addButton.addEventListener('click', addForm)
function addForm(e) {
e.preventDefault()
let newForm = jobForm[0].cloneNode(true) //Clone the bird form
let formRegex = RegExp(`trabajosarealizar_set-(\\d){1}-`,'g') //Regex to find all instances of the form number
formNum++ //Increment the form number
newForm.innerHTML = newForm.innerHTML.replace(formRegex, `trabajosarealizar_set-${formNum}-`) //Update the new form to have the correct form number
container.insertBefore(newForm, addButton) //Insert the new form at the end of the list of forms
totalForms.setAttribute('value', `${formNum+1}`) //Increment the number of total forms in the management form
}
and this would be the structure of my form
that's where I try to add the new fields, between the job-form class and the divider with id div-form
This error means "addButton is not a child of container".
The nodes to provide are parentNode.insertBefore(newNode, referenceNode).
parentNode has to be the direct parent of the referenceNode.
So try:
jobForm.parentNode.insertBefore(newForm, addButton)
But that may not be correct either... since #addButton is a child of .job-form... I think that will have two add buttons.
But now that you know what .insertBefore() needs... You can fix it.

Dynamic text field can't take the value jquery php

I'm trying to add/remove items dynamically but I can't take the values of all the elements of the array.
Basically I have this form
<form action="" method="post">
<div class="input_fields_wrap">
<div>
<label> <span>Team name </span>
<input type="text" class="input-field" name="teams[]"> </label>
</div>
</div>
<span id="num_teams"></span> <label><span> </span>
<input type="submit" value="Add Team" class="add_field_button" name="add_field_button">
<input type="submit" name="next" value="Next" />
</label>
</form>
It just shows an input box where I'd have to insert the team name and two buttons ; one to go to the next page, and the other one to add a new text field using jquery.
Here it is the jquery script
<script type="text/javascript">
$(document).ready(function() {
var wrapper = $(".input_fields_wrap"); //Fields wrapper
var add_button = $(".add_field_button"); //Add button ID
var x = 1; //initlal text box count
$(add_button).click(function(e){ //on add input button click
e.preventDefault();
var max_fields = $('#n_teams').val(); //maximum input boxes allowed
if(x < max_fields){ //max input box allowed
x++; //text box increment
$(wrapper).append('<div><label><span>Team Name </span><input type="text" class="input-field" name="teams[]"> Delete</label></div>'); // add input box
$("#num_teams").html('Number of Teams: '+x);
}
});
$(wrapper).on("click",".remove_field", function(e){ //user click on remove text
e.preventDefault(); $(this).parent('label').remove(); x--;
$("#num_teams").html('Number of Teams: '+x);
})
});
</script>
The script above works perfectly: it adds and removes textfields.
The problem that I have now is that I can't take the values of the array 'teams[]' .
in a
if(isset($_POST['next']))
even if I try to take the values manually like
echo $_POST["teams"][0]; and
echo $_POST["teams"][1]; ect...
It just takes the first value (i.e. the one I don't add using jquery). It doesn't 'see' the jquery text fields added.
Of course my final aim is to insert 'teams[]' in a mysql table, but for now I noticed that I can't either take the values.
Where am I wrong ?
EDIT - SOLVED
It was a very stupid error I made in the html code. Actually there was a <div> before of the <form> that caused all the troubles. After a very accurate analysis , trying every single piece of code alone, I finally got that I just had to move the <form> above two <div> to make the code work.
I do apologize to everyone, silly me!
Instead of using name="teams[]" use name="teams" and on server side use:
$_POST['teams']
which should give you the comma separated list.
var wrapper = $(".input_fields_wrap").first();

Categories