Simple AJAX code not being recognized - php

I'm trying to begin learning AJAX, and I've already hit a little stump. So I'm starting simple and just trying to get an alert to pop up showing the length of the string the user types into a text field.
The HTML:
<form action="/scripts/addemail_fb.php" method="post">
<input type="text" name="email" value="Enter your email here!" />
<input id="submit" type="submit" name="submit" value="Go!" onClick="check(this.form.email.value);"/>
</form>
The JS:
function check(email) {
if (window.XMLHttpRequest) {
req = new XMLHttpRequest();
}
else if (window.ActiveXObject) {
req = new ActiveXObject("Microsoft.XMLHTTP");
}
email=encodeURIComponent(email);
req.open("POST","/scripts/addemail.php");
req.setRequestHeader(
'Content-Type',
'application/x-www-form-urlencoded; charset=UTF-8');
req.send(email);
req.onreadystatechange=function() {
if(req.readyState==4) {
result = req.responseText;
alert("The length of the email is:" + result);
}
}
return false;
}
The PHP (addemail.php):
<?php
function check_email($input) {
return strlen($input);
}
$email = urldecode(implode(file('php://input')));
$result = check_email($email);
echo $result;
?>
And yes, I've included the JS in the section. I got this almost directly from a tutorial so I'm not sure what's going on. My testing browser is Safari, but I've also tried FF. Sorry is this is obvious, as this is my very first AJAX attempt. Thanks!
EDIT: Sorry, the problem is that its just going to the file described in action="addemail_fb" instead of the JS.
-iMaster

Change the onclick handler to onsubmit (on the form), like so:
<form onsubmit="return check(this.email.value);"> ... </form>
Also, set your req.onreadystatechange before calling req.send ()

inline javascript is bad practice. this solution may seem a bit more convoluted but if you implement it into the rest of your scripts then you will find this much more elegant.
JS libraries use similar methods, but if you cant use one then do this instead:
onDomReady(function(){
var oForm = document.getElementById("myform");
addListener(oForm,"submit",function(){
removeListener(oForm,"submit",arguments.callee);
// do stuff here
});
});
// Cross-browser implementation of element.addEventListener()
function addListener(element, type, expression, bubbling)
{
bubbling = bubbling || false;
if(window.addEventListener) { // Standard
element.addEventListener(type, expression, bubbling);
return true;
} else if(window.attachEvent) { // IE
element.attachEvent('on' + type, expression);
return true;
} else return false;
}
// Cross-browser implementation of element.removeEventListener()
function removeListener(element, type, expression, bubbling)
{
bubbling = bubbling || false;
if(window.removeEventListener) { // Standard
element.removeEventListener(type, expression, bubbling);
return true;
} else if(window.detachEvent) { // IE
element.detachEvent('on' + type, expression);
return true;
} else return false;
}
function onDomReady(fn) {
// Mozilla, Opera and webkit nightlies currently support this event
if ( document.addEventListener ) {
// Use the handy event callback
document.addEventListener( "DOMContentLoaded", function(){
document.removeEventListener( "DOMContentLoaded", arguments.callee, false );
fn();
}, false );
// If IE event model is used
} else if ( document.attachEvent ) {
// ensure firing before onload,
// maybe late but safe also for iframes
document.attachEvent("onreadystatechange", function(){
if ( document.readyState === "complete" ) {
document.detachEvent( "onreadystatechange", arguments.callee );
fn();
} else {
setTimeout( arguments.callee, 0 );
return;
}
});
} else {
// A fallback to window.onload, that will always work
addListener(window,"load",fn);
}
}

Here is the problem:
You are doing it wrong.
And jQuery is the Answer.
But seriously. Try using jQuery, as it will make you Javascript life easier than cutting into a piece of pumpkin pie.
AJAX is one of the most annoying subjects in Javascript, and jQuery, along with other libraries have gone and made the problem much easier to deal with. Plus, there are many many other great features of jQuery that just make it so much more wonderful to work with Javascript.
In jQuery, the entire code would look like:
$.post("/scripts/addemail.php", {email_address:email}, function(data){
alert("The length of the email is:"+data);
});
Speaking of pumpkin pie.....
Now that I've finished my public server announcement for jQuery, you will want to check the Javascript console (Ctrl + Shift + J in Firefox), and run the page. It will give you any errors that you are bound to have such as syntax errors or various other things that go wrong.
If you can go there and then give us any error messages that pop-up, we will be more likely to be able to solve your problem.

