AJAX Request with PHP - php

I'm working on ajax for the first time and I feel like I'm close to solving this problem but I need some help. I have my webpage file first below, that has an input field for an email address. When the user submits, the ajax doWork() function should be called which creates the request and processes the request. I have fixed the initial issue of the request being created so I'm positive that the correct object has been created based on the browser. My issue is there's no response text being submitted back and no email is created. The goal is for the user to enter the email, then an introductory email sent back to that address, when this is successful, a response string should be submitted back letting the user know that they have successfully been added to the mailing list and the submission has worked. Thanks for any help, it is greatly appreciated.
<?php include('../includes/educateHeader.php');?>
<script type="text/javascript" charset="utf-8" src="ajax.js"></script>
<div class="involve">
<h1>How to Get Involved In OEC</h1>
<span>Want to become more involved in Operation:Educate Children and don't know how? Share your email address with us, like our facebook page, or check out blog out to learn more about how you can join and help children obtain the education they deserve</span><br></br>
<form method="get">
Email: <input type="email" name="email" id="email" required><br></br>
<input type="submit" value="Send" onclick="doWork()">
</form>
</div>
<div id="outputResponse">
</div>
<?php include('../includes/educateFooter.php');?>
So here is the ajax.js file that creates the request and prints out the data recieved from the email.php file
function getHTTPObject() {
if (window.ActiveXObject) {
return new ActiveXObject("Microsoft.XMLHTTP");
}
else if (window.XMLHttpRequest) {
return new XMLHttpRequest();
}
else {
alert("Your browser does not support AJAX.");
return null;
}
}
function setOutput() {
if (httpObject.readyState == 4 && httpObject.status == 200) {
document.getElementById('outputResponse').value = httpObject.responseText;
}
}
function doWork() {
httpObject = getHTTPObject();
if (httpObject != null) {
httpObject.open("GET", "email.php?email=" + document.getElementById('email').value, true);
httpObject.send(null);
httpObject.onreadystatechange = setOutput;
}
}
var httpObject = null;
Lastly here is the email.php script which should accept the ajax request and echo back whether a success has occurred or not.
<?php
if (isset($_GET['email'])) {
$mail = trim($_GET['email']);
$subject = 'Welcome!';
$message = 'Thank you for joining the Operation:Educate Children email list. In the future, we will send you updates about new opportunities to become more involved in the activities that we run here at OEC and you could make a difference on children\'s futures. Thank you and best wishes!';
mail($mail, $subject, $message);
echo 'Success! Thank you for your interest in Operaton:Educate Children. Stay tuned for updates!';
}
?>

First add return false; at the end of your function doWork and change onclick="doWork()" to onclick="return doWork()"
Then also change below line
document.getElementById('outputResponse').value = httpObject.responseText;
to
document.getElementById('outputResponse').innerHTML = httpObject.responseText;
Read this question too :) Setting innerHTML vs. setting value with Javascript

JQuery makes this really easy:
$.ajax({
url:'email.php',
type: "POST",
data: 'email='+$('input[name=email]').val(),
success:function(html) {
$('#mydiv').html(html);
}
});
Or for GET, even easier:
$.ajax({
url:'email.php?email='+$('input[name=email]').val(),
success:function(html) {
$('#mydiv').html(html);
}
});

Related

How to access name and value pair of <button type="submit"> with php using Fetch API?

