HTML Submit form only executing one JavaScript function on submit - javascript

Good Afternoon,
I am currently in the process of creating a website using HTML, PHP and JavaScript, and I have run into an issue when trying to check for duplicate usernames in a database. Currently, I have a form which uses the following code to call two javascript functions on submit.
<form onsubmit="return (checkValid() && usernameCheck())" action="create.php" method="post" id="registerForm">
The javascript code is then present at the bottom of the body tag, within script tags, and is the following.
<script>
var pass = document.getElementById('passVal').value;
var confPass = document.getElementById('confPassVal').value;
var error = document.getElementById('errorMsg');
var result = true;
function checkValid(){
if(pass !== confPass)
{
error.type = "text";
error.value = "Passwords do not match!";
error.style.backgroundColor = "#E34234";
document.getElementById('passVal').style.borderColor = "#E34234";
document.getElementById('confPassVal').style.borderColor = "#E34234";
result = false;
}
return result;
}
function usernameCheck()
{
var username = document.getElementById('userName').value;
var j = checkName(username);
console.log(j);
if ( j == "taken" ) {
error.type = "text";
error.value = "Username Already Exists, Please choose an alternative.";
error.style.backgroundColor = "#E34234";
document.getElementById('userName').style.borderColor = "#E34234";
console.log(j);
result = false;
}
if ( j == "available" ) {
console.log(j);
result = true;
}
return result;
}
function checkName(uname) {
if (window.XMLHttpRequest) {
xhttp = new XMLHttpRequest();
} else {
xhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
var httpURL = "checkUserName.php?n=" + uname;
xhttp.open("GET",httpURL,false);
xhttp.send();
return xhttp.responseText;
}
</script>
The issue I am having is that the second JavaScript function is not executing, even though it is being called in the onsubmit function. Because of this, the third function is also not executing, as this function is called within the second function. The second function submits a GET value with the username input in the HTML form to a PHP script. The PHP script then checks the database to see if this user exists, and returns a value based on if this is true or not. The code below shows the PHP script.
<?php
session_start();
require 'sql.php';
header('Content-type: text/plain');
$userName = $_GET['n'];
$query = "SELECT username FROM users where username='$username'";
$checkun = $conn->query($query);
while ($row = $checkun->fetch_assoc()) {
if ($row > 0)
{
exit('taken');
} else
{
exit('available');
}
}
?>
The first JavaScript function successfully executes, which is used to check if the password fields match. This function either returns a false value if the password fields do not match (hence the second function will not execute), or a true value if they do. Even if the first function returns true, the next function does not execute, and the form submits without running this second function.
I would be grateful if someone more experienced than me (I have only been practising web development for a few months) could highlight if there are any errors in my method, and possibly help me with a solution.
Thank you for taking the time to read this!

When you say "the second function does not run" - do you mean that you get no response in the JS? I would imagine that to be true as you will NEVER have a match in your MySQL query - and, you don't have your 'catchall' in the right place.
This looks like a first learning experience for you to get data from a database, so I won't harp on the fact that you are WIDE OPEN for SQL injection attacks, though I will say that you must NOT use this code on any open system where there are real users (you need to learn how to protect against those attacks - there's loads of data on that on SO)!
So, your first step in at least getting the 'second function' to 'work'.....
<?php
session_start();
require 'sql.php';
header('Content-type: text/plain');
// $userName = $_GET['n']; // <<<==== here you use with a capital
$username = $_GET['n']; // let's change it to be the same
$query = "SELECT username FROM users where username='$username'"; // now, we have a chance...
$checkun = $conn->query($query);
while ($row = $checkun->fetch_assoc()) {
if ($row > 0)
{
exit('taken');
}
}
// Here is where to put your 'catchall' in case you don't get anything from the query (what you have won't ever give 'available')
exit('available');
?>

Related

How to turn this Password validation right?

var password=123;
var input;
var opp=0;
for(var t=0;t<=2;t++){
if(password!=input && t<=2){
input=prompt("enter your password");
}
else{
opp++;
}
}
if(opp!=0){
alert("success");
}
else if(opp<1){
alert("fail");
}
im expect it to be a password validation which can only try three times.
but it will failed even with typing correct password in the third try.
Let's begin saying this should just be a didactic excercise.
I suggest you to drop the for loop strategy and embed the logic inside a while loop that will keep running as long as the attempt counter variable will be <=3.
Until the typed password still doesn't match the expected one, it will keep asking for a new password after saying fail for a total amount of 3 attemps max.
If the typed password matched, it just alerts the user saying success and exiting the loop.
Of course as just said by other users, this approach is very wrong in terms of security starting from the fact that the expected password is stored in plain text.
As a side note, the expected password defined as a literal should be a string literal and not a number.
let password = '123';
let attempt = 0;
let input;
let wasSuccess = false;
while(++attempt<=3){
input = prompt("enter your password");
if(input == password){
wasSuccess = true;
alert('success');
break;
}else{
alert('fail');
}
}
if(wasSuccess){
//perform any logic expected to run after successfully logged in
}
I am not sure what it is you are trying to do, this is totally unsafe.
To easily crack your password challenge, click 'view source' on the browser, and lookup the password.
Please use better authentication, preferably on the server, not in javascript.
Of course you can use Javascript, but not for actual password checking.
Since OP is just trying and will never use this in a production environment, here is a working piece of script:
var password= "123";
var input;
var tries=1;
var maxTries = 5;
var passed = false;
while ( (!passed) && (tries <= maxTries) ){
input=prompt("enter your password (attempt nr "+tries+")");
if (input === password){
passed = true; // Yeah!
} else {
tries = tries + 1;
}
}
if (passed){
alert("success");
} else {
alert("fail");
}