Related

If Safari does not support the require attribute for inputs, how can I require a few specific inputs in my form? [duplicate]

I have tried following code for make the required field to notify the required field but its not working in safari browser.
Code:
<form action="" method="POST">
<input required />Your name:
<br />
<input type="submit" />
</form>
Above the code work in firefox. http://jsfiddle.net/X8UXQ/179/
Can you let me know the javascript code or any workarround? am new in javascript
Thanks
Safari, up to version 10.1 from Mar 26, 2017, doesn't support this attribute, you need to use JavaScript.
This page contains a hacky solution, that should add the desired functionality: http://www.html5rocks.com/en/tutorials/forms/constraintvalidation/#toc-safari
HTML:
<form action="" method="post" id="formID">
<label>Your name: <input required></label><br>
<label>Your age: <input required></label><br>
<input type="submit">
</form>
JavaScript:
var form = document.getElementById('formID'); // form has to have ID: <form id="formID">
form.noValidate = true;
form.addEventListener('submit', function(event) { // listen for form submitting
if (!event.target.checkValidity()) {
event.preventDefault(); // dismiss the default functionality
alert('Please, fill the form'); // error message
}
}, false);
You can replace the alert with some kind of less ugly warning, like show a DIV with error message:
document.getElementById('errorMessageDiv').classList.remove("hidden");
and in CSS:
.hidden {
display: none;
}
and in HTML:
<div id="errorMessageDiv" class="hidden">Please, fill the form.</div>
The only drawback to this approach is it doesn't handle the exact input that needs to be filled. It would require a loop accross all inputs in the form and checking the value (and better, check for "required" attribute presence).
The loop may look like this:
var elems = form.querySelectorAll("input,textarea,select");
for (var i = 0; i < elems.length; i++) {
if (elems[i].required && elems[i].value.length === 0) {
alert('Please, fill the form'); // error message
break; // show error message only once
}
}
If you go with jQuery then below code is much better. Just put this code bottom of the jquery.min.js file and it works for each and every form.
Just put this code on your common .js file and embed after this file jquery.js or jquery.min.js
$("form").submit(function(e) {
var ref = $(this).find("[required]");
$(ref).each(function(){
if ( $(this).val() == '' )
{
alert("Required field should not be blank.");
$(this).focus();
e.preventDefault();
return false;
}
}); return true;
});
This code work with those browser which does not support required (html5) attribute
Have a nice coding day friends.
I had the same problem with Safari and I can only beg you all to take a look at Webshim!
I found the solutions for this question and for this one very very useful, but if you want to "simulate" the native HTML5 input validation for Safari, Webshim saves you a lot of time.
Webshim delivers some "upgrades" for Safari and helps it to handle things like the HMTL5 datepicker or the form validation. It's not just easy to implement but also looks good enough to just use it right away.
Also useful answer on SO for initial set up for webshim here! Copy of the linked post:
At this time, Safari doesn't support the "required" input attribute. http://caniuse.com/#search=required
To use the 'required' attribute on Safari, You can use 'webshim'
1 - Download webshim
2 - Put this code :
<head>
<script src="js/jquery.js"></script>
<script src="js-webshim/minified/polyfiller.js"></script>
<script>
webshim.activeLang('en');
webshims.polyfill('forms');
webshims.cfg.no$Switch = true;
</script>
</head>
I have built a solution on top of #Roni 's one.
It seems Webshim is deprecating as it won't be compatible with jquery 3.0.
It is important to understand that Safari does validate the required attribute. The difference is what it does with it. Instead of blocking the submission and show up an error message tooltip next to the input, it simply let the form flow continues.
That being said, the checkValidity() is implemented in Safari and does returns us false if a required filed is not fulfilled.
So, in order to "fix it" and also show an error message with minimal intervention (no extra Div's for holding error messages) and no extra library (except jQuery, but I am sure it can be done in plain javascript)., I got this little hack using the placeholder to show standard error messages.
$("form").submit(function(e) {
if (!e.target.checkValidity()) {
console.log("I am Safari"); // Safari continues with form regardless of checkValidity being false
e.preventDefault(); // dismiss the default functionality
$('#yourFormId :input:visible[required="required"]').each(function () {
if (!this.validity.valid) {
$(this).focus();
$(this).attr("placeholder", this.validationMessage).addClass('placeholderError');
$(this).val(''); // clear value so it shows error message on Placeholder.
return false;
}
});
return; // its invalid, don't continue with submission
}
e.preventDefault(); // have to add it again as Chrome, Firefox will never see above
}
I found a great blog entry with a solution to this problem. It solves it in a way that I am more comfortable with and gives a better user experience than the other suggestions here. It will change the background color of the fields to denote if the input is valid or not.
CSS:
/* .invalid class prevents CSS from automatically applying */
.invalid input:required:invalid {
background: #BE4C54;
}
.invalid textarea:required:invalid {
background: #BE4C54;
}
.invalid select:required:invalid {
background: #BE4C54;
}
/* Mark valid inputs during .invalid state */
.invalid input:required:valid {
background: #17D654 ;
}
.invalid textarea:required:valid {
background: #17D654 ;
}
.invalid select:required:valid {
background: #17D654 ;
}
JS:
$(function () {
if (hasHtml5Validation()) {
$('.validate-form').submit(function (e) {
if (!this.checkValidity()) {
// Prevent default stops form from firing
e.preventDefault();
$(this).addClass('invalid');
$('#status').html('invalid');
}
else {
$(this).removeClass('invalid');
$('#status').html('submitted');
}
});
}
});
function hasHtml5Validation () {
return typeof document.createElement('input').checkValidity === 'function';
}
Credit: http://blueashes.com/2013/web-development/html5-form-validation-fallback/
(Note: I did extend the CSS from the post to cover textarea and select fields)
I use this solution and works fine
$('#idForm').click(function(e) {
e.preventDefault();
var sendModalForm = true;
$('[required]').each(function() {
if ($(this).val() == '') {
sendModalForm = false;
alert("Required field should not be blank."); // or $('.error-message').show();
}
});
if (sendModalForm) {
$('#idForm').submit();
}
});
The new Safari 10.1 released Mar 26, 2017, now supports the "required" attribute.
http://caniuse.com/#search=required
You can add this event handler to your form:
// Chrome and Firefox will not submit invalid forms
// so this code is for other browsers only (e.g. Safari).
form.addEventListener('submit', function(event) {
if (!event.target.checkValidity()) {
event.preventDefault();
var inputFields = form.querySelectorAll('input');
for (i=0; i < inputFields.length; i++) {
if (!inputFields[i].validity.valid) {
inputFields[i].focus(); // set cursor to first invalid input field
return false;
}
}
}
}, false);
Within each() function I found all DOM element of text input in the old version of PC Safari, I think this code useful for newer versions on MAC using inputobj['prpertyname'] object to get all properties and values:
$('form').find("[required]").each(function(index, inputobj) {
if (inputobj['required'] == true) { // check all required fields within the form
currentValue = $(this).val();
if (currentValue.length == 0) {
// $.each((inputobj), function(input, obj) { alert(input + ' - ' + obj); }); // uncomment this row to alert names and values of DOM object
var currentName = inputobj['placeholder']; // use for alerts
return false // here is an empty input
}
}
});
function customValidate(){
var flag=true;
var fields = $('#frm-add').find('[required]'); //get required field by form_ID
for (var i=0; i< fields.length;i++){
debugger
if ($(fields[i]).val()==''){
flag = false;
$(fields[i]).focus();
}
}
return flag;
}
if (customValidate()){
// do yor work
}

Can i send parameter to php controller using javascript but without jquery or ajax?

well the question is enough explained can it be done.
what I am trying to do is to get data from a popup and onclose I want to send the content I retrieved to a php controller for processing.
But I dont want to use jquery library, because it is creating a conflict for me.
Update
window.onbeforeunload = confirmExit;
function confirmExit()
{
var a = document.getElementsByTagName("div");
for (i = 0; i < a.length; i++) {
if(a[i].className == 'Ymacs-frame-content'){
var b = a[i].getElementsByTagName("div").innerHTML;
//alert(b);
}
}
//Ajax should be here
window.onbeforeunload = reloadOpener;
if (top.opener && !top.opener.closed) {
try {
opener.location.reload(1);
}
catch(e) { }
window.close();
}
}
window.ununload=function() {
reloadOpener();
}
You can just use jquery-less AJAX:
var a = new XMLHttpRequest();
a.open("GET","myscript.php?var=foo&othervar=bar",true);
a.onreadystatechange = function() {
if( this.readyState == 4) {
if( this.status == 200) {
// data sent successfully
// response is in this.responseText
}
else alert("HTTP error "+this.status);
}
};
a.send();
Alternatively, you can create an iframe tag and point it to the right page. You can even create a form and post it to the frame if needed.
You can do it in javascript without using jQuery since that is all jQuery does in the background. You will need to look at the different ways IE does it compared to other browsers though.
Yes, XMLHttpRequest, but you'll need to account for differences in browsers, which jQuery does for you.
I just went through this. The only way to use Javascript to pass info to PHP is by using XMLHttpRequest, or at least if there is another way I did not find it. It has to do with the fact that PHP renders on the server side, and Javascript isn't executed until after it is served to the client...unless you use the XHR which is...AJAX.

Ajax to read PHP

I think I'm getting ahead of myself, but I tried AJAX tutorials to read from a PHP file. The PHP file simply has an echo statement for the time, and I want to pass that to initialize a javascript clock.
But this is my first time trying AJAX and I can't even seem to get it to activate a test alert message.
Here is the code, it's at the bottom of my PHP page after all of the PHP.
<script type='text/javascript'>
function CheckForChange(){
//alert("4 and 4");
//if (4 == 1){
//setInterval("alert('Yup, it is 1')", 5000);
//alert('Now it is changed');
//}
var ajaxReady = new XMLHttpRequest();
ajaxReady.onreadystatechange = function(){
if (ajaxReady.readystate == 4){
//Get the data
//document.getElementById('clocktxt').innerHTML = ajaxReady.responseText;
alert("here");
alert(ajaxReady.responseText);
}
}
ajaxReady.open("GET","ServerTime.php",true);
ajaxReady.send(null);
}
setInterval("CheckForChange()", 7000);
</script>
Can somebody tell me why this isn't working? No idea what I'm doing wrong.
The problem in your code is an uncapitalized letter. (Oops!) You check ajaxReady.readystate; you need to check ajaxReady.readyState.
Because ajaxReady.readystate will always be undefined, your alerts never fire.
Here's your code fixed and working.
As an aside, have you considered using a library to handle the ugliness of cross-browser XHR? jQuery is your friend:
function CheckForChange(){
$.get('ServerTime.php', function(data) {
$('#clocktxt').text(data);
});
}
You should probably have something like:
setInterval(CheckForChange, 7000);
On an unrelated note, it's common naming convension in JavaScript to have function and methods names' first letters not capitalized, and the rest is in camelCase. i.e. checkForChange().
I'm not sure the exact problem with your code; here's what I use -- I'm sure it will work for you. (plus, it works with more browsers)
var xhr = false;
function CheckForChange(){
/* Create xhr, which is the making of the object to request an external file */
if(window.XMLHttpRequest){
xhr = new XMLHttpRequest();
}else{
if(window.ActiveXObject){
try {
xhr = new ActiveXObject("Microsoft.XMLHTTP");
}catch(e){}
}
}
/* End creating xhr */
/* Retrieve external file, and go to a function once its loading state has changed. */
if(xhr){
xhr.onreadystatechange = showContents;
xhr.open("GET", "ServerTime.php", true);
xhr.send(null);
}else{
//XMLHTTPRequest was never created. Can create an alert box if wanted.
}
/* End retrieve external file. */
}
function showContents(){
if(xhr.readyState==4){
if(xhr.status==200){
alert(xhr.responseText);
}else{
//Error. Can create an alert box if wanted.
}
}
}
setInterval(CheckForChange, 7000);

How to call multiple AJAX functions (to PHP) without repeating code

I have a little script which uses AJAX and PHP to display an image. You can see below that if I call the function mom() it looks in the PHP file index.php?i=mom and displays the image I'm looking for.
But I need the javascript to be lighter as I have 30 images and for each one I have to modify and copy the script below. Is there not a simpler way to have the functions be different and still call a different page?
<script type="text/javascript">
function mom()
{
var xmlHttp = getXMLHttp();
xmlHttp.onreadystatechange = function()
{
if(xmlHttp.readyState == 4)
{
HandleResponse(xmlHttp.responseText);
}
}
xmlHttp.open("GET", "index.php?i=mom", true);
xmlHttp.send(null);
}
function HandleResponse(response)
{
document.getElementById('mom').innerHTML = response;
}
</script>
My Trigger is this
<a href="#" onclick='mom();' />Mom</a>
<div id='mom'></div>
You could modify your function so it takes a parameter :
// The function receives the value it should pass to the server
function my_func(param)
{
var xmlHttp = getXMLHttp();
xmlHttp.onreadystatechange = function()
{
if(xmlHttp.readyState == 4)
{
// Pass the received value to the handler
HandleResponse(param, xmlHttp.responseText);
}
}
// Send to the server the value that was passed as a parameter
xmlHttp.open("GET", "index.php?i=" + param, true);
xmlHttp.send(null);
}
And, of course, use that parameter in the second function :
function HandleResponse(param, response)
{
// The handler gets the param too -- and, so, knows where to inject the response
document.getElementById(param).innerHTML = response;
}
And modify your HTML so the function is called with the right parameter :
<!-- for this first call, you'll want the function to work on 'mom' -->
<a href="#" onclick="my_func('mom');" />Mom</a>
<div id='mom'></div>
<!-- for this secondcall, you'll want the function to work on 'blah' -->
<a href="#" onclick="my_func('blah');" />Blah</a>
<div id='blah'></div>
This should work (if I understand correctly)
<script type="text/javascript">
function func(imgName)
{
var xmlHttp = getXMLHttp();
xmlHttp.onreadystatechange = function()
{
if(xmlHttp.readyState == 4)
{
document.getElementById(imgName).innerHTML =
}
}
xmlHttp.open("GET", "index.php?i=mom", true);
xmlHttp.send(null);
}
</script>
MARTIN's solution will work perfectly.
By the way you should use some javascript framework for Ajax handling like jQuery.
It will make your life easy.
If you are having light weight images you preload the images on your page.
I solved this by making an array of in your case xmlHttp and a global variable, so it increments for each request. Then if you repeatedly make calls to the same thing (eg it returns online users, or, whatever) then you can actually resubmit using the same element of the array too.
Added example code:
To convert it to a reoccuring event, make a copy of these 2, and in the got data call, just resubmit using reget
var req_fifo=Array();
var eleID=Array();
var i=0;
function GetAsyncData(myid,url) {
eleID[i]=myid;
if (window.XMLHttpRequest)
{
req_fifo[i] = new XMLHttpRequest();
}
else if (window.ActiveXObject)
{
req_fifo[i] = new ActiveXObject("Microsoft.XMLHTTP");
}
req_fifo[i].abort();
req_fifo[i].onreadystatechange = function(index){ return function() { GotAsyncData(index); }; }(i);
req_fifo[i].open("GET", url, true);
req_fifo[i].send(null);
i++;
}
function GotAsyncData(id) {
if (req_fifo[id].readyState != 4 || req_fifo[id].status != 200) {
return;
}
document.getElementById(eleID[id]).innerHTML=
req_fifo[id].responseText;
req_fifo[id]=null;
eleID[id]=null;
return;
}
function reget(id) {
myid=eleID[id];
url=urlID[id];
req_fifo[id].abort();
req_fifo[id].onreadystatechange = function(index){ return function() { GotAsyncData(index); }; }(id);
req_fifo[id].open("GET", url, true);
req_fifo[id].send(null);
}
The suggestions to parameterize your function are correct and would allow you to avoid repeating code.
the jQuery library is also worth considering. http://jquery.com
If you use jQuery, each ajax call would literally be this easy.
$('#mom').load('/index.php?i=mom');
And you could wrap it up as follows if you'd like, since you say you'll be using it many times (and that you want it done when a link is clicked)
function doAjax(imgForAjax) { $('#'+imgForAjax).load('/index.php&i='+imgForAjax);}
doAjax('mom');
It makes the oft-repeated ajax patterns much simpler, and handles the issues between different browsers just as I presume your getXMLhttp function does.
At the website I linked above you can download the library's single 29kb file so you can use it on your pages with a simple <script src='jquery.min.js'></script> There is also a lot of great documentaiton. jQuery is pretty popular and you'll see it has a lot of questions and stuff on SO. ajax is just one of many things that jQuery library/framework (idk the preferred term) can help with.

I have a problem in AJAX

I have a problem with some of my validation code. Here it is.
function isEmailValid(email) {
if( email == "") {
document.getElementById("emailMsg").innerHTML="<font color=red>Email cannot be empty</font>";
}
else {
var emailRegexStr = /^[a-zA-Z0-9._-]+#[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/;
if (!emailRegexStr.test(email)) {
document.getElementById("emailMsg").innerHTML="<font color=red>Invalid email</font>";
}
else {
xmlhttp = getHTTPObject();
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
document.getElementById("emailMsg").innerHTML = xmlhttp.responseText;
if(xmlhttp.responseText == "<font color=green>Correct !</font>" ) {
return true;
}
else {
return false;
}
}
}
xmlhttp.open("GET","includes/register_function.php?email="+email,true);
xmlhttp.send();
}
}
}
The below part of above code is not working properly.
if (xmlhttp.responseText == "<font color=green>Correct !</font>") {
return true;
}
else {
return false;
}
May be a stupid mistake I am newbie in PHP + AJAX.
here is the related PHP code
if (isset($_GET['email'])) {
$email=$_GET['email'];
if (!isUserExistsByEmail($email)) {
echo "<font color=green>Correct !</font>";
} else {
echo "<font color=red>Email already exisits</font>";
}
}
here is gethttpobject function
function getHTTPObject(){
if (window.ActiveXObject) return new ActiveXObject("Microsoft.XMLHTTP");
else if (window.XMLHttpRequest) return new XMLHttpRequest();
else {
alert("Browser does not support AJAX.");
return null;
}
}
i need to know how to change the getHTTPObject function for synchronous scenario .
Thanks.
You're relying on string-matching an arbitrary string - This is often error prone. Most likely there' a trailing carriage return in the response
Try doing:
alert('[' + xmlhttp.responseText +']');
in place of your if statement.
If the alerted value is not exactly
[<font color=green>Correct !</font>]
then you've got a problem. I suspect you'll get:
[<font color=green>Correct !</font>
]
or similar - in which case you need to modify your if statement as appropriate.
A better and less fragile approach would be something like this:
if(xmlhttp.responseText.indexof("Correct")>=0) {
return true;
} else {
return true;
}
or even better just do:
return (xmlhttp.responseText.indexof("Correct")>=0);
Are you expecting isEmailValid() to return true or false? Because the way it's written it will return nothing. The nested function defined inside isValidEmail() returns true or false but that will get called asynchronously some time after isValidEmail() has finished executing. And it won't be called by by your code. It gets called by the browser so you'll likely never have a chance to examine the return value to check if it's true or false.
One way to change your code to accomplish the goal of having isValidEmail() return true or false is to make the XMLHttpRequest call synchronous, rather than asynchronous (SJAX instead of AJAX). That way isValidEmail() will block until it receives a response back from the server (or times out). Of course your user will be unable to do anything on the page while they wait for their email address to be validated. This may or may not be acceptable.
Also, as others have pointed out, your regular expressions and string matching may need a little tweaking but judging by the question, that's not specifically what you're asking about.
I would suggest using a better stuffs in both PHP and javascript. Like, the PHP script could output the result in XML or JSON. And the Javascript, on the client side would parse the string according the format.
I suggest you have a look at the following links:
For JSON (I personally prefer JSON to XML, and some ways JSON is much better than XML)
http://www.json.org/example.html
http://www.php.net/manual/en/function.json-encode.php
For XML, simply google, I am sure you will get many results.
Eg:
in PHP:
$obj['result'] = 1;
$obj['color'] = 'green';
echo json_encode($obj);
in Javascript:
try{
var result = JSON.parse(xmlhttp.responseText);
}catch(err){
alert("...");
}

Categories