Inputs generated by Javascript are being ignored - javascript

Basically, it's a form that needs specific information, "Tamanho"/"Tamanhos" means "size"/"sizes", which I have a list of acceptable sizes that goes from 8 to 30 that are registered in a database (to make it easier to add more acceptable sizes if needed), the user should be able to chose many "sizes" and put a quantity of "how many products of that size?" in an input right after it.
I was able to create an JavaScript function AddTam() called by a button that generates one more block to fill, with a select, and all the block's select inputs are named Tam[], so their values pass as an array, and their respective inputs named as "TamQnt8", the number 8 at the end refers to the size chosen, it changes every time the user chooses other size for the same block using other function DefTam(), that way, I could verify the sizes array in the Back-End, and use it to get their respective quantities and organize it all in an array, to finally send it to the database.
But for some reason, when I test if the information is passing through correctly, it doesn't send any data in the key "Tam" saying it's undefined when I tested it, in PHP I'm testing: if(!empty($_POST['Tam'])) but i also tried isset().
I just don't know what's wrong, so I was asking if isn't it the method I'm using insertAdjacentHTML() to generate the blocks, and if it works as well as createElement() in forms.
Also, when I created the blocks manually and instead of many selects I used checkboxes, it was working, just decided to change to the generated method because the checkboxes took way too much space in the screen, even worse for mobile.
Here's a simplification of the code in HTML:
<form method="post">
<section>
<div class="littlebutton" id="addTamanho" onclick="AddTam()">Add Tamanho</div>
</section>
<script>
var contador = 0;
function AddTam(){
let tamTitulo = document.querySelector('#addTamanho');
tamTitulo.insertAdjacentHTML("afterend",
'<div class="cellTam cell">'+
'<select name="Tam[]" class="'+contador+'tam8 '+contador+'" onchange="DefTam(this)">'+
'<?php foreach ($_SESSION["tamanhos"] as $key => $value) { ?>'+
'<option value="<?php echo $value["tamanho"];?>"><?php echo $value["tamanho"];?></option>'+
'<?php }?>'+
'</select>'+
'Tem => <input class="qnt" id="'+contador+'tam8" name="TamQnt8" type="number" min=1>'+
'</div>');
contador++
}
function DefTam(ElementTam){
let infoTam = ElementTam.value;
let refTam = ElementTam.getAttribute("class");
refTam = refTam.split(" ");
let relInput = document.getElementById(refTam[0]);
ElementTam.setAttribute("class", refTam[refTam.length-1]+"tam"+infoTam+" "+refTam[refTam.length-1]);
relInput.setAttribute("name", "TamQnt"+infoTam);
relInput.setAttribute("id", refTam[refTam.length-1]+"tam"+infoTam);
}
</script>
<button class="post" name="Inserir" type="submit">Postar</button>
</form>
Output: The Add Tamanho button, 3 generated blocks of the form and the Elements tab of browser's Developer tools
Sorry if I wrote something wrong or weirdly, still learning English, or if it's just a silly mistake in my code, also, any help is welcome.

Related

HTML text input tags generated with javascript do not POST when the form is submitted

