Problems with simple Javascript form validation - javascript

I'm working on putting together a multi-page set of forms that are interlinked by a session and use Javascript for form validation whenever each section is submitted. My first form is working fantastically. My second one, not so much. It's a dynamically created form that depends on the previous form for the number of drop down boxes (between 1 and 20) that are populated from a database. I will spare you all the query code to create the array that fills in my dropdowns and get straight to the form validation script and then the form itself.
The validation script from the head without the <script> tags:
function validateForm()
{
var count = <?php echo $_SESSION['credits']; ?>;
var i = 1;
for (i = 1; i <= count; i++)
{
var j = i;
for (j++; j <= count; j++)
{
var a = document.forms["addcredits"]["creditdropdown_"+i].value;
var b = document.forms["addcredits"]["creditdropdown_"+j].value;
if ((a == b) && (a != 0))
{
alert('Cannot select the same writer more than once.');
return false;
}
}
}
var foundOne = false;
var h = 1;
while (h <= count && !foundOne)
{
if (document.forms["addcredits"]["creditdropdown_"+h].value != 0)
{
foundOne = true;
}
h++;
}
if (!foundOne)
{
alert('You must select at least one writer to credit.');
return false;
}
}
The form code:
<form id="addcredits" class="appintro" method="post" action="recordcheck.php" onsubmit="return validateForm()">
<div class="form_description">
<h2>Song Title Submission</h2>
<p>Step 2: Select writing credits for song title</p>
</div>
<ul>
<?php
for ($i = 1; $i <= $_SESSION['credits']; $i++)
{ ?>
<li id="li_<?php echo $i; ?>">
<label class="description" for="creditdropdown_<?php echo $i; ?>">Song Credit #<?php echo $i; ?>:</label>
<select "creditdropdown_<?php echo $i; ?>">
<option value="0">Select a writer</option>
<?php foreach ($writers as $key => $writer) { ?>
<option value="<?php echo $key; ?>"><?php echo $writer; ?></option>
<?php } ?>
</select>
<p class="guidelines" id="guidelines_<?php echo $i; ?>">Writer not found in database? Add them here.</p>
</li>
<?php } ?>
<li id="buttons">
<input type="hidden" name="form_id" value="2">
<input type="hidden" name="submit" value="1">
<input id="nextButton" class="button_text" type="submit" name="submit" value="Next">
</li>
</ul>
</form>
Neither of the alert windows pop-up when I click Next and if I stick random debugg-ing alert windows into the validation script, the only ones I was able to get to show up were the ones I stuck at the beginning of the code. The furthest I got them to work was the first assignment of a after that, not even the debuggers would show. I'm assuming I'm doing something incorrectly in the assignment or there is something wrong with the values in the dropdown? Either way, I'm stumped.

I'd say the problem is in your HTML:
<select "creditdropdown_<?php echo $i; ?>">
You are specifying, presumably, the name attribute but you forgot the name= part. Try this:
<select name="creditdropdown_<?php echo $i; ?>">
In your validation function when you get to this line:
var a = document.forms["addcredits"]["creditdropdown_"+i].value;
You'll find you have an error because document.forms["addcredits"]["creditdropdown_"+i] is undefined because of the missing name= in the html and undefined can't have a .value property.
(By the way, debugging with alert() is useful very occasionally, but you're much better off using the built in developer tools in Chrome - just hit (I think) ctrl-shift-J to get the JS console - or download FireBug for Firefox. Or use IE's developer toolbar. Use console.log() instead of alert(), and/or step through the code until you find the problem.)

Related

How to update first td value onclickthe way it does when dragging