I need the name and value of a button (Not an input type = submit) when a form is submitted with the button of type submit.
I know everyone always asks why, even though the "why" is not a part of the answer to the question so I will answer the why to save time. I want a form to direct a person to choose to login, register or submit email verification. So having buttons that I can set the label for, with each have a unique value for a given name would solve this need but the name and values are not included in the POST with the rest of the input data when BUTTON type = submit is used.
Given the information in HTML5 Spec as shown on this site https://www.htmlquick.com/reference/tags/button-submit.html it seems like it's supposed to work. But short of adding javascript to manually add the key value pair to the post on click it doesn't seem to work.
Now, I want to ask why? If only inputs can be added to the data list then why isn't there an option to change the label of the submit inputs?
*EDIT
So far everyone agrees that what I've done should work, so lets get to the specific case and see if we can find where the problem is then.
Using this form:
<form data-targetblock="accountBlock" class="fetchForm" action="<?=ADDRESS ?>/MAINhubs/accountBlockHub.php" method="post">
<fieldset>
<legend>Member Login</legend>
<input type="hidden" name="formTarget1" value="test">
<button type="submit" name="formTarget" value="login">Log In</button>
<button type="submit" name="formTarget" value="register">Register</button>
<button type="submit" name="formTarget" value="verify">Verify Your Email</button>
</fieldset>
</form>
Sent with this:
function addFetch(event, targetBlock, domain)
{
event.preventDefault();
const form = new FormData(event.target);
const request = new Request(event.target.action,
{
method: event.target.method,
body: form,
mode: 'same-origin',
credentials: 'same-origin'
});
fetch(request)
.then(response => {
if(response.ok)
{
return response.text();
}
else
{
document.getElementById(targetBlock).innerHTML = 'ERROR! ERROR! There has been an ERROR!'
}
})
.then(function(text){document.getElementById(targetBlock).innerHTML = text;})
.catch(error => console.log('There was an error:', error))
}
Going to this:
<?php
session_start();
if ($_SERVER['REQUEST_METHOD'] === "POST")
{
var_dump($_POST);
}
?>
Gets me this when I click Log In:
formTarget1 = test
I'm gonna guess it has to do with this line in the Fetch:
const form = new FormData(event.target);
To answer the question of how the function is called, this JS is run to add the function to all applicable forms:
function fetchFormCallback(mutations)
{
mutations.forEach(function(mutation)
{
for (const thisForm of Array.from(document.getElementsByClassName('fetchForm')))
{
addFormListener(thisForm, thisForm.dataset.targetblock)
}
});
}
function generalCallback(mutations)
{
mutations.forEach(function(mutation)
{
// Take alertBlocks and move them to bottom of ID outerFrame because of IOS bug
if (newAlertBlock = document.getElementById('alertMessageBlock'))
{
if (newAlertBlock.dataset.relocated !== 'true')
{
var destinationBlock = document.getElementById('outerFrame');
destinationBlock.appendChild(newAlertBlock);
newAlertBlock.dataset.relocated = 'true';
}
}
// Get getElementsByClassName closeButton
for (var closeButton of Array.from(document.getElementsByClassName('closeButton')))
{
if (closeButton.dataset.closeButton !== 'true')
{
closeButton.dataset.closeButton = 'true';
closeButton.addEventListener('click', function(){this.parentNode.parentNode.removeChild(this.parentNode);});
}
}
// Potentially auto close based on a closeButton class of AUTO
});
}
document.addEventListener("DOMContentLoaded", function()
{
var config = {childList: true};
for (const thisForm of Array.from(document.getElementsByClassName('fetchForm')))
{ // setup all fetchforms
addFormListener(thisForm, thisForm.dataset.targetblock);
var thisTargetBlock = document.getElementById(thisForm.dataset.targetblock);
// if notset dataset.mutationobserver OR
if (thisTargetBlock.dataset.mutationobserver !== 'true')
{
thisTargetBlock.dataset.mutationobserver = 'true';
var observer = new MutationObserver(fetchFormCallback);
observer.observe(thisTargetBlock, config);
}
}
config = {childList: true, subtree: true};
var generalObserver = new MutationObserver(generalCallback);
generalObserver.observe(document, config);
});
function addFormListener(form, targetBlock)
{ // first check if element has attribute set for eventListeners
if (form.dataset.submitlistener !== 'true')
{
form.dataset.submitlistener = 'true';
form.addEventListener('submit', function()
{
addFetch(event, targetBlock);
});
}
}
EDIT:
We've confirmed that the issue here is that FormData is for some reason not supposed to include the submit value. Why a value should be excluded just because it may not be present/needed in the use case is beyond me. I do have a reason why it should be included and have documented it above. I developed this structure to be as universally applicable as possible without the addition of code for special case uses.
So now my evolving question has become this:
How; using the above functions, can I get the value of the clicked submit button, and include that name value pair in the FormData without changing the fundamental structure of these functions that otherwise do exactly what I want them to do in every other case.
This discussion illustrates that it's possible but has been reworked based on the spec to no longer do exactly what I'm trying to do:
FormData() object does not add submit-type inputs from form, while on Firefox
If I can't access the name and value of the button at the point of submition, then I might as well make another eventlistener to all BUTTON elements in forms that adds a hidden input with it's values on click... Before I go and do that, I can already see hurdles like the event.preventDefault(); line in the addFetch function might prevent the on click from happening? I guess it's back to trial and error unless someone has a better thought.
In your PHP:
$_POST['formTarget'];
Will have the value of the submit button. Either login, register, etc.
However I would not use a form for this, there is no need. I would just simply use links and style them as buttons if you wanted them to look like a button.
Edit: Based on your additions to the post. I offer an alternative way to accomplish this using data attributes.
HTML:
<fieldset>
<legend>Member Login</legend>
<button id="loginButton" data-url="getForm.php" data-target-block="#showForm" data-form-type="login">Log In</button>
<button id="registerButton" data-url="getForm.php" data-target-block="#showForm" data-form-type="register">Register</button>
<button id="verifyButton" data-url="getForm.php" data-target-block="#showForm" data-form-type="verify">Verify Your Email</button>
</fieldset>
<div id="showForm"></div>
<script>
document.querySelector("#loginButton").addEventListener("click", addFetch);
document.querySelector("#registerButton").addEventListener("click", addFetch);
document.querySelector("#verifyButton").addEventListener("click", addFetch);
function addFetch() {
const data = new FormData;
const targetBlock = this.dataset.targetBlock;
for(element in this.dataset) {
data.append(element, this.dataset[element]);
}
const request = new Request(this.dataset.url,
{
method: "POST",
body: data,
mode: 'same-origin',
credentials: 'same-origin',
});
fetch(request).then(response => {
if(response.ok) {
return response.text();
} else {
document.querySelector(targetBlock).innerHTML = 'ERROR! ERROR! There has been an ERROR!'
}
}).then(function(text){document.querySelector(targetBlock).innerHTML = text;})
.catch(error => console.log('There was an error:', error))
}
</script>
PHP:
<?php
if ($_SERVER['REQUEST_METHOD'] === "POST") {
switch($_POST['formType']) {
case 'verify':
echo "verify Form";
break;
case 'register':
echo "Register Form";
break;
case 'login':
echo "Login Form";
break;
default:
echo "Not valid";
break;
}
}