PHP Array to Javascript Object no array after console.log

Now there are plenty of people with the same issue and their resolutions have not worked.
Problem
I have a list of Times coming back from a REST call. They are created exactly as they should, except I want them to be stored into a JavaScript Array.
PHP
function getOpenAppts()
{
global $wpdb;
$final_array = "";
$td = date('m/d/Y');
$datetime = new DateTime('tomorrow');
$tm = $datetime->format('Y-m-d');
$startDate = $td;
$endDate = $tm;
$apptTypeID = "23";
$get_loc = $wpdb->get_results('SELECT provid,id FROM location');
foreach($get_loc as $val){
// call to Athena to get open appointments
$res = getOpenAppointments($val->id, $val->provid, $startDate, $endDate, $apptTypeID);
//print_r($res);
// if we got some appointments back strip any that started before now
if (array_key_exists('totalcount', $res) && $res['appointments'] > 0)
{
$tzStr = "America/Los_Angeles";
$tzObject = new DateTimeZone($tzStr);
$nowDT = new DateTime();
$nowDT->setTimezone($tzObject);
//print_r($nowDT);
//print_r("\n");
$appts = array();
for ($i = 0; $i < count($res['appointments']); $i++)
{
$apptDT = new DateTime($res['appointments'][$i]['date']." ".$res['appointments'][$i]['starttime'], $tzObject);
//print_r($apptDT);
//print_r("\n");
if ($nowDT < $apptDT)
$appts[] = $res['appointments'][$i];
}
}
if (count($appts) > 0)
foreach($appts as $data) {
$final_array[] = $data;
}
else
$res; // something went wrong. return error message
}
echo json_encode($final_array);
}
Header.php
<script>
var times = <?php getOpenAppts(); ?>;
console.log(times); //Will display properly
</script>
That is exactly how it should come back!
But.. When I run a console on the variable times (which is in the header making it a global variable. I get this.
It should give me the exact same list that the console.log gave me.
What I Have tried
I ran:
PARSE.json(times);
No effect...
I did in PHP:
json_encode(json_decode($appts),true);
No effect...
What part of this process is incorrect?
You are using time as a global variable.
Since the console.log right after the declaration prints everything fine, you are probably overriding its value somewhere after.
Avoid the most you can global variables, they're evil :)

Getting wrong array length with jQuery and mysqli_num_rows()

I'm adding new data to database table with jQuery. Then i'm getting all content from that table. Problem is i'm getting wrong array size every odd time.If i refresh the page it's getting right array size but when i'm clicking button with jQuery function it's all messed up.
I figure out that
$n = mysqli_num_rows($result);
already return wrong num of rows
Here is the script:
$(document).ready(function(){
$.getallentries = function(){
$.getJSON("entries.php",{action : "getall"},function(data) {
var content_array = $.map(data, function(e) { return e;});
console.log(content_array.length); // to check array size
});
$.addstatic = function(){
$.post("entries.php",{action : "addstatic"});
};
};
$("#adds").on("click",function(){
$.addstatic();
$.getallentries();
});
$.getallentries();
And here is entries.php:
function getall(){
$link = db_connect();
$query= "SELECT * FROM jq";
$result = mysqli_query($link,$query, MYSQLI_STORE_RESULT);// Smart people said MYSQLI_STORE_RESULT should help but it didn't
$n = mysqli_num_rows($result);
for($i = 0 ;$i<$n;$i++)
{
$row=mysqli_fetch_assoc($result);
$b[]=$row;
}
echo json_encode(array($b));
}
function addstatic(){
$link = db_connect();
$statin_Entry = "Static Entry";
$query = "INSERT INTO jq (Entry) VALUES ('$statin_Entry')";
$result = mysqli_query($link,$query);
}
if(isset($_GET['action']) && !empty($_GET['action'])) {
$action = $_GET['action'];
switch($action) {
case 'getall' : getall(); break;
}
}
else {
if(isset($_POST['action']) && !empty($_POST['action'])) {
$action = $_POST['action'];
switch($action) {
case 'addstatic' : addstatic();break;
case 'removelast' : removelast();break;
// ...etc...
}
}
}
This is log of array length
So the problem again, same array size 143,146,151 and where is 156??
You should call $.getallentries in the callback function of the $.addstatic AJAX call, so that it runs after $.addstatic has finished updating the database.
$.addstatic = function(){
$.post("entries.php",{action : "addstatic"}, $.getallentries);
};
There's no need to use mysqli_num_rows before fetching the rows. You should use a loop like this:
while ($row = mysqli_fetch_assoc($result)) {
$b[] = $row;
}
Also, you're wrapping your array in another array. Just do:
echo json_encode($b);
The way you've written it, console.log(content_array.length) should always log 1, I don't understand how you're getting higher numbers. Are you sure you posted the actual code?
There's no point in use $.map, all it's doing is making a copy of the data array. Just use data itself.
And in your PHP, you don't need to test both isset() and !empty(), because empty() checks if the variable is set first.
You don't need to use MYSQLI_STORE_RESULT, it's the default for that option.

Stored value generating [object HTMLInputElement]

I have an indexedDB and using it for a login function. I'm trying to populate a form with the users information when they log in. However the form populates with [object HTMLInputElement] instead of the users info.
This is where I take the user (db key) to access the Object (the user)
EDITThis is my site where it's running: http://www3.carleton.ca/clubs/sissa/html5/admin.html
My site editor is updating it as I save, so there may be changes to the site script as I try new things.
This is where I take the user (db key) to access the Object (the user)
function loginCheck(user,pass){ db.transaction("users").objectStore("users").get(user).onsuccess = function(event) {
var loggedUser = event.target.result;
if(!loggedUser){
alert('Sorry, Username does not exist. Please try again.');
}else if(pass !== loggedUser.pw ){
alert('Incorrect log in combination. Please try again.');
}else{loggedIn(loggedUser);}
}
}
function loggedIn(loggedUser){
var u=loggedUser;
alert('Welcome '+u.fn+' '+u.ln+' to Macroplay');
//function to populate fields
alert('get values called');
getValues(u);
//session store
var signedin = 'user';
var username = u.userName;
newLocal(signedin,username);
alert('local storage set');
}
I use this function getValues to store the various fields I want from the object.
EDIT: I declared the variable test as global and stored the users first name (fn). The alerts show the correct name but the populate still gives me undefined.
var test;
function getValues(loggedUser){
var u = loggedUser;
alert('storing first name');
test = u.fn;
alert('First name = '+test);
lName = u.ln;
users = u.userName;
pass = u.pw;
email = u.em;
dob = u.dob;
tel = u.tel;
bio = u.bio;
school = u.scl;
alert('user values stored');
if(u.gender == 'M'){
gender[0].checked= true ;
}else{gender[1].checked= true ;}
}
This is the function I use to populate the form that's giving me [object HTMLInputElement]
function populateFields(){
alert('Name of populated field: '+test);
fName.value = test;
lName.value = lName;
users.value = users;
pass.value = pass;
email.value = email;
dob.value = dob;
tel.value = tel;
bio.value = bio;
terms.disabled = true;
school.value = school;
alert('populate fields done');
save.value = 'Update';
signin.innerHTML = 'Log Out';
registerLabel.innerHTML = 'Account Information';
//open user info form
var accountInfo = document.getElementsByTagName('details');
accountInfo[1].open = open;
}
Just look at one line:
fName.value = fName
You are setting the value property of fName to fName itself.
Rather than creating numerous global variables, just use loggedUser directly in populateFields():
fName.value = loggedUser.fn;
Edit: Looking at your site, I see the important bit you left out. populateFields() is being called after the page reloads. So, populateFields() does not have access to any variable created before the page reloaded.
Since I'm helping you with homework, I don't want to just hand you the answer on a silver platter. The trick is that the user data must be retrieved from the database and made available to populateFields() before it is called, or from within the function. You can make the user object available as a global variable, but it may be better to pass it in as a parameter.
You probably want to also cancel the form submission:
document.getElementById("loginForm").onsubmit = function (e) {
e.preventDefault();
}
And then just call populateFields() directly from loggedIn() instead of getValues().

Use jQuery.post() result in javascript function

I've got no clue how to do the following, so I wasn't sure what to search for either.
For validating my registration form I've a javascript function that checkes the existence of the inserted username in the database onblur of the username textfield.
function checkUsername(username){
$.post("checkmail.php", {username: username} , function(data){
var $response=$(data);
var response = $response.filter('#username-response').text();
if(response == "taken") {
document.getElementById('username').style.borderColor = rood;
valid = false;
}
});
}
This works fine, but now I want to validate it again onsubmit of the form in case users decide to submit an existing username.
function validateForm() {
var valid = true;
//checks different fields
//now check voor username existence
var username = document.getElementById('username').value;
checkUsername.call(username);
if (!valid) {
return false;
}
else {
return true;
}
}
I'm not familiar enough with Javascript to get this working. Probably thinking in the wrong direction...
You can use synchronous ajax call for this as you are using return data for validation.

Categories

Resources