Is there a way to convert left and right single quotes into apostrophes when a form is submitted and before validation begins?
The reason I ask is that my form works on all platforms just how I want it, however iPhone users at times use the wrong character and input a left or right single quotation instead. As my form verifies the entered data and must be exact, the left single quote is being seen as a error compared to the apostrophe in the DB table and not accepting the information.
If I could have those characters convert when the user submits to apostrophes then all would work even on the iPhones. any insight would be gratefully appreciated, I have tried a few items like htmlspecialchar but didn't seem to assist.
Also I should note that when using the iPhone and entering the coorect apostrophe in the smart keyboard layout on ios11 I was able to successfully pass validation of the form. It seems this is a known issue of apples but they have yet to rectify this, I am sure the solution would be beneficial to many in the community I hope, if we can find the answer that is.
The form field in question is:
<input type="text" name="last_name" id="last_name" value="<?php echo htmlspecialchars(stripslashes(isset($fields['last_name'])) ? $fields['last_name'] : '') ?>" >
how can I set this form field to convert left and right single quotes into apostrophes on form submit using php or jquery?
UPDATE
#fubar you are my savior tonight. the first solution worked great. But how would I add teh second option instead?
function cv(&$fields, &$errors) {
// Check args and replace if necessary
if (!is_array($fields)) $fields = array();
if (!is_wp_error($errors)) $errors = new WP_Error;
// Check for form submit
if (isset($_POST['submit'])) {
// Get fields from submitted form
$fields = cv_get_fields();
// Validate fields and produce errors
if (cv_validate($fields, $errors)) {
// If successful, display a message
$Id=$fields['login'];
$First=$fields['first_name'];
$Last=$fields['last_name'];
global $wpdb;
$user = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM users WHERE login = %s", $Id ) );
$userquery = $wpdb->get_results($user->login);
$Id=$fields['login'];
if ( !username_exists ($Id)) {
$Id=$fields['login'];
$access = $wpdb->get_row( $wpdb->prepare( "SELECT access FROM table WHERE ID = %s", $Id ) );
foreach ($access as $accessquery) {
if ($accessquery == lvl2) {
$_SESSION['mem_data']=$fields;
header("Location: https://example.com/lvl2-register/");
}
if ( is_null ($accessquery)) {
$_SESSION['mem_data']=$fields;
header("Location: https://example.com/lvl1-register/");
}
}
}
elseif ( username_exists ($Id)) {
header("Location: https://example.com/already-registered/");
}
}
}
// Santitize fields
cv_sanitize($fields);
// Generate form
cv_display_form($fields, $errors);
}
function cv_sanitize(&$fields) {
$fields['login'] = isset($fields['login']) ? sanitize_user($fields['login']) : '';
$fields['first_name'] = isset($fields['first_name']) ? sanitize_text_field($fields['first_name']) : '';
$fields['last_name'] = isset($fields['last_name']) ? sanitize_text_field($fields['last_name']) : '';
}
function cv_display_form($fields = array(), $errors = null) {
// Check for wp error obj and see if it has any errors
if (is_wp_error($errors) && count($errors->get_error_messages()) > 0) {
// Display errors
?>
<div class="step1-form" style="display:block;margin:0 auto;text-align:left;max-width:1080px;">
<?php
foreach ($errors->get_error_messages() as $key => $val) {
?><p>
<?php echo $val; ?>
</p><?php
}
?><?php
}
// Display form
?>
</div>
<div class="step1-form" style="display:block;margin:0 auto;text-align:left;max-width:1080px;">
<h1 class="til-postheader entry-title">User Registration: Step 1 of 2</h1>
<h4>Prior to registering for this website you must first verify Your Membership.<h4>
<div id="login" style="max-width:175px;width:100%;margin:10px;">
<form action="" method="post">
<div>
<label for="first_name">First Name:</label><br>
<input type="text" name="first_name" id="first_name" value="<?php echo (isset($fields['first_name']) ? $fields['first_name'] : '') ?>" >
</div>
<br>
<div>
<label for="last_name">Last Name:</label><br>
<input type="text" name="last_name" id="last_name" value="<?php echo htmlspecialchars(stripslashes(isset($fields['last_name'])) ? $fields['last_name'] : '') ?>" >
</div>
<br>
<div>
<a data-fancybox data-src="#ID" href="javascript:;" style="outline:none;border:0px;text-decoration:none;" tabindex="-1"><span style="width:21px;float:right;color:#ffffff;background:#0a4b73;text-align:center;line-height:21px;border-radius:50%;" tabindex="-1">?</span></a><label for="login">Member ID:</label><br>
<input type="text" name="login" id="login" value="<?php echo (isset($fields['login']) ? $fields['login'] : '') ?>" >
</div>
<br>
<input type="submit" name="submit" value="Verify Membership">
</form>
</div>
<?php
}
function cv_get_fields() {
return array(
'login' => isset($_POST['login']) ? $_POST['login'] : '',
'first_name' => isset($_POST['first_name']) ? $_POST['first_name'] : '',
'last_name' => isset($_POST['last_name']) ? $_POST['last_name'] : '',
);
}
function cv_validate(&$fields, &$errors) {
// Make sure there is a proper wp error obj
// If not, make one
if (!is_wp_error($errors)) $errors = new WP_Error;
// Validate form data
// Define $Card $First $Last $PIN
$Id=$fields['login'];
$First=$fields['first_name'];
$Last=$fields['last_name'];
// $Lastname = htmlspecialchars_decode(stripslashes($fields["last_name"]));
$Lastname = '‘ ‘ - ’ ’';
$Lastname = str_replace(['‘', '’'], "'", html_entity_decode(stripslashes($fields["last_name"])));
global $wpdb;
$result = $wpdb->get_row( $wpdb->prepare( 'SELECT distinct ID, First, Last, FROM table WHERE ID = %s AND First = "%s" AND Last = "%s", $Id, $First, $Lastname ) );
if ( is_null ( $result ) ) {
$errors->add('non_member', 'The information entered does not match our records.');
}
if (empty($fields['login']) || empty($fields['first_name']) || empty($fields['last_name'])) {
$errors->add('field', '');
}
// If errors were produced, fail
if (count($errors->get_error_messages()) > 0) {
return false;
}
$Id=$fields['login'];
global $wpdb;
$accessno = $wpdb->get_row( $wpdb->prepare( "SELECT distinct access FROM table WHERE ID = %s", $Id ) );
foreach ($accessno as $noquery) {
if ( $noquery == NO) {
header ('Location: https://example.com/access-denied/');
}
}
// Else, success!
return true;
}
// The callback function for the [cv] shortcode
function cv_cb() {
$fields = array();
$errors = new WP_Error();
// Buffer output
ob_start();
// Custom verification, go!
cv($fields, $errors);
// Return buffer
return ob_get_clean();
}
add_shortcode('cv', 'cv_cb');
This would convert the single quote, both raw and encoded into apostrophes.
$value = '‘ ‘ - ’ ’';
$value = str_replace(['‘', '’'], "'", html_entity_decode($value));
If you want to apply this to all POST data, you could use:
$_POST = array_map(function ($value) {
return str_replace(['‘', '’'], "'", html_entity_decode($value));
}, $_POST);
Edit
If you replace the following line:
// Get fields from submitted form
$fields = cv_get_fields();
With:
// Get fields from submitted form
$fields = array_map(function ($value) {
return str_replace(['‘', '’'], "'", html_entity_decode($value));
}, cv_get_fields());
And then you can remove the following:
$Lastname = '‘ ‘ - ’ ’';
$Lastname = str_replace(['‘', '’'], "'", html_entity_decode(stripslashes($fields["last_name"])));
Related
new to forum, AJAX and JQuery. A little experience of PHP and JS.
I'm trying to present a long series of questions (400+) one by one in an input text field on a form with 2 submit buttons labelled "True" and "False". I need one question to be presented at a time, then record the True or False result as (1 or -1) sequentially into another text file. I cannot refresh the input field with the next question after 'Submit'. I believe that AJAX would be the answer.
This code is the first effort: (any later efforts are more complicated, but don't work any better) it opens the questions file (CPXQ.dat) into an indexed array, then places the first question into the input text field. When either of the submit buttons are pressed, the result is POSTed to data.cpx, and the next question appears, but it won't continue thereafter. I have tried various PHP loops and some javascript, but these don't work, either looping through immediately to the last question, or getting stuck in the loop. (The php includes just contain CSS and JQuery source.)
I'd also like to prevent the user from being able to go back over any of the questions, but that may be a query for another day!
Any advice much appreciated, and apologies if not clear. Happy to provide any further info.
<div class="container">
<?php include("top.php"); ?>
<div class="intro">
<p><h1>CPI TEST</h1></p>
<?php
$i = 0;
//file in to an array
$lines = file("CPXQ.dat");
?>
<?php
if(isset($_POST['submitT'])) {
//echo $_POST['submitT'];
$data="1";
//echo $data;
$fp = fopen('data.cpx', 'a') or die("Unable to open file!");
fwrite($fp, PHP_EOL);
fwrite($fp, $data);
fclose($fp);
++$i;
}
if(isset($_POST['submitF'])) {
//echo $_POST['submitF'];
$data="-1";
//echo $data;
$fp = fopen('data.cpx', 'a') or die("Unable to open file!");
fwrite($fp, PHP_EOL);
fwrite($fp, $data);
fclose($fp);
++$i;
}
?>
<form method = "post" action = "CPI_Test.php">
<input type="text" name="question" value="<?php echo $lines[$i];?>">
<input type="submit" name="submitT" value="True">
<input type="submit" name="submitF" value="False">
</form>
</div>
</body>
Here's the code for the preliminary page collecting user details:
<!DOCTYPE html>
<html>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>PPCS CPI Information</title>
<?php include("head.php"); ?>
</head>
<body>
<?php
// define variables and set to empty values
$initdataErr = $surnamedataErr = $agedataErr = $gendataErr = "";
$initdata = $surnamedata = $agedata = $gendata = $codata = "";
function test_input(&$surnamedata) {
$surnamedata = trim($surnamedata);
$surnamedata = stripslashes($surnamedata);
//$data = htmlspecialchars($data);
$surnamedata = preg_replace('/\s+/', '', $surnamedata);
return $surnamedata;
}
if ($_SERVER["REQUEST_METHOD"] == "POST") {
if (empty($_POST['initdata'])) {
$initdataErr = "Initials are required";
} else {
$initdata = test_input($_POST['initdata']);
// check if name only contains letters and whitespace
if (!preg_match("/^[A-Z- ]*$/",$initdata)) {
$initdataErr = "Please use capital letters without spaces only";
}
}
if (empty($_POST['surnamedata'])) {
$surnamedataErr = "Surname is required";
} else {
$surnamedata = test_input($_POST['surnamedata']);
// check if name only contains letters and whitespace
if (!preg_match("/^[a-zA-Z-' ]*$/",$surnamedata)) {
$surnamedataErr = "Please use letters only";
}
}
if (empty($_POST['agedata'])) {
$agedataErr = "Age is required";
} else {
$agedata = test_input($_POST['agedata']);
// check if name only contains letters and whitespace
if (!preg_match("/^[0-9]*$/",$agedata)) {
$agedataErr = "Only numbers and white space allowed";
}
}
if (empty($_POST['gendata'])) {
$gendataErr = "Gender is required";
}
}
?>
<div class="container">
<?php include("top.php"); ?>
<br><h1>CPI TEST INFORMATION</h1><br>
<b>Please fill in the form below carefully</b>
<p><span class="error">* required field</span></p>
<br>
<form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>">
Initials: <span class="error">* <?php echo $initdataErr;?></span> <br>
<input type="text" name="initdata" value="<?php echo $initdata;?>"><br>
<br>
Surname: <span class="error">* <?php echo $surnamedataErr;?></span> <br>
<input type="text" name="surnamedata" value="<?php echo $surnamedata;?>" ><br>
<br>
Company (Optional):<br>
<input type="text" name="codata" value="<?php echo isset($_POST["codata"]) ? $_POST["codata"] : '';?>" ><br>
<br>
Age in Years: <span class="error">* <?php echo $agedataErr;?></span><br>
<input type="text" name="agedata" maxlength="2" min="0" max="99" step="1" pattern="[0-9]{2}"value="<?php echo $agedata;?>"><br>
<br>
Gender: <span class="error">* <?php echo $gendataErr;?></span><br>
<select name="gendata">
<option value="">Select...</option>
<option value="m" <?php echo (isset($_POST['gendata']) && $_POST['gendata'] == 'm') ? 'selected' : ''; ?>>Male</option>
<option value="f" <?php echo (isset($_POST['gendata']) && $_POST['gendata'] == 'f') ? 'selected' : ''; ?>>Female</option>
</select>
<br>
<input type="submit" name="submit" value="Submit">
</form>
</div>
</body>
</html>
<?php
if(isset($_POST['submit'])){
// Fetching variables of the form which travels in URL
$initdata = $_POST['initdata'];
$surnamedata = $_POST['surnamedata'];
$codata = $_POST['codata'];
$agedata = $_POST['agedata'];
$gendata = $_POST['gendata'];
if($initdata !=''&&(preg_match("/^[A-Z]*$/",$initdata))
&& $surnamedata !='' && (preg_match("/^([A-Za-z \-]+(?:\'|�*39;)*)*[A-Za-z \-]+$/",$surnamedata)) && $agedata !='' && (preg_match("/^[0-9]*$/",$agedata)) && $gendata !='')
{
date_default_timezone_set("Europe/London");
//^['\a-zA-Z]*$/ This is the most recent
test_input($surnamedata);
$_POST['surnamedata'] = ucwords($_POST['surnamedata']);
$data = '"' . $_POST['initdata'] . ' ' . stripslashes($_POST['surnamedata']) . '","' . $_POST['agedata'] . '","'. $_POST['gendata'] .'","' . $_POST['codata'] . '","' . '","'. '","'. date("d/m/Y"). '","'. date("H:i:s"). '","';
//Create CPX filename
$fn = $_POST['initdata'] . $_POST['surnamedata'];
$fn = preg_replace('/\PL/u', '', $fn);
$fn = strtoupper($fn);
$fn = $fn . "XXXXXX";
$fn = substr($fn,0,8);
echo "$fn";
echo "$data";
//Create temp file for CPX filename
$fp = fopen($fn . '.temp', 'a') or die("Unable to open file!");
fwrite($fp, $fn);
fclose($fp);
//Create CPX file
$fp = fopen($fn . '.cpx', 'a') or die("Unable to open file!");
fwrite($fp, $data);
//Append new line
//fwrite($fp, "\ntest");
fclose($fp);
// Redirect
/header("Location:/CPI_Form_Trial/instructions.php");
}
else{
?>
<br><span class = "error"><?php echo "Please make sure that you have filled in all required fields and click 'Submit' again";?></span> <?php
}
}
?>
Using AJAX (fetch) is ideally suited to this type of problem where you do not wish to refresh the screen and want to present new data after submitting a http request. The following single page application shows how you might accomplish your stated goal but it does not take into account a couple of possible issues which are:
[a] multiple users participating in the questionnaire simultaneously
[b] a user abandoning the questionnaire and restarting, once or more than once.
The issues mentioned could be negated by using a database to store answers and assigning the users unique identifiers (ie: user id, username) which is used when sending the ajax request.
The demo that follows will write, to the answerfile, either 1 or 0 ( which is more common than -1 for false ) alongside the question line number ( which is sort of the ID )
<?php
if( $_SERVER['REQUEST_METHOD']=='POST' && isset( $_POST['action'] ) ){
ob_clean();
$file='CPXQ.dat';
$answerfile='data.cpx';
$lines=file( $file );
switch( $_POST['action'] ){
case 'start':
header('Content-Type: text/html');
exit( $lines[0] );
break;
case 'question':
$id=(int)$_POST['id'];
# increment ID value
$id++;
$question=isset( $lines[ $id ] ) ? $lines[ $id ] : false;
if( $question && $id < count( $lines ) ){
# log the current answer
file_put_contents( $answerfile, sprintf( 'q:%s,a:%s', $id, $_POST['answer'] ) . PHP_EOL, FILE_APPEND );
# the json payload
$data=array(
'id' => $id,
'question' => $question
);
} elseif( !$question && $id==count( $lines ) ){
# log the final answer
file_put_contents( $answerfile, sprintf( 'q:%s,a:%s', $id, $_POST['answer'] ) . PHP_EOL, FILE_APPEND );
$data=array(
'id' => 0,
'question' => 'End of questionnaire'
);
}
header('Content-Type: application/json');
exit( json_encode( $data ) );
break;
}
exit();
}
?>
<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='utf-8' />
<title>Questions, questions, questions...</title>
</head>
<body>
<!--
a basic form: The question is rendered within the `fieldset`
element. Both buttons use datasets, the data-id refers to the
question number (line from source file) and data-value is the
boolean value indicating answer value.
-->
<form name='questions' method='post'>
<fieldset></fieldset>
<div>
<input type='button' data-value=1 data-id=0 value='True' />
<input type='button' data-value=0 data-id=0 value='False' />
</div>
</form>
<script>
const fs=document.querySelector('fieldset');
/*
When the page loads we fetch the first question ( ie: first line in source file )
and display on the page. The action parameter helps the backend determine what stage
we are at.
*/
let fd=new FormData();
fd.set('action', 'start');
// make the request an show question
fetch( location.href, { method:'post', body:fd })
.then(r=>r.text())
.then(text=>{
fs.innerHTML=text;
});
/*
The delegated event handler processes button clicks and sends the
data-id ( ie: line number ) and answer to the backend processing script.
Here this is all done on the same page for convenience - for your case
it would be CPI_Test.php
*/
const clickhandler=function(e){
if( e.target.tagName.toLowerCase()=='input' && e.target.type=='button' ){
// set a different `action` so that the backend knows what to do
fd.set('action','question');
fd.set('id',e.target.dataset.id);
fd.set('answer',e.target.dataset.value);
// send the request and display new question
fetch( location.href, { method:'post', body:fd } )
.then( r=>r.json() )
.then( json=>{
fs.innerHTML=json.question;
// update the buttons so that they have the new id assigned ready for next click
// or disable ( or remove ) when the questionnaire is over.
document.querySelectorAll('[type="button"][data-value]').forEach( bttn=>{
if( Number( json.id ) !==0 ) bttn.dataset.id=json.id;
else bttn.disabled=true;
});
})
}
};
// add a delegated event handler to process button clicks
document.forms.questions.addEventListener( 'click', clickhandler );
</script>
</body>
</html>
A sample of the answerfile:
q:1, a:1
q:2, a:0
q:3, a:1
q:4, a:1
q:5, a:0
q:6, a:0
q:7, a:1
q:8, a:0
q:9, a:1
q:10, a:0
q:11, a:1
q:12, a:1
q:13, a:1
q:14, a:1
q:15, a:0
q:16, a:1
q:17, a:0
q:18, a:1
q:19, a:1
q:20, a:0
I hope it helps you arrive at a solution but as mentioned it would be more robust / reliable with a database rather than simple text file.
I'm pretty new to programming in the middle of 2 Udemy courses. one for Javascript and one for PHP, anyways I'm not sure how to tackle this problem. On my site, if you click the Sign-Up link, the nav slides out a sign up form. the problem is if the input has an error like it's blank or something it closes the nav automatically instead of just displaying the error. so I have to click Signup again to see the error. I can't make the nav stay open. So I found a possible solution to my problem called
preventDefault(); which makes the form not reload the page finally, but it now it does not submit the data and display error messages now. My site is a WordPress site if that makes a difference. All my google answers I've looked at say preventDefault(); is the answer but if you look at this from w3schools.com.
The preventDefault() method cancels the event if it is cancelable, meaning that the default action that belongs to the event will not occur.
For example, this can be useful when:
Clicking on a "Submit" button, prevent it from submitting a form
so I'm very confused about how this function can fix my problem.
here's my code
HTML / PHP
<?php
global $wpdb, $user_ID;
//Check whether the user is already logged in
if ( !$user_ID ) {
// Default page shows register form.
// To show Login form set query variable action=login
$action = ( isset( $_GET[ 'action' ] ) ) ? $_GET[ 'action' ] : 0;
// Login Page
if ( $action === "login" ) {
?>
<?php
$login = ( isset( $_GET[ 'login' ] ) ) ? $_GET[ 'login' ] : 0;
if ( $login === "failed" ) {
echo '<div class="col-12 register-error"><strong>ERROR:</strong> Invalid username and/or password.</div>';
} elseif ( $login === "empty" ) {
echo '<div class="col-12 register-error"><strong>ERROR:</strong> Username and/or Password is empty.</div>';
} elseif ( $login === "false" ) {
echo '<div class="col-12 register-error"><strong>ERROR:</strong> You are logged out.</div>';
}
?>
<div class="col-md-5">
<?php
$args = array(
'redirect' => home_url(),
);
wp_login_form( $args );
?>
<p class="text-center"><a class="mr-2" href="<?php echo wp_registration_url(); ?>">Register Now</a> <span clas="mx-2">·</span><a class="ml-2" href="<?php echo wp_lostpassword_url( ); ?>" title="Lost Password">Lost Password?</a></p>
</div>
<?php
} else { // Register Page ?>
<?php
if ( $_POST ) {
$error = 0;
$username = esc_sql( $_REQUEST[ 'username' ] );
if ( empty( $username ) ) {
echo '<div class="col-12 register-error">User name should not be empty.</div>';
$error = 1;
}
$email = esc_sql( $_REQUEST[ 'email' ] );
if ( !preg_match( "/^[_a-z0-9-]+(\.[_a-z0-9-]+)*#[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,4})$/", $email ) ) {
echo '<div class="col-12 register-error">Please enter a valid email.</div>';
$error = 1;
}
if ( $error == 0 ) {
$random_password = wp_generate_password( 12, false );
$status = wp_create_user( $username, $random_password, $email );
if ( is_wp_error( $status ) ) {
echo '<div class="col-12 register-error">Username already exists. Please try another one.</div>';
} else {
$from = get_option( 'admin_email' );
$headers = 'From: ' . $from . "\r\n";
$subject = "Registration successful";
$message = "Registration successful.\nYour login details\nUsername: $username\nPassword: $random_password";
// Email password and other details to the user
wp_mail( $email, $subject, $message, $headers );
echo "Please check your email for login details.";
$error = 2; // We will check for this variable before showing the sign up form.
}
}
}
if ( $error != 2 ) {
?>
<?php if(get_option('users_can_register')) { ?>
<div class="col-md-5 manual-register-form">
<form id="sign-up" action="index.php" method="post">
<p>
<label for="user_login">Username</label>
<input type="text" name="username" class="register-input mb-4" value="<?php if( ! empty($username) ) echo $username; ?>" />
<br />
</p>
<p>
<label for="user_email">Email</label>
<br>
<input type="text" name="email" class="register-input mb-4" value="<?php if( ! empty($email) ) echo $email; ?>" />
<br>
</p>
<input type="submit" id="register-submit-btn" class="mb-4" name="submit" value="Sign Up" />
</form>
<p>Already have an account? Login</p>
</div>
<?php
} else {
echo "Registration is currently disabled. Please try again later.";
}
}
?>
<?php
}
} else {
?>
<p>You are logged in. Click here to go home</p>
<?php } ?>
JQuery
var frm = jQuery('#sign-up');
frm.submit(function (ev) {
jQuery.ajax({
type: frm.attr('method'),
url: frm.attr('action'),
data: frm.serialize(),
success: function (data) {
alert('ok');
}
});
ev.preventDefault();
});
functions.php
function hideout_scripts() {
wp_enqueue_script( 'sign-up', get_template_directory_uri() . '/js/login-signup-jquery.js', array('jquery'), '1.0.0', true );
}
add_action( 'wp_enqueue_scripts', 'hideout_scripts' );
The Event.preventDefault() could work if you would first check your fields on the frontend and / or use AJAX to send the fields to the backend. Now there are multiple options to consider.
Required input fields
HTML5 <input> elements already have some built in validation. With the right attributes they can stop a user from submitting a form if they have they don't meet the requirements for submitting.
Adding a required attribute will let the browser know that this field has to be filled in mandatorily. In combination with a pattern attribute you could add complexity to the requirement, like omitting specific symbols or requiring only alphanumeric characters.
The type attribute can also help here. For example, you have an email field. With the type="email" attribute you can tell the browser that this needs to be a valid email.
<form id="sign-up" action="index.php" method="post">
<label for="user-name">Username</label>
<input id="user-name" type="text" name="username" required/>
<label for="user-email">Email</label>
<input id="user-email" type="email" name="email" required/>
<input type="submit" name="submit" value="Sign Up" />
</form>
Though, inputs can be manipulated by the user by inspecting the element. So don't rely solely on the validity of these attributes.
Check all available input types here.
JavaScript Validation
Like validating in PHP you can also validate in JavaScript, or a combination of both, but we'll get to that later on.
Some of the logic, like checking the username and email fields can be transported over to JavaScript. This is similar to the method above with the attributes but is safer to use because you are in full control, nobody can mess with this behavior.
You will have to check each individual field if they are valid and manually add a message if they don't.
var $form = $('#sign-up');
var regex = /^[_a-z0-9-]+(\.[_a-z0-9-]+)*#[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,4})$/g;
var error = {
emptyUserName: 'User name should not be empty.',
invalidEmail: 'Please enter a valid email.',
}
// Listen for the submit event.
$form.on('submit', function(event) {
// Create a flag to check form validity with.
var isValidForm = true;
// Select the input fields.
var $userName = $('#user-name');
var $userEmail = $('#user-email');
// Check the user name for empty string.
if ($userName.val() === '') {
console.log(error.emptyUserName);
isValidForm = false;
}
// Check the email for a valid email with the regex.
if (!regex.test($userEmail.val())) {
console.log(error.invalidEmail);
isValidForm = false;
}
// If the form is not completely valid, stop.
// Otherwise, do nothing and let the form submit.
if (!isValidForm) {
event.preventDefault();
return;
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form id="sign-up" action="index.php" method="post">
<label for="user-name">Username</label>
<input id="user-name" type="text" name="username"/>
<label for="user-email">Email</label>
<input id="user-email" type="email" name="email"/>
<input type="submit" name="submit" value="Sign Up" />
</form>
The only problem here is checking doing backend checks, like the if the user already exists. You were on the right path by using AJAX to do that, but it needs to be improved.
AJAX Request
So first thing is that you'll need a way to communicate with the backend. You can do that by sending to the admin-ajax.php file. From there you can specify what you want to do with the received data.
First modify your functions.php so that it will output the URL for the AJAX request. We can do that by outputting it as JSON inside an inline script tag so that the URL is available in JavaScript.
// This will create a JSON string with the AJAX url in it.
$wp_data = json_encode( array(
'ajax' => admin_url( 'admin-ajax.php' ),
) );
function hideout_scripts() {
wp_register_script( 'sign-up', get_template_directory_uri() . '/js/login-signup-jquery.js', array( 'jquery' ), '1.0.0', true );
// That JSON string will be put in an inline script tag before the main script.
// This means that we can use the URL in our main script for an AJAX request.
// The ugly __wp__ name is to ensure that this property will not be overwritten, ever by another script, and therefor breaking our code.
wp_add_inline_script( 'sign-up', "window.__wp__ = {$wp_data}", 'before' );
wp_enqueue_script( 'sign-up' );
}
add_action( 'wp_enqueue_scripts', 'hideout_scripts' );
Now the admin-url.php URL is available in our form validation script. We'll stay in the functions.php and add a hook to which we will be able to communicate to when we want to send a request. Something like an endpoint.
function sign_up_ajax() {
$user_name = isset( $_POST[ 'username' ] ) ? $_POST[ 'username' ] : '';
$user_email = isset( $_POS[ 'email' ] ) ? $_POST[ 'email' ] : '';
// Write your validation and checks here.
echo 'Everything is okay';
die();
}
add_action( 'wp_ajax_nopriv_sign_up_ajax', 'sign_up_ajax') ;
add_action( 'wp_ajax_sign_up_ajax', 'sign_up_ajax') ;
So what I did here is use the wp_ajax_nopriv and wp_ajax hooks to register a sign_up_ajax action endpoint. Whenever we call a HTTP request to the admin-url.php endpoint with an action=sign_up_ajax value it will know that we want to call the sign_up_ajax function.
Now for JavaScript. You already had a large part of the AJAX request. All you have to do it set the URL to the admin-ajax.php file, which is stored in window.__wp__.ajax and add a ?action=sign_up_ajax string after it so the endpoint knows what function to call.
var $form = $('#sign-up');
var regex = /^[_a-z0-9-]+(\.[_a-z0-9-]+)*#[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,4})$/g;
var error = {
emptyUserName: 'User name should not be empty.',
invalidEmail: 'Please enter a valid email.',
}
// Listen for the submit event.
$form.on('submit', function(event) {
// Prevent the submit right away.
event.preventDefault();
// Create a flag to check form validity with.
var isValidForm = true;
// Select the input fields.
var $userName = $('#user-name');
var $userEmail = $('#user-email');
// Check the user name for empty string.
if ($userName.val() === '') {
console.log(error.emptyUserName);
isValidForm = false;
}
// Check the email for a valid email with the regex.
if (!regex.test($userEmail.val())) {
console.log(error.invalidEmail);
isValidForm = false;
}
// If the form is not completely valid, stop.
// Otherwise, do nothing and let the form submit.
if (!isValidForm) {
return;
}
// From here we send a AJAX request. The ajax URL is available
// on the window object in the __wp__ property.
$.ajax({
url: window.__wp__.ajax + '?action=sign_up_ajax',
method: 'POST',
data: $form.serialize(),
success: function(data) {
console.log(data);
// Check your data, and finally submit the form if the data is good. :)
// if (data === 'Everything is okay') {
// $form.submit();
// }
}
})
});
That's the gist of it. Handling forms is no easy feat in WordPress, but I hope that these examples will help you get further.
I'm new to this and I have trouble understanding how all things works.
I have a php/html page and a login form in it. The login submit button executes a php file (let's say check_user.php) in which theoretically it checks the user and password i put in the form in a database. If it finds them I want the php file (check_user.php) to return to the main page the name of the user and his "class" (like supervisor, operator etc) in order to use them for further active change of main page content (like hide/show menus, enable/disbale elements etc). The problem is that the php returns with echo a text as I understand....How can I process this text to be stored in variables (one or more then one) to be usable in the main page? I understand how to pass variables to a php file, but i don't understand how to process the result of the php, except changing the content of an element in the mane page.
Maybe I need a callback function, I need to use JSON....
PS: I want to do this without $_SESSION
my code is here:
main page:
<div id="show2">
<?php
$userErr = $passErr = "";
$user = $pass = "";
if ($_SERVER["REQUEST_METHOD"] == "POST") {
if (empty($_POST["user"])) {
$userErr = "User name is required";
}
else {
$user = test_input($_POST["user"]);
if (!preg_match("/^[a-zA-Z ]*$/",$user)) {
$userErr = "Only letters and white space allowed";
}
}
if (empty($_POST["pass"])) {
$passErr = "Password is required";
}
else {
$pass = test_input($_POST["pass"]);
}
}
function test_input($data) {
$data = trim($data);
$data = stripslashes($data);
$data = htmlspecialchars($data);
return $data;
}
?>
<h2>LOGIN INFORMATION:</h2>
<form method="post" action="check_user.php">
User: <input type="text" name="user" value="<?php echo $user;?>">
<span class="error">* <?php echo $userErr;?></span>
<br><br>
Password: <input type="password" name="pass" value="<?php echo $pass;?>">
<span class="error">* <?php echo $passErr;?></span>
<br><br>
<input type="submit" name="submit" value="Login">
</form>
</div>
check_user.php:
<?php
if ($_POST["user"] == "xxx" And $_POST["pass"] == "yyyy") {
$name = "John Legend"; /*here I assign value from database*/
$class = "Supervisor"; /*here I assign value from database*/
echo .... ; /*here I don't know what to echo. I want to echo $name and $class and use them as variables (not as text) in the main page*/
}
else {
echo "error";
}
?>
the implementation for database is not done, but the example still apply to any value I assign to the variables I want the php to echo
I have a permissions table and I want the ability to check each multiple boxes and a modal window opens with the input fields to edit the permission name. Once I submit I want to update the database with the new names of each input.
Here is what I have so far...
For each box checked I out put this in the modal:
<div class="form-group">
<label>Permission Name</label>
<input class="del-'+row.id+' form-control" id="name['+row.name+']" type="text" name="name['+row.id+']" value="'+row.name+'" >
<input class="del-'+row.id+' form-control" id="id['+row.name+']" type="hidden" name="id['+row.id+']" value="'+row.id+'" >
</div>
Here is what the JS code looks like for the above:
$("#editModalForm").append('<div class="form-group"><label>Permission Name</label><input class="del-'+row.id+' form-control" id="name['+row.name+']" type="text" name="name['+row.id+']" value="'+row.name+'" ><input class="del-'+row.id+' form-control" id="id['+row.name+']" type="hidden" name="id['+row.id+']" value="'+row.id+'" ></div>');
Here is the PHP code when I submit the form:
//Update permission level names
$permissionId = $_POST['id'];
if($permissionDetails['name'] != $_POST['name']) {
$permission = trim($_POST['name']);
$previousName = $permissionDetails['name'];
//Validate new name
if (permissionNameExists($permission)) {
$errors[] = lang("ACCOUNT_PERMISSIONNAME_IN_USE", array($permission));
} elseif (minMaxRange(1, 50, $permission)) {
$errors[] = lang("ACCOUNT_PERMISSION_CHAR_LIMIT", array(1, 50));
} else {
if (updatePermissionNames($permissionId, $permission)) {
$successes[] = lang("PERMISSION_NAME_UPDATE", array($previousName, $permission));
} else {
$errors[] = lang("SQL_ERROR");
}
}
}
Here is the function that updates the database:
//Change a multiple permission level names
function updatePermissionNames($id, $name) {
global $mysqli,$db_table_prefix;
$i = 0;
$stmt = $mysqli->prepare("UPDATE ".$db_table_prefix."permissions
SET name = ?
WHERE
id = ?
LIMIT 1");
foreach($id as $ids) {
$stmt->bind_param("si", $name, $ids);
$result = $stmt->execute();
}
$stmt->close();
return $result;
}
I am not really sure what I am doing wrong here so I am hoping someone can help me out. If you have any examples that would be great. Again, I want to know how I can update each value?
if you want to get value of input with name="id['+row.id+']"
you should do use
$arrID = $_POST['id']
foreach($arrID as $key => $value){
echo $key;
echo $value;
}
because input id[1] is array when post to server, itn't string.
I'm trying to validate my form with php upon pressing submit and I want the following :
User press submit, if no errors are found, the registration form is processed and data is sent to database.
If errors are present, the page doesn't refresh and the error console appears.
Every time the user clicks submit, if errors are found the old messages are deleted & new messages posted in the error console div.
I wrote all the code for the form , validation(php) , Error console div & CSS . I just have no idea how to integrate them together
something like:
if ( ($username && $email) != 0 ) { error console + remain on same page } else {send to db};
(source: 1.ii.gl)
PHP VALIDATION CODE
$username = 0;
$uservar = $_POST['username'];
if (empty($uservar))
{
$username = 1;
}
else if (!preg_match("/^\w{5,20}$/",$uservar))
{
$username = 2;
}
if ( ($username) != 0 ) {
echo "<h4 class='error2'><img src='http://s28.postimg.org/ql0x06555/warning6.png' alt='Error'> Error Console</h4> </br>";
switch ($username) {
case 1:
echo "<img src='http://s27.postimg.org/vjxntq073/sign5.png' alt='Error'>";
echo " The Field 'Username' cannot be left blank";
break;
case 2:
echo "<img src='http://s27.postimg.org/vjxntq073/sign5.png' alt='Error'>";
echo " Invalid 'Username' Format - Please use Letters & Numbers only (5-20 Characters)";
break;
}}
</div>
FORM:
<form id="registration-form" action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post">
<input type="text" name="username" id="username" placeholder="Username">
<button type="submit" name="submit" id="submit" class="button-submit">Submit</button>
</form>
split your main php from your html
php in your html only handle simple logical and display result
As a quick answer, please check code below:
<?php
function valiation(){
$aryMsg = array();
$aryExport = array();
if( !isset( $_POST['_submit'] ) ){
//no submit
return array( $aryMsg, $aryExport );
}
$aryPostFieldWhiteList = array( 'username' );
//1. post content filter
//make sure pass all the field you need from $_POST to $aryExport
foreach( $aryPostFieldWhiteList as $strField ){
$aryExport[$strField] = htmlentities( $_POST[$strField], ENT_QUOTES );
}
//2. post content filter
//...
//if username is wrong fill $aryMsg['username'] ... etc
//3. check validation result
if( sizeof($aryMsg) ){
//means not pass the validation, return error message and filtered data
return array( $aryMsg, $aryExport );
}
//4. past validation
//4.1 all db, to insert result
//db insert ...etc
//4.2 page redirect to thank you page
header( 'Location: /thankyou.php' );
die();
}
list( $aryMsg, $aryPost ) = valiation();
?>
<html>
<head>
...
</head>
<body>
<?php if( is_array( $aryMsg ) && sizeof( $aryMsg ) ):?>
<h4 class='error2'><img src='http://s28.postimg.org/ql0x06555/warning6.png' alt='Error'> Error Console</h4>
<ul class="error_msg">
<?php foreach( $aryMsg as $strMsg ):?>
<li><?php echo $strMsg;?></li>
<?php endforeach;?>
</ul>
<?php endif;?>
<form id="registration-form" action="" method="post">
<input type="text" name="username" id="username" placeholder="Username" value="<?php echo $aryPost['username'];?>">
<button type="submit" name="_submit" id="submit" class="button-submit">Submit</button>
</form>
</body>
</html>