I have a form which asks for employment history, where you have applied to college etc. So for example for colleges they applied to I have one text box at first and there is a button below that calls a javascript function to add another text input right below it. When I first made this form I was doing that with a few different pieces of data then once they were submitted I would get them from $_POST and put them in arrays then add each element of the array to the corresponding table in my db. All of a sudden though, I can no longer submit my form and I get a message telling me that I have tried to get an unspecified index. However when i inspect the text inputs in my browser they are correctly named. I read that I should name them college[] so that they all go into an array, but that also did not work.... now what?
js:
var numcol = 1;
function addnewschool(){
numcol++;
var container = document.getElementById("collegecontainer");
container.appendChild(document.createTextNode(numcol));
var input = document.createElement("input");
input.type = "text";
input.name = 'applied'+numcol;
container.appendChild(input);
container.appendChild(document.createElement("br"));}
html:
<p class="text-dark mb-4">List the Colleges you have applied to:<br>
<div id="collegecontainer" name="collegecontainer">
<input type="text" name='applied1'><br>
</div>
<input type="button" id="addcollege" name="addcollege" value="Add College"
onClick="addnewschool()"><br>
</p>
php:
$applied = array();
foreach($_POST['applied'] as $value){
array_push($applied, $value);
}
Update: Ok so I changed it to another way and that didn't work so i decided to just copy an earlier version of it which was working and paste it into the correct layout. And that worked... SO now that it was fixed i continued adding to it. I added "required" to a few tags, changed some styling a bit, and changed my javascript file a bit. But now I'm having the same issues as before. All of my POST arrays only have the first value in them. What could I have added that changed this? Has anyone ever had any issues like this?
Your first additional input should have index "applied1", not "applied2"
look at:
var numcol = 1; // put this to 0
function addnewschool(){
numcol++; // or move this to the end of the function
You don't need to add a different name for each input. Just use applied[] in all input names.
To get the array in PHP, just use $_POST['applied'].
If you want to use each of them later, you could use a foreach, like
foreach ($_POST['applied'] as $value) {
// Do what you want. Retrieve the value using $value
}
Or any other method you prefer.
Name your text input field(s) applied[] and when you process the form the post value of $_POST['applied'] will be an array already filled for you with however many entries were completed.
To get the data into your table:
foreach ($_POST['applied'] as $id => $applied) {
$sql = "INSERT INTO Colleges(id, college) VALUES('$id','$applied')";
if($conn2->query($sql) === TRUE){
echo "New Record created successfully";
} else {
echo "Error: " . $sql . "<br>" . $conn2->error;
}
} // end of foreach

use data return from php / database to create new form

I did some research already but can't find a good solution to this. I am sure it's simple, but I could use some help.
I am using HTML -> Javascript -> PHP to get info back from a database.
My goal is to have the data return, but have it add check boxes at the end of each row where if the person check it, it will add them to another table.
In my example, it will return a list of cards and if the person uses the check box it will add each card they checked to a "have" list. For my code provided below, it's a "display all" so I didn't use any javascript. I put it straight from html to php. I figure if I can get the most simple example working, adding the js to my other search display will be easy.
HTML
<fieldset>
<form action="display_all.php" method="post">
Order by: <select name="order_all" id="order_all">
<option value="parallel">Parallel</option>
<option value="faction">Faction</option>
</select>
<input type="submit" value="display all cards">
</form>
</fieldset>
PHP (to save space I cut out some of the standard code)
$order_all = $_POST['order_all'];
// Create SQL statement
$query = "SELECT * FROM cards ORDER BY $order_all ASC";
// Execute SQL statement
if (!($result = # mysql_query ($query, $connection)))
showerror();
// Display results
while ($row = # mysql_fetch_array($result)) {
echo "<tr><td>{$row["parallel"]}</td>
<td>{$row["faction"]}</td>
<td>{$row["in_set"]}</td>
<td>{$row["card_name"]}</td>
<td>{$row["color"]}</td>
<td>{$row["number_in_set"]}</td>
<td>{$row["rarity"]}</td>
<td>{$row["sold_out"]}</td>
<td>{$row["series"]}</td>
</tr>";
}
I tried adding different things to the while { } at the end of the PHP file but I don't really know the proper way to do that. Based on what I saw around, people suggest doing this in javascript and creating a function for it. Start with my ajax call and callback? I planned on linking my checkboxes to the ID of each card (which is stored in the database, but not printed) I figure they will just be linked to query insert commands. Like if check [ insert command ] and form submit? idk looking for some suggestions, I am still new to using databases in this sort of way.
FOUND A SOLUTION TO MY PROBLEM, well sorta.
It was a bunch of little things. I haven't added functionality, but I at least got the checkbox to show up.
while ($row = # mysql_fetch_array($result)) {
echo"
<tr>
<td>{$row["parallel"]}</td>
<td>{$row["faction"]}</td>
<td>{$row["in_set"]}</td>
<td>{$row["card_name"]}</td>
<td>{$row["color"]}</td>
<td>{$row["number_in_set"]}</td>
<td>{$row["rarity"]}</td>
<td>{$row["sold_out"]}</td>
<td>{$row["series"]}</td>
";
echo'<td><input type="checkbox" value="submit" id="{$row["id"]}/></td>';
echo"</tr>";
}
Your code is paradise for SQL injection! You have to check user input, at least escaping with mysql_real_escape_string or
Switch to newer, better and safer mysqli (or PDO) interface and use prepared statements. I recommend mysqli anyway.
Note: in this particular case is best to use switch with options.
To question: why don't you get checkbox value from post and then take actions, but I'm not sure what are you asking.

Select specific row in <select> list after return from SQL query

I have this rather tricky problem to solve whereby I have used the following to display a list of named shops with ID number for selection from a drop down list when creating a new employee record. This works well at this point. A piece of javascript splits the displayed text from the the user selection and sends the shop ID number off with the new employee details to be inserted into the employee table in the database. I am using a hidden shopID text box to store the number as can be seen in the javascript.
Here is the code PHP first then javascript:
$result = mysqli_query($link,"SELECT shopID, shopName FROM SHOP");
echo "<br><select class='formInput' name='listbox' id='listbox' onchange='captureShopID()' tabindex=9>";
#Use onchange instead of onclick where Keyboard is used. onclick does not register changes fro keyboard
while($row = mysqli_fetch_array($result))
{
$shopID = $row['shopID'];
$shopName = $row['shopName'];
$allText = "$shopID, $shopName";
echo "<option value='$allText'>S00$shopID $shopName</option>";
}
echo "</select>";
AND (including this, because it may contain hints to a solution for my problem)
<script>
function captureShopID()
{
var sel = document.getElementById("listbox");
var result;
result = sel.options[sel.selectedIndex].value;
var shopNumber = result.split(',');
document.getElementById("shopID").value = shopNumber[0];
}
</script>
OK. So all good so far. What I am trying to do is use the same set up for amendments to the same record. So the update layout is similar to the one for creating the record. I have the list element again but what I would like is to have it showing the shop that the employee works at otherwise it is confusing as the list defaults to the first item in the list, in most cases not the actual shop that the employee works in.
So, instead of:
S001 London
Maybe it should be:
S003 Paris… Where the employee works.
I have tried various things but it is a tricky one. The fact that there is the option value concatenation of $shopID and $shopName may be complicating things a bit in my quest for a solution.
Pretty new to PHP and javascript (javascript pretty mysterious) and programming as a whole. Learning quickly but suffer many days of brain cell overload.
Any pointers in the right direction appreciated.
My Solution… After some outside the box tangental thinking working on some other aspects of my project.
<?php
include "../db.php";
$result = mysqli_query($link,"SELECT shopID, shopName FROM SHOP");
echo "<br><select class='formInput' name='listbox' id='listbox' onchange='captureShopID()' tabindex=9>";
#Use onchange instead of onclick where Keyboard is used. onclick does not register changes from keyboard
echo '<option>Works at:'.$shopName.'</option>';
while($row = mysqli_fetch_array($result))
{
$shopID = $row['shopID'];
$shopName = $row['shopName'];
$allText = "$shopID, $shopName";
echo "<option value='$allText'>S00$shopID $shopName</option>";
}
echo "</select>";
?>
I achieved what I wanted by adding the extra to the top of the list outside the loop to act as the default item listed:
echo 'Works at:'.$shopName.'';
This has the result of presenting the update employee record so that shop from their record is what you see in the menu like so:
Works at: London Southwark
And the list pops up to show the other shop options
Works at: London Southwark
S001 DISTRIBUTION CENTRAL Paris
S002 Paris Montmartre
S003 London Southwark
S004 Roma Trastevere
and so on.
Not exactly what I initially intended but just as good
I am aiming for a clean and spasre interface without too many labels and this solution makes the list element self explanatory.
If any one has a good suggestion for the thread title please post as this one is quite useful.

JavaScript variable passed to PHP

I'm working on a form that adds up the totals selected (via checkboxes). In my JavaScript file, build.js, the totals are added together. On my PHP page, the code takes the items selected on the previous form/HTML page and passes them to what is shown on the PHP page. I want to be able to take the total that was added up via JavaScript on the form page and bring it over to be listed as a total underneath all the options that were selected.
My knowledge of PHP and JavaScript are very rudimentary. This is the first real form I have created in either of these languages. I have poured over this site and the internet in general and have not been able to get any of the options I've found to work. I think I just lucked out on getting the form this far, so I apologize if my code isn't very clean!
Any help would be amazing, as specific as possible please. Here is my code:
The JavaScript that adds the total:
$(document).ready(function() {
$("input[type=checkbox]:checked").attr("checked", false);
function recalculate() {
var sum = 0;
$("input[type=checkbox]:checked").each(function() {
sum += parseInt($(this).attr("rel"));
});
$("#output").html(sum);
}
$("input[type=checkbox]").change(function() {
recalculate();
});
});
Code written on the form itself that shows the total:
<span id="output" class="total"></span><BR><BR>
Code written on the PHP page:
<b>Estimate:</b>
<?php
$aTruck = $_POST['formSelected'];
if(empty($aTruck))
{
echo("You didn't select a truck.<BR><BR>");
}
else
{
$N = count($aTruck);
echo("<h3>Truck Type: ");
for($i=0; $i < $N; $i++)
{
echo($aTruck[$i] . " ");
}}
$aAddons = $_POST['formAddons'];
if(empty($aAddons))
{
echo("You didn't select any options.");
}
else
foreach ($aAddons as $v)
{
echo "<h3> $v </h3>";
}
?>
If I'm not mistaken, the reason I can't currently pass the total is because of something I read on here: the PHP is run on the server while the JavaScript runs on the user's end. My options are thus to send the total in the form (possibly as a hidden variable, which I can't figure out either), pass it along in Ajax (I don't know if the server I'm on is capable of this- possibly so and it's all use error!), or use an XMLHttpRequest. I've tried anything I could find on any of those and either do not have the right variable listed inside, am placing it in the wrong spot, or it's just plain wrong.
As I mentioned, I've poured over the forums for everything I can that's related to this and nothing I've found is specific enough for the tiny bit of understanding I have. Among other things I've tried: Pass a javascript variable value into input type hidden value and Pass Javascript Variable to PHP POST along with using an XMLHttpRequest, using Ajax, passing it as a hidden variable (which I'm leaning towards but don't think I'm implementing correctly) and a ton more- it's pretty much all I did all day at work yesterday so I'm not trying to be redundant with my question- I just can't figure out where I'm going wrong.
It looks like you hit upon it right here:
send the total in the form (possibly as a hidden variable)
Since you're talking about one page posting to another page, and that other page showing the results, then there's no need for AJAX here. You can just use a form value like any other. The "hidden variable" in this case is actually an input element:
<input type="hidden" name="sum" />
In your JavaScript where you're displaying the sum on the first page:
$("#output").html(sum);
You can also set that sum to the form element's value:
$("#output").html(sum);
$("input[name=sum]").val(sum);
As long as that input is inside the same form as the other input elements (like formSelected and formAddons) then when the first page posts to the second page, the code in the second page can access the sum value the same way:
$_POST["sum"]
In your form you should add a hidden input like this :
<input type="hidden" name="sum" value="">
Then in your recalculate() (javasript) function, you should change the value of this input once you calculated everything :
function recalculate() {
var sum = 0;
$("input[type=checkbox]:checked").each(function() {
sum += parseInt($(this).attr("rel"));
});
$("#output").html(sum);
// Change the hidden input value
$("input[name='sum']").val(sum);
}
Now, when your form is submitted, you should access the sum value, server side (PHP), with a simple :
$sum = $_POST['sum'];

Saving information on HTML page without using variables

So I'm trying to create a webpage where the user puts in there course information. There is an add button on the page, that adds another text field for them if they need more fields.
Once the Add button is pressed, the page is reset and all of the information that has been previously entered is gone. I could save the information in an array, and when or if the the add button is pressed save the information into an array, and re populate the fields using what was stored in the array.
My question is: Is there a way to refresh a page, and keep the information in the text fields, without taking the long process mention above, is there some attribute that I can use that will not delete information that has been previously entered into ?
If you code HTML5, you can use localStorage with a fallback to cookies. Also, if the information should be removed after session end, then you may use sessionStorage instead.
You can use ajax i think...it runs in background no page reload is done.
Assuming this HTML:
<form id="course-info-form" action="submit-course-info.php" method="post">
Professor name: <input type="text" name="professor"><br>
Additional info:<br>
<input type="text" name="additional0"><br>
<input type="submit" value="Submit">
</form>
<br>
<button id="add-button">Add Field</button>
<!-- Use jQuery for DOM manipulation -->
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
With JavaScript / jQuery:
var courseInfoForm = $('#course-info-form');
var addButton = $('#add-button');
// Keep track of how many fields there are, so each can have a unique "name" attribute
var additionalFieldsAdded = 1;
// Whenever "Add Field" is clicked, create another input field
addButton.on('click', function() {
var newInput = $("<input>", {
type: "text"
name: "additional" + additionalFieldsAdded
});
courseInfoForm.append(newInput, "<br>");
additionalFieldsAdded += 1;
});
I'm not very good at PHP. In your PHP script, make a while loop that checks to see if isset($_POST['additional0']), and additional1, additional2, etc, until you are sure that there were no more additional fields passed. Then store all those additional details into an array, and handle it how you see fit.
As for your original question, I recommend using my solution instead. It's better to avoid unnecessarily reloading the page, if all you're doing is simply adding a new form each time.
I suppose you could capture the information that was "tentatively-submitted" when the "Add Field" button is clicked, and then in your PHP script loop through all the additional fields and create 1 more input element each time another field is added, and set the value attribute of each "old" input element to whatever was "tentatively-submitted."
So, to answer your question, you can set the default value of an input field (server-side) with:
// add-course-information.php
<?php
$addingField = false;
// Check for the optional "?do=addfield" parameter
if (isset($_POST['do']) && $_POST['do'] == 'addfield') {
$addingField = true;
$fields = array();
$nextField = 'additional' . count($fields);
// Get each piece of POSTed field data
while (isset($_POST[$nextField]) && $_POST[$nextField] != '') {
array_push($fields, $_POST[$nextField]);
$nextField = 'additional' . count($fields);
}
}
?>
<!-- Silly HTML! -->
<?php
// If adding a field, recreate and repopulate all previous fields
if ($addingField) {
for ($i = 0; i < count($fields); i++) { ?>
<input type="text" name="additional<?= $i ?>" value="<?= $fields[$i] ?>">
<?php } ?>
<input type="text" name="additional<?php echo count($fields) + 1 ?>">
<?php }
// Otherwise, show the default additional field
else { ?>
<input type="text" name="additional0">
<?php } ?>
<!-- More awesome HTML! -->
That might work... (Currently untested.)
What that page is supposed to do (if it works) is:
On default, give the user his initial setup, with just 1 additional input field, "additional0".
When the user clicks "Add Field," ?do=addfield should be POSTed to add-course-information.php (you can write that part), and when this page receives the do=addfield parameter, then it knows to loop through all the submitted additional fields, and store them each into an array, and then afterwards output all the submitted data back into another loop's-worth of dynamically generated <input> elements.
But I think that that would be much more complicated, and unnecessarily increase the processing your server has to do. It could even be abused if someone was to hammer the "Add Field" button hundreds of thousands of times a minute, eventually making your for-loops iterate millions of times... (Unless you imposed a limit on the maximum number of fields, which would be easy.)
However, you might as well leverage the client's processing power if it's available.

Categories