I have rewritten my question to better elaborate as to what I am trying to accomplish and what I have tried thus far.
I have a table on my website which dynamically loads the table rows from a database. I have successfully integrated the jQuery UI "Sortable" and "Draggable" functionality to this page. the outcome is the numeric value changes as you are dragging the rows above or below their neighboring rows and as a result always update the first column of numbers within the table.
Here is the table
<form action="" method="post" id="sort_picks">
<div class="sort-picks-container">
<table class="table-preference-order" id="sortable">
<tbody class="ui-sortable">
<?php
$counter = 1;
foreach ( $result as $query ){
$pickcheck = "SELECT * FROM picks";
$pickcutoffcheck = $wpdb->get_results( $wpdb->prepare ($pickcheck, OBJECT_K ));
foreach ($pickcutoffcheck as $pickcutoffresult) { ?>
<div style="display:none;"><?php echo $pickcutoffresult->pickCutoff; ?></div>
<?php } ?>
<?php $maxlimit = $wpdb->get_row("SELECT count(*) as CNT1 FROM picks where User='$userid'" ); ?>
<tr class="ui-state-default preference-row">
<td class="index preference-pick-order">
<input type="text" class="pick-order" id="sort" name="sort[]" pattern="[1-<?php echo $maxlimit->CNT1; ?>]{1,2}" value="<?php echo $counter; ?>" style="border:0px;max-width:60px;font-size:20px;" readonly>
</td>
<td class="preference-pick-order">
<input type="text" name="rem[]" class="borderless" style="text-align:left;width:25px;display:none;" value="<?php echo $query->REM; ?>" readonly><?php echo $query->REM; ?>
</td>
<td class="preference-emp-info">
<input type="text" name="empname[]" class="borderless" style="display:none;" value="<?php echo $query->EmpName; ?>" readonly><b><?php echo $query->EmpName; ?></b>
</td>
<td class="preference-start-class">
<input type="text" name="starttime[]" class="borderless" style="text-align:left;max-width:75px;display:none;" value="<?php echo $query->StartTime; ?>" readonly><?php echo $query->StartTime; ?>
</td>
<td class="preference-details">
<input type="text" name="job_details[]" class="borderless" value="<?php echo $query->Job_Details; ?>" readonly style="display:none;"><?php echo $query->Job_Details; ?>
<br>
<input type="text" name="startdate[]" class="borderless" style="font-weight:bold;width:100%;text-align:left;display:none;" value="<?php if($query->StartDate!=""){echo date('l\, F jS Y', strtotime($query->StartDate)); }?>" readonly><?php if($query->StartDate!=""){echo date('l\, F jS Y', strtotime($query->StartDate)); }?>
</td>
</tr>
<?php $counter++; ?>
<?php }?>
</tbody>
</table>
</div>
<br>
<div class="sorters-holder">
<button onclick="upNdown('up');return false;" class="sorters">&wedge; </button><br>
<button onclick="upNdown('down');return false;" class="sorters">&vee;</button>
</div>
<div style="display:block;margin:auto;text-align:center;">
<input type="submit" name="submit[]" value="Next" class="job-select-submit" id="validate"> <input type="button" onclick="window.history.go(-1); return false;" value="Back" class="job-select-submit">
</div>
</form>
This is the working jQuery script
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.10.3/jquery-ui.js"></script>
<script src="../wp-content/themes/Excellence_At_Work/jquery.ui.touch-punch.min.js"></script>
<script>
var $j = jQuery.noConflict();
var sort;
$j(function() {
$j("#sortable tbody").sortable({
change: function(event, ui) {
sort = 0;
$j('#sortable tr.ui-state-default:not(".ui-sortable-helper")').each(function() {
sort++;
if ($j(this).hasClass('ui-sortable-placeholder'))
ui.helper.find('td input[name^=sort]').attr('name', 'sort[]').attr('value', sort).val(sort);
else
$j(this).find('td input[name^=sort]').attr('name', 'sort[]').attr('value', sort).val(sort);
});
}
});
$j("#sortable tbody").disableSelection();
});
</script>
<script>jQuery('#sortable').draggable();</script>
As you can see in the html code, I have successfully integrated the buttons that I need to relocate the rows however when doing so I need the value of the first td to also update accordingly as does the drab and drop method. What would I add to the below javascript to get the value of the input with the name sort[] to change to its corresponding numeric place within the table rows newly changed order onclick?
<script>
var order; // variable to set the selected row index
function getSelectedRow()
{
var table = document.getElementById("sortable");
for(var i = 0; i < table.rows.length; i++)
{
table.rows[i].onclick = function()
{
if(typeof order !== "undefined"){
table.rows[order].classList.toggle("selected");
}
order = this.rowIndex;
this.classList.toggle("selected");
};
}
}
getSelectedRow();
function upNdown(direction)
{
var rows = document.getElementById("sortable").rows,
parent = rows[order].parentNode;
if(direction === "up")
{
if(order > 0){
parent.insertBefore(rows[order],rows[order - 1]);
// when the row go up the index will be equal to index - 1
order--;
}
}
if(direction === "down")
{
if(order < rows.length){
parent.insertBefore(rows[order + 1],rows[order]);
// when the row go down the index will be equal to index + 1
order++;
}
}
}
</script>
I hope this better explains whatt I am trying to accomplish. I have hit a road block and could really use some insight, thanks in advance for all those who can provide insight.
UPDATE
I have been able to successfully update the rows first td values onclick by adding the following script after order-- and order++ however this solution is causing the input fields to drop out of the td. Any insight on how to modify this script to include the input field?
Array.prototype.forEach.call(document.querySelectorAll('td:first-child'), function (elem, idx) {
elem.innerHTML = idx + 1;
FINAL UPDATE
I have succeeded in my mission and with a minor adjustment to the snippet from the last update I was able to get the form above working as noted.
Array.prototype.forEach.call(document.querySelectorAll('td:first-child input[name^=sort]'), function (elem, idx) {
elem.value = idx + 1;
By changing
'td:first-child'
to
'td:first-child input[name^=sort]'
I was able to reference the specific input field as opposed to all input fields in the first td column and no longer am replacing the input fields with plain text.
FINAL UPDATE
I have succeeded in my mission and with a minor adjustment to the snippet from the last update I was able to get the form above working as noted.
Array.prototype.forEach.call(document.querySelectorAll('td:first-child input[name^=sort]'), function (elem, idx) {
elem.value = idx + 1;
By changing
'td:first-child'
to
'td:first-child input[name^=sort]'
I was able to reference the specific input field as opposed to all input fields in the first td column and no longer am replacing the input fields with plain text.

<Script> functions not working when reducing screen size

I have a problem with the reservation module I developed in the last few months. You can have a look at it at the following address:
Taxi milan
Everything is working perfectly except for one issue. When I reduce the size of the browser window, I decided to make the image disappear and leave only the reservation module. When it is resized it stops working: all the script functions (the one providing the arrivals based on the departure selection and the "get price" button) do not work. Can you tell me what is causing the issue?
Below you can find the main parts of the code in which you may find the issue.
HOMEPAGE
<body>
<?php
$explode = explode('/', $_SERVER['REQUEST_URI']);
if($explode[1] == 'it' and $explode[2] == 'ros-ncc'){
?>
<div id="image">
<div id="modulemax">
<?php
require('wp-content/themes/customizr/prenota/index.php');
?>
</div>
</div>
<?php
}else if($explode[1] == '' and $explode[2] == ''){
?>
<div id="image">
<div id="modulemax">
<?php
require('wp-content/themes/customizr/book/index.php');
?>
</div>
</div>
<?php
} else {
}
?>
<div id="modulemin">
<?php
$explode = explode('/', $_SERVER['REQUEST_URI']);
if($explode[1] == 'it' and $explode[2] == 'ros-ncc'){
require('wp-content/themes/customizr/prenota/index.php');
}else if($explode[1] == '' and $explode[2] == ''){
require('wp-content/themes/customizr/book/index.php');
} else {
}
?>
</div>
</body>
INDEX - BOOK (english reservation module)
<?php include "prova1.php"; ?>
<script>
function getArrival(val) {
$.ajax({
type: "POST",
url: "wp-content/themes/customizr/book/process.php",
data:'dep_name='+val,
success: function(data){
$("#arrivals-list").html(data);
}
});
}
</script>
<script>
function chk(){
var var1=document.getElementById('departures-list').value;
var var2=document.getElementById('arrivals-list').value;
var var3=document.getElementById('passengers').value;
var var4=document.getElementById('bags').value;
var dataString='var1='+ var1 +'&var2='+ var2 +'&var3='+ var3 +'&var4='+ var4;
$.ajax({
type: "POST",
url: "wp-content/themes/customizr/book/process2.php",
data:dataString,
cache:false,
success: function(html){
$('#resbox').html(html);
}
});
return false;
}
</script>
<body>
<div id="rcorners1">
<form action='wp-content/themes/customizr/book/index.php' method='post'>
<label>Departure:</label>
<select name="departures" id="departures-list" class="form-control" onchange="getArrival(this.value);">
<option value="">Select Departure</option>
<?php
require('wp-content/themes/customizr/book/prova1.php');
$sql1 = "SELECT * FROM departures";
$result1 = $mysqli->query($sql1);
while($row1 = $result1->fetch_assoc()){
?>
<option value="<?php echo $row1["dep_name"]; ?>|<?php echo $row1["dep_air"]; ?>"><?php echo $row1["dep_name"]; ?></option>
<?php } ?>
</select>
<label>Arrival:</label>
<select id="arrivals-list" name="arrivals">
<option value="">Select Arrival</option>
</select>
<input id="input" type="submit" name="submit" onclick="return chk()" value="Get Price" />
</form>
You have two different div in your website. One of it has id = image, and second is id = modulemin. Div with id = image hiding when screen size < 800px width with css( display = none ), and second is hiding when screen size > 799px width with css( display = none ). And both of them have similar forms. Why you need it? Why to have 2 similar forms only for different screen sizes?
Your main problem is with id's of your form inputs variables var1, var2 ....
Your trying to got some info using ids of inputs in this lines:
var var1=document.getElementById('departures-list').value;
But, as you can understand, you always will get only inputs from first form in DOM tree, because after finding first occurrence of any id, js stoped searching and return it. More detailed about it you can find in any js documentation.
You can use class instead of id for getting all inputs with same classname from page. You can use some differ id for forms, and then get inputs with id/name/class/tagname as child node of that form( ex. ).
Also, strongly not recommend to send ajax request to some other file. Instead of it, use wp-ajax.

How do you assign variables or work with numbers in forms created by php loops?

I am working on a very simple php page. The user picks how many numbers they would like to be added up, then enters the numbers on the new page, clicks a button, and then the sum is displayed.
I cannot figure out how to add up the numbers though since I can't just assign variables to each number because of the loop. I've tried this not using loops, assigning variables to each one, and simply making the button add those variables, but that required making the code for the inputs many many times, and I want this to work with a loop in case I wanted to integrate the choice to pick hundreds of numbers or something. If php isn't the best thing for this, please let me know what would be better, but anyways... how do I add up the numbers that the user inputs?
Index page:
<p>How many number would you like to add?</p>
2<br>
3<br>
4<br>
5<br>
Calculator page:
<?php
$inputs = $_GET['inputs'];
?>
<div>Enter the numbers<br>
<?php
for ($x=0; $x < $inputs; $x++) {
echo '<input type="number"><br>';
}
?>
</div>
<form action='' method='post'><input type='submit' value='Find value' name='findvalue'></form>
<?php
if (isset($_POST['findvalue'])) {
}
?>
for ($x=0; $x < $inputs; $x++) {
echo '<input type="number"><br>';
}
You cant use input without any name. You can use dynamic name, for example:
for ($x=0; $x < $inputs; $x++) {
echo '<input type="number" name="number_'.$x.'"><br>';
}
Or better way to use array names:
for ($x=0; $x < $inputs; $x++) {
echo '<input type="number" name="number[]"><br>';
}
After that, var_dump your $_POST variable.
But, best way to create dynamic fields is creating one and clone it with javascript, when user want to add next value. Example with jQuery:
<div class="myInputs"><input type="number" name="numbers[]"></div>
Add input
<script>
$('#Add').click(function(){
$('.myInputs input:first').clone().appendTo(".myInputs");
return false;
});
Try this:
<?php
$inputs = $_GET['inputs'];
?>
<form action='' method='post'>
<div>Enter the numbers<br>
<?php
for ($x=0; $x < $inputs; $x++) {
echo '<input name="numbers[]" type="number"><br>';
}
?>
</div>
<input type='submit' value='Find value' name='findvalue'>
</form>
<?php
if (isset($_POST['findvalue'])) {
print_r($_POST["numbers"]);
}
?>
There is currently no JavaScript on your page. To interact with the client, JavaScript would be the best choice since there is no need to go to the backend to create input fields unless you need to save the number before interacting with the user
window.onload = function() {
document.getElementById("nums").onchange = function() {
var fields = document.getElementById("fields"),
numberOfField = parseInt(this.value, 10),
inputs = [];
for (var i = 0; i < numberOfField; i++) {
inputs.push('<input type="text" class="calcField" name="number' + i + '" />');
}
fields.innerHTML = inputs.length > 0 ? inputs.join("<br/>") : "";
}
document.getElementById("calc").onsubmit = function() {
var total = 0,
fields = document.querySelectorAll(".calcField");
for (var i = 0; i < fields.length; i++) {
var val = parseInt(fields[i].value, 10);
total += isNaN(val) ? 0 : val;
}
document.getElementById("total").value=total;
return false; // stop submission - remove to submit the form
}
}
<p>How many numbers would you like to add?</p>
<form id="calc">
<select id="nums">
<option value="0">Please select</option>
<option value="2">Two numbers</option>
<option value="3">Three numbers</option>
<option value="4">Four numbers</option>
</select>
<div id="fields"></div><hr/>
<input type="submit" value="Find value" /> <input type="text" id="total" />
</form>
try adding a hidden field for the number of inputs then use it to loop
<?php
$inputs = $_GET['inputs'];
?>
<form action='' method='post'><input type='submit' value='Find value' name='findvalue'>
<div>Enter the numbers<br>
<input type="hidden" name="numberofinputs" value="<?php echo $inputs;?>"/>
<?php
for ($x=0; $x < $inputs; $x++) {
//Please note the $x
echo '<input type="number'.$x.'"><br>';
}
?>
</div>
</form>
<?php
if (isset($_POST['findvalue'])) {
$numberOfinputs = $_POST['numberofinputs'];
for($i=0; $i<numberOfinputs; $i++){
//You can access it here
echo $_POST['number'.$i];
}
}
?>

Passing url parameters in form action attribute

<?php for($i = 0; $i < $pin_num_rows; $i++){ ?>
<form action="/group/<?php echo $group_id ?>?Comment=<?php echo $pin_id[$i] ?>" method="post" id="group-comment-form">
<textarea name="group-comment" id="group-comment" placeholder="Add a comment..." spellcheck="false"></textarea>
</form>
<?php } ?>
This is the some part of my code. As you can see, I am passing the value of pin_id in my form action. The problem is, whenever I post comment, the form submits the value with /group/?Comment=1 but it supposed to submit with 1, when I comment to the first post. So, when I comment to the second post, it supposed pass 2 but it doesn't. It always passes /group/?Comment=1
I did echo this right after my textarea and I see that for every comment form, the number increments as it should be but when I submit, it submits with value 1. I am going crazy.
<?php echo "/group/<?php echo $group_id ?>?Comment=$pin_id[$i]" ?>
I have also this part in my code in the same loop above and it has the same logic but it works. I don't understand why the form part doesn't work.
Edit
Delete
EDIT
I wrote this simple program which demonstrates the same logic that I used for the site and this simple program works but website. I guess the problem is not about the names of form or textarea.
<?php
$inputValue = NULL;
$id = [1,2,3];
if(isset($_POST['inputName'])){
$inputValue = $_POST['inputName'];
echo "<br>Input Value: " . $inputValue;
}
if(isset($_GET['id'])){
$getValue = $_GET['id'];
echo "<br>Get Value: " . $getValue;
}
?>
<html>
<head><title>Multiple Forms in One Page</title></head>
<body>
<br>
Main Page
<br>
<?php for($i = 0; $i < 3; $i++){ ?>
<form action="index.php?id=<?php echo $id[$i] ?>" method="post" name="formName">
<textarea name="inputName"></textarea>
<input type="submit" name="submitName">
</form>
<?php } ?>
</body>
</html>
FOUND THE PROBLEM (BUT STILL NEED FIX)
<script>
$(function() {
$('textarea#group-comment').on('keydown', function(e) {
if(e.keyCode == 13 && !e.shiftKey){
document.getElementById('group-comment-form').submit();
}
});
});
</script>
I use this script to submit my forms. I don't have a submit button to submit. If I use submit button, everything works perfect but if I use this script above to submit the form, it won't work. What should I do to make the script above work?
SOLUTION
After I found where the problem is caused, I created another question to find a fix for the problem.
The answer is here: Solutution

Multiple forms onclick event only working for first form

I'm sure this has been asked befor but I can't seem to find it in a search
I have multiple forms on a page generated by php all with onCick event
The problem is it only picks up the first event after that any other clicks produce same result from first click
Here is javascript
function CompareScores(form)
{
var scoreA = document.getElementById("score_A").value;
var scoreB = document.getElementById("score_B").value;
if(scoreA > scoreB){
alert('Score A is Larger ' + scoreA)
}else{
alert('Score B is Larger ' + scoreB)
}
}
And the php generating forms
<?php
while($i<=$numPrelimTeams) {
if($i!=$e) {
?>
<form action="processScores.php" method="post"><p><u><?php echo $prelimTeam[$i]; ?> --> SCORE : <input type="text" class="small" id="score_A" name="score_A" size="1"></u></p>
<input type="hidden" name="team_A" value="<?php echo $prelimTeam[$i]; ?>">
<input type="hidden" name="game" value="<?php echo $game_num; ?>">
<p class="right">Game # <?php echo $game_num; ?> ) <input type="button" value="Enter Scores" onClick="CompareScores(this.form)"></p>
<?php
}else{
?>
<p><u><?php echo $prelimTeam[$i]; ?> --> SCORE : <input type="text" class="small" id="score_B" name="score_B" size="1"></u></p>
<input type="hidden" name="team_B" value="<?php echo $prelimTeam[$i]; ?>">
</form><br><br><br>
<?php
$game_num++;
$e=$e+2;
}
$i++;
}
?>
Without knowing the inputs or seeing the result, it's hard to tell for sure, but it looks like you might be generating multiple instances of this form on the same page, giving you multiple page elements named "score_A" and "score_B". document.getElementById will then become a bit ambiguous.
Since you're already sending the form object, use that instead:
var scoreA = form.score_A.value;
...
There is essentially a single problem with your code. You have multiple instances of the same ID.
To fix it, try something like this.
<input type="text" class="small score_A" name="score_A" size="1" />
Similarly
<input type="text" class="small score_B" name="score_B" size="1" />
Now, you can write a querySelector in your JS
function CompareScores(form) {
var a = form.querySelector('.score_A').value;
var b = form.querySelector('.score_B').value;
//do something
}

Categories