updating page when new message is sent

This is to function in a similar way to slack. I need the page to update dynamically, in case the user is typing.
I have index.php, messages.html and newmessage.php
The chat page (index.php) looks like this:
<h1>Chat</h1>
<?php
echo file_get_contents("./messages.html") ;
?>
<br>
<form action="newmessage.php" method="post">
<input type="text" placeholder= "Compose a new message..." name="message" required>
<input type="submit"><br>
with the php looking like this in newmessage.php:
<?php
$message = $_POST["message"];
$timestamp =date('l jS \of F Y h:i:s A');
$text = "<hr>{$message} <br> from: {$_SERVER['PHP_AUTH_USER']} at: {$timestamp} <br><br> \n";
$file = fopen("./messages.html","a+ \n");
fwrite($file, $text);
fclose($file);
?>
<meta http-equiv="refresh" content="0.5;URL='/chat/index.php'"/>
<p>Sending Message...</p>
So messages show up to the user who sent the message, but not others in the chat. I can't use meta refresh in case other users are typing something and I've tried to make just the <?php echo file_get_contents("./messages.html") ; ?> refresh or use AJAX or event listeners. I need that contents to dynamically update once a new message is posted to messages.html.
Any pointers would be appreciated. Thanks in advance.
update because answer edit was rejected
function reloadData()
{
var now = new Date();
url = 'liveData?' + now.getTime();
try {
req = new XMLHttpRequest();
} catch (e) {
try {
req = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
req = new ActiveXObject("Microsoft.XMLHTTP");
} catch (oc) {
alert("No AJAX Support");
return;
}
}
}
req.onreadystatechange = processReqChange;
req.open("GET", url, true);
req.send(null);
}
function processReqChange()
{
// If req shows "complete"
if (req.readyState == 4)
{
dataDiv = document.getElementById('currentData');
// If "OK"
if (req.status == 200)
{
// Set current data text
dataDiv.innerHTML = req.responseText;
// Start new timer (1 min)
timeoutID = setTimeout('reloadData()', 60000);
}
else
{
// Flag error
dataDiv.innerHTML = '<p>There was a problem retrieving data: ' + req.statusText + '</p>';
}
}
}
The best way to get the dynamic updating you are looking for would be AJAX, because you don't really want a real refresh all the time. You said, you tried AJAX? How did that approach look like?
My hint would be to get a basic understanding of web architecture. Try to understand the JS-code you found and how AJAX works. Did you work with JS before? If not, learn the basics.
Change the url variable to the url you use on your server to return the data. Yes, you will need that. Than look at the callback function (processReqChange()).
I would give you more than just hints, but in your early stage it is better to do a lot alone with some hints by more experienced developers.

