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...
Related
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;
}
}
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.
I am making an ajax call in a file called level1_1.php that posts to validate1_1.php (attached below). However, what happens is that the user gets redirected to validate1_1.php which simply prints to the screen the string (either "CORRECT", "INCORRECT", or "NOLIVES") that I want to be passed into the callback function that makes up the third parameter of my $.post call. How do I return back to level1_1.php from validate1_1.php??
level1_1.php:
session_start();
<h5>Type answer here: </h5>
<form>
<textarea rows="10" cols="50" name="userinput"></textarea>
<span> <?php echo $msg;?></span>
<br>
<input id="submit" type="submit" name="Submit">
</form>
<script>
$("#submit").click(function(){
$.post("validate1_1.php",
{
userinput: $("#userinput").val;
},
function(data){
if (data == "CORRECT")
{
alert("Good job! Get ready for the next level!");
// take user to next level
window.location.replace("game.php");
}
else if (data == "INCORRECT")
{
alert("Sorry, that is incorrect. You have lost a life.");
}
else
{
// redirect user to game over screen
window.location.replace("gameover.php");
}
});
});
</script>
validate1_1.php:
<?php
session_start();
$msg = "";
$userinput = preg_replace('/\s+/', '', $_POST["userinput"]);
// if incorrect, lose life
if (strcasecmp($userinput, $_SESSION["ptext"]) != 0)
{
$_SESSION["lives"]--;
$msg = "INCORRECT";
// if no more lives, game over!
if ($_SESSION["lives"] == 0)
{
$msg = "NOLIVES";
}
}
// otherwise, move on to next level
else
{
$msg = "CORRECT";
}
echo $msg;
?>
change the below line
userinput: $("#userinput").val;
to
userinput: $("#userinput").val();
Here are some fixes. If you still have problems, use your browser's debugging tools to help.
$("#submit").click(function(e){
// 1. prevent your submit button from submitting the form
e.preventDefault();
$.post("validate1_1.php",
{
// 2. you're using 'name' attribute not 'id' attribute
// 3. val() not val
userinput: $("[name=userinput]").val();
},
function(data){
if (data == "CORRECT")
{
alert("Good job! Get ready for the next level!");
// take user to next level
window.location.replace("game.php");
}
else if (data == "INCORRECT")
{
alert("Sorry, that is incorrect. You have lost a life.");
}
else
{
// redirect user to game over screen
window.location.replace("gameover.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);
}
});
In this basic jQuery, AJAX, PHP form I want to display errors next to inputs instead of the bottom of the form. I use if(empty(something)) { jQuery here }. Why won't this work? Whats the best practice to do this? Thank you.
HTML:
Name:<input type="text" id="name" /> <span id="name_error"></span>
<input type="button" value="Update!" id="update" /> <span id="name_error"></span>
<span id="update_status"></span>
PHP
<?php
include('init.inc.php');
if(isset($_POST['name'])) {
$name = mysql_real_escape_string(htmlentities($_POST['name']));
if(empty($name)) {
?>
// Why wont this work here? It just outputs the the whole thing as text. in the update_status div (You can see that in the ajax part at the bottom of the code).
<script>
$('#name_error').text('Name required');
</script>
<?php
if(!empty($name)) {
$query = mysql_query("UPDATE users SET
name = '$name'
WHERE user_id = ".$_SESSION['user_id']."
");
if($query === true) {
echo 'Your settings have been saved';
} else if($query === false) {
echo 'Unable to save your settings';
}
}
}
// This is the jQuery / AJAX part -- no issues here. Just have it to include both parts.
$('#update').click(function() {
var name = $('#name').val();
$('#update_status').text('Loading...');
$.ajax({
type: 'POST',
url: 'page.php',
data: 'name='+name,
success: function(data) {
$('#update_status').text(data);
}
});
});
CODE UPDATED
Why aren't you checking for empty before the form submit?
You can stop the form submission and check for empty values with javascript, if all is clear then you can submit the form.
You can do this, but you are specifiying .text()
What you need to do is jQuery("#update_status").html(data);
jQuery("#update").click( function(){
if(jQuery.trim(jQuery("#name").val()) == ''){ alert("empty"); return false; }
jQuery.post("page.php", {name:jQuery("#name").val()}, function(html){
jQuery("#update_status").html(html);
});
});
Note that you PHP page is going to return more than just your intended code as it is now. It is going to try and return the form again also.
You need to wrap your processing and from in separate if/else statement. Better to put them in two separate files and keep ajax stuff separate.
That's a really bad way to do it. The reason it doesn't work is because that JavaScript needs to be parsed and run by the browser first, that's a whole different story and would involve using eval(). The better way to do it would be to send back a JSON object, then use it in your JavaScript to display the message to the user.