Passing data to PHP via Ajax without using a submit button

I've had a look around and unfortunately the solutions I've found on the site don't appear to address my issue below.
Basically I'm doing a project where I need to effectively set up a diary - the user writes in a textarea element and this is passed via PHP to a database and stored for the user. In the lecturer's video, it appears he's doing without using a submit button (even if he's not, I think it'd be an interesting thing to learn how to do).
I'm having some issues though. Here's my PHP:
<?php
session_start();
if(array_key_exists("id", $_COOKIE)) {
$_SESSION['id'] = $_COOKIE['id'];
}
if(array_key_exists("id",$_SESSION)) {
echo "Logged in: <p><a href='secretDiaryFinal2.php?logout=1'>
Log out</a></p>";
} else {
header("Location: secretDiaryFinal2.php");
}
/* I'm putting in the database update later, for now I just wanted to check if I could
actually create the POST variable below*/
$msg = "";
if(array_key_exists('diaryEntry',$_POST)) {
$msg = $_POST['diaryEntry'];
} else {
$msg = "Some kind of PHP error";
}
?>
The relevant HTML:
<body>
<div id="testDiv">
<? echo $msg ?>
</div>
<div class="container" id="diaryArea">
<form method="post">
<textarea id="diary" value=""></textarea>
</form>
</div>
The relevant JQuery (I'm very weak on Ajax and I suspect there's a lot of issues here - also note the url I'm using is actually in the same script as the JQuery, I'm not certain if that works?) is below.
The basic idea is that every time the user types, the database should be updated (I realise this is a lot of calls to the server, I'll probably replace it with a timed command):
<script type="text/javascript">
$("#diary").keyup(function () {
var dataString = $("#diary").val();
$.ajax({
type: "POST",
url: "loggedInPageFinal.php",
data: ({diaryEntry:dataString}),
success: function(data) {
console.log(data);
}
});
return false;
});
</script>
Many thanks in advance and apologies for my poor code!
var DataString = $("#diary").val();
$.post( "loggedInPageFinal.php",{dataString:DataString }, function( data ) {
console.log(data);
});
Your ajax script actually does work.
But your php code isn't returning anything. put exit($msg); at the end of the code and see what happens.

onkeypress Email Validation using ajax js and php

Preface: this will eventually expand to a signup sheet, but I am more concerned with getting one portion completed first.
Now you will not be able to connect to my server, but I do need help, or at least an explanation of why this code isn't working. I have been working on this for a week or so, and have found nothing really similar to my problem.
HTML:
<html>
<head>
<script type="text/javascript" src="checking.js"></script>
</head>
<body>
<span id="conTest">
<?php
$con = mysqli_connect("L28-6","turkey","supersecretpassword","stored");
if (mysqli_connect_errno($con))
{
echo"Failed to connect to MySQL: " . mysqli_connect_error();
} else {
echo "success";
}
?>
</span>
Email: <input type="text" id="email" onkeyup="emailCheck(this.value)"/>
<br/>
<span id="emailError"></span>
</body>
</html>
The main error is somewhere in the js which looks like:
function emailCheck(inputvalue)
{
var pattern=/^([a-zA-Z0-9_.-])+#([a-zA-Z0-9_.-])+\.([a-zA-Z])+([a-zA-Z])+/;
var span=document.getElementById("emailError");
if(pattern.test(inputvalue))
{
span.innerHTML="true..checking";
var myRequest = new XMLHttpRequest();
var response = myRequest.reponseText;
myRequest.onreadystatechange = function()
{
if(myRequest.readyState == 4 && myRequest.status == 200)
{
if(response.test(inputvalue))
{
span.innerHTML="already in use";
}
else
{
span.innerHTML="valid";
}
}
myRequest.open("POST", "email.php", true);
myRequest.send();
}
}
else
{
span.innerHTML="not valid email";
}
}
The problem is definitely with the ajax call but here is the php portion (which isn't in working condition yet):
<?php
mysqli_query($con,"select user_email from email");
?>
I know its a lot of code, but I really appreciate any input.
Also here is the page's response when a properly formed email is used:
Email:asdfasdf#yahoo.com
true..checking
so I know for certain it isn't even dropping into the myRequest.readystatechange function, because if it where it should, at least, return "not valid email".
Your ajax request is inside the readystatechange. This means the ajax request will never be called.
try something like :
function emailCheck(inputvalue)
{
var pattern=/^([a-zA-Z0-9_.-])+#([a-zA-Z0-9_.-])+\.([a-zA-Z])+([a-zA-Z])+/;
var span=document.getElementById("emailError");
if(pattern.test(inputvalue))
{
span.innerHTML="true..checking";
var myRequest = new XMLHttpRequest();
var response = myRequest.reponseText;
myRequest.onreadystatechange = function()
{
if(myRequest.readyState == 4 && myRequest.status == 200)
{
if(response.test(inputvalue))
{
span.innerHTML="already in use";
}
else
{
span.innerHTML="valid";
}
}
}
myRequest.open("POST", "email.php", true);
myRequest.send();
}
else
{
span.innerHTML="not valid email";
}
}
I can see another issue with your code. The email will be valid even before finish to be filled
something#domain.c will be valid even if i need to informe something#domain.com. Use a button to request the validation

AJAX and/or JQUERY form POST?

Hi Masters Of Web Programming,
here I come with another stupid question, hoping someone will answer me. I'm not very good in AJAX programming but due some situations I must build a completely non-refreshable site.
Next question is how to make this form to send a request and return the result, WITHOUT reload of current page?
<?PHP
function mobio_checkcode($servID, $code, $debug=0) {
$res_lines = file("http://www.mobio.bg/code/checkcode.php?servID=$servID&code=$code");
$ret = 0;
if($res_lines) {
if(strstr("PAYBG=OK", $res_lines[0])) {
$ret = 1;
}else{
if($debug)
echo $line."\n";
}
}else{
if($debug)
echo "Unable to connect to mobio.bg server.\n";
$ret = 0;
}
return $ret;
}
$servID = 29;
$code = $_REQUEST["code"];
$ok = $_REQUEST["ok"];
if($ok) {
if(mobio_checkcode($servID, $code, 0) == 1) {
echo "The SMS code is correct!";
}else{
echo "Wrong SMS code.";
}
}else{
?>
<form method="post" name="smscode">
SMS code: <input type="text" size="20" name="code"/>
<input type="submit" name="ok" value=" Submit "/>
</form>
<?PHP } ?>
This form sends request to verify SMS code. It is what providers of this service gave to me. But it's simple php file. I included it to my non-refreshable site but when I press SUBMIT button it refreshes whole current page and then shows the predefined echo.
Instead of submit use simple button and bind ajax event to it. Here's the rough example.
$(document).ready(function(){
$("#btnId").click(function(){
$.ajax({
type: "GET",
url: "test.js",
dataType: "script"
});
});
});
This helped me a lot when i started doing some ajaxing:
http://net.tutsplus.com/tutorials/javascript-ajax/5-ways-to-make-ajax-calls-with-jquery/
Sounds like you need the jquery form plugin.
it will get you the behavior you are describing.
$(document).ready(function() {
var options = {
// other options left out
success: showResponse // post-submit callback
};
$('#myForm1').ajaxForm(options);
});
// post-submit callback
function showResponse(responseText, statusText) {
alert('response: ' + responseText);
}
All solutions are not working in my case. Either they don't POST to server or I can't make them show the reply from server, which as you might see is inside the same file
if($ok) {
if(mobio_checkcode($servID, $code, 0) == 1) {
echo "The SMS code is correct!";
}else{
echo "Wrong SMS code.";
}
So in this situation can anyone tell me how to reload only the div that contains this file included in it, on SUBMIT button click?
Or any other solution will be welcome...

Categories