Encountering an endless loop on an ajax function with no obvious loop - php

I have a file input declared as follows:
<input id = "front_photo" type = "file" name = "front_photo" onchange = "send_photo()" />
The function it calls is declared as follows:
function send_photo ()
{
var fileInput = document.getElementById('front_photo');
var file = fileInput.files[0];
var formData = new FormData();
formData.append('front_photo', file);
console.log("in");
var ajaxHandler = new XMLHttpRequest();
ajaxHandler.onreadystatechange = function ()
{
if(ajaxHandler.readyState == 4)
{
var picture_box = document.getElementById("polaroids_holder");
var adder = document.getElementById("add_polaroid");
var new_pic = document.createElement("div");
new_pic.className = "polaroid";
new_pic.style.backgroundImage = "url('/assets/img/temp_front/"+ajaxHandler.responseText+"')";
picture_box.insertBefore(new_pic, adder);
send_photo();
}
}
ajaxHandler.open('POST', 'upload_polaroid', true);
ajaxHandler.send(formData);
}
Selecting a file to upload once causes it to go into an endless loops. The "in" I have there at the top is piling up in the console log, so I'm sure it's the function itself being called repeatedly and not a server side redirect. Also, the images are being created on the server. Here's the PHP for that:
function upload_polaroid ()
{
if(isset($_FILES['front_photo']))
{
$format = explode(".", $_FILES["front_photo"]["name"]);
$format = $format[1];
$filename = md5(mt_rand().microtime(true)).".".$format;
$allowedTypes = array("image/tiff", "image/gif", "image/jpeg", "image/png", "image/x-bmp", "image/x-ms-bmp", ".bmp", ".dib", "image/vnd.microsoft.icon", "image/x-xbitmap", "image/x-xbm", ".xbm", ".cur");
if(in_array($_FILES["front_photo"]["type"], $allowedTypes))
{
if(file_exists(getcwd()."/assets/img/temp_front/".$filename))
{
chmod(getcwd()."/assets/img/temp_front/".$filename,0755);
unlink(getcwd()."/assets/img/temp_front/".$filename);
}
move_uploaded_file($_FILES["front_photo"]["tmp_name"], getcwd()."/assets/img/temp_front/".$filename);
$image_path = "/assets/img/temp_front/".$filename;
echo $image_path;
}
else
{
echo "File is not of a valid image type."; die;
}
}
else
die; //var_dump($_FILES);
}
What could be going wrong here?

When the ajax request is successful the code calls send_photo(); which fires another ajax request and calls the send_photo(); method again when successful. This is causing the code to be recursive.
function send_photo ()
{
var fileInput = document.getElementById('front_photo');
var file = fileInput.files[0];
var formData = new FormData();
formData.append('front_photo', file);
console.log("in");
var ajaxHandler = new XMLHttpRequest();
ajaxHandler.onreadystatechange = function ()
{
if(ajaxHandler.readyState == 4)
{
var picture_box = document.getElementById("polaroids_holder");
var adder = document.getElementById("add_polaroid");
var new_pic = document.createElement("div");
new_pic.className = "polaroid";
new_pic.style.backgroundImage = "url('/assets/img/temp_front/"+ajaxHandler.responseText+"')";
picture_box.insertBefore(new_pic, adder);
/***********************************************/
send_photo(); //this is making the code recursive
}
}
ajaxHandler.open('POST', 'upload_polaroid', true);
ajaxHandler.send(formData);
}

You're calling the send_photo function right from the ajax callback, after you've shown the success via inserting new_pic in the document. That way, it will forever upload the selected file again and again.

Related

Is it possible to add Jquery mobile loader on XMLHttpRequest() request?

function uploadFile() {
var fd = new FormData();
var count = document.getElementById('image').files.length;
for (var index = 0; index < count; index ++)
{
var file = document.getElementById('image').files[index];
fd.append('myFile', file);
}
var xhr = new XMLHttpRequest();
xhr.addEventListener("progress", updateProgress, false);
xhr.addEventListener("load", uploadComplete, false);
xhr.addEventListener("error", uploadFailed, false);
xhr.open("POST", "savetofile.php", false);
xhr.send(fd);
}
function updateProgress(evt) {
/* This event is raised when the server send back a response */
$.mobile.showPageLoadingMsg();
}
function uploadComplete(evt) {
/* This event is raised when the server send back a response */
alert(evt.target.responseText);
$.mobile.hidePageLoadingMsg()
}
function uploadFailed(evt) {
alert("There was an error attempting to upload the file.");
}
I am using Jquert mobile framework and in this XMLHttpRequest I am uploading a file to the server and it takes around 5-6 seconds to complete.I have read that to add and remove the page load(spinner) for jquery mobile just add $.mobile.showPageLoadingMsg() [to load] and $.mobile.hidePageLoadingMsg()[to remove]. Have I placed the function in the wrong positions? or did I make some other mistake ?
Found on solution
function uploadFile() {
//ad this code
$.mobile.loading('show', {
theme: "a",
text: "yoo",
textonly: true,
textVisible: true
});
//end
var fd = new FormData();
var count = document.getElementById('image').files.length;
for (var index = 0; index < count; index ++)
{
var file = document.getElementById('image').files[index];
fd.append('myFile', file);
}

Passing a image size variable using Javascript to a PHP page

I am trying to send a canvas drawing to the server using javscript.
Having a function such as :
function uploadPic() {
var imgData = document.getElementById("myCanvas").toDataURL();
window.location = "myPHPfile.php?imageData=" + imgData;
}
What would the best way to pass the imgData variable to the php page due to its large size.
Thanks in advance!
User post request to pass large data. You can use jQuery post method
$.post('myPHPfile.php', { imageData: imgData }, function(data) {
// completed
});
Or create and post form:
function uploadPic() {
var imgData = document.getElementById("myCanvas").toDataURL();
var form = document.createElement('form');
form.method = "POST";
form.action = "myPHPfile.php";
var hidden = document.createElement('input');
hidden.type = 'hidden';
hidden.name = 'imageData';
hidden.value = imgData;
form.appendChild(hidden);
document.body.appendChild(form);
form.submit();
}

loading xml from a database to be used in multiple functions

I have a database where i'm using php to randomize the information by ID and send it out via xml. My issue is that I only want to grab the xml once and store it for use in at least 2 functions... one function that runs onload to grab the first line of xml, another that will run every time a button is pressed to access the next line of xml until the end. My 2 functions are loadfirst() and loadnext(). loadfirst() works perfectly, but I'm not sure how to pass the xml data to loadnext(). Right now I'm just using loadfirst() on pageload and loadfirst() on button press, but i end up creating new xml from the database each time which causes randomization issues and is incredibly inefficient. Any help would be appreciated.
var places;
var i = 0;
function loadXML(){
downloadUrl("places.php", function(data){
places = data.responseXML;
getFeatured(i);
});
}
function getFeatured(index){
var id = places[index].getAttribute("id");
var name = places[index].getAttribute("name");
var location = places[index].getAttribute("location");
var imgpath = places[index].getAttribute("imgpath");
var tags = places[index].getAttribute("tags");
}
function getPrev() {
i--;
getFeatured(i);
}
function getNext() {
i++;
getFeatured(i);
}
function downloadUrl(url, callback) {
var request = window.ActiveXObject ?
new ActiveXObject('Microsoft.XMLHTTP') :
new XMLHttpRequest;
request.onreadystatechange = function() {
if (request.readyState == 4) {
request.onreadystatechange = doNothing;
callback(request, request.status);
}
};
request.open('GET', url, true);
request.send(null);
}
function doNothing() {}
loadnext() will be very similar to loadfirst(), I'm just running into issues with passing the xml data so that i can use it without having to access the database again. Thanks.
Set your xml and i in public scope. Then all you have to do is increment/decrement i and re-read data from XML. Something like this:
var xml;
var xml_idx = 0; // replaces your i counter
function loadXML() {
downloadUrl ("places.php", function(data) {
xml = data.responseXML;
)};
}
function loadItem(index) {
var id = xml[index].getAttribute("id");
var name = xml[index].getAttribute("name");
var location = xml[index].getAttribute("location");
var imgpath = xml[index].getAttribute("imgpath");
var tags = xml[index].getAttribute("tags");
// do something with this data
}
function loadCurrentItem() {
loadItem(xml_idx);
}
function loadNextItem() {
xml_idx++;
loadItem(xml_idx);
}
function loadPreviousItem() {
xml_idx--;
loadItem(xml_idx);
}
// usage
loadXML(); // do this first to populate xml variable
loadItem(xml_idx); // loads first item (i=0)
loadCurrentItem(); // loads i=0
loadNextItem(); // loads i=1
loadNextItem(); // loads i=2
loadPreviousItem(); // loads i=1
If you really want to get fancy (and keep the global namespace cleaner), you could easily make this into a class.
Use global variables (items - items array, iterator - counter) to store data available for all functions.
Try something like this:
items = false;
iterator = 0;
function loadfirst(){
downloadUrl ("places.php", function(data) {
var i = 0;
var xml = data.responseXML;
var places = xml.documentElement.getElementsByTagName("place");
var id = places[i].getAttribute("id");
var name = places[i].getAttribute("name");
var location = places[i].getAttribute("location");
var imgpath = places[i].getAttribute("imgpath");
var tags = places[i].getAttribute("tags");
items = places;
iterator++;
)};
}
function loadnext(){
var i = iterator;
var id = items[i].getAttribute("id");
var name = items[i].getAttribute("name");
var location = items[i].getAttribute("location");
var imgpath = items[i].getAttribute("imgpath");
var tags = items[i].getAttribute("tags");
iterator++;
}
You should wrap all this into a single object to control scope and data state. (Untested code below, which should just illustrate a possible pattern and interface to use.)
function PlacesScroller(url, callback) {
this.url = url;
this.data = null;
this._index = null;
this.length = 0;
var self = this;
downloadURL(this.url, function(result, status) {
if (Math.floor(status/100)===2) {
self.setData(result);
}
if (callback) {
callback(self, result);
}
});
}
PlacesScroller.prototype.setData(xmldom) {
this._index = 0;
// this may require changing; it depends on your xml structure
this.data = [];
var places = xmldom.getElementsByTagName('place');
for (var i=0; i<places.length; i++) {
this.data.push({
id : places[i].getAttribute('id'),
name : places[i].getAttribute('name')
// etc
});
}
}
PlacesScroller.prototype.getPlaceByIndex = function(index) {
if (this.data) {
return this.data[index];
} else {
return null;
}
}
PlacesScroller.prototype.getCurrentFeature = function() {
return this.getPlaceByIndex(this._index);
}
PlacesScroller.prototype.addToIndex(i) {
// This sets the index forward or back
// being careful not to fall off the end of the data
// You can change this to (e.g.) cycle instead
if (this.data===null) {
return null;
}
var newi = i+this._index;
newi = Math.min(newi, this.data.length);
newi = Math.max(0, newi);
this._index = newi;
return this._index;
}
PlacesScroller.prototype.getNextFeature = function() {
this.addToIndex(1);
return this.getCurrentFeature();
}
PlacesScroller.prototype.getPreviousFeature = function() {
this.addToIndex(-1);
return this.getCurrentFeature();
}
Then initialize it and use it like so:
var scroller = new PlacesScroller('places.php', function(scrollerobject, xmlresult){
// put any initialization code for your HTML here, so it can build after
// the scrollerobject gets its data.
// You can also register event handlers here
myNextButton.onclick = function(e){
var placedata = scrollerobject.getNextFeature();
myPictureDisplayingThing.update(placedata);
}
// etc
});

JQuery Validation not working on Ajax Control....!

Hi there I have Problem with my Code I just want to validate States which is generated from Ajax response.text
Here is the JQuery for State Field:
$(document).ready(function () {
var form = $("#addStudentfrm");
var state = $("#state");
var stateInfo = $("#stateInfo");
state.blur(validateStates);
state.keyup(validateStates);
function validateStates() {
if (state.val() == '') {
state.addClass("error");
stateInfo.text("Please Select/Enter State");
stateInfo.addClass("error5");
return false;
} else {
state.removeClass("error");
stateInfo.text("");
stateInfo.removeClass("error5");
return true;
}
}
});
Here PHP Function for Get All States in Respected Country:
public function getAllCountryStates($post){
$que = "Select * from ".WMX_COUNTRY." where code = '".$post[value1]."'";
$cRes = $this->executeQry($que);
$cResult = $this->getResultRow($cRes);
$cId = $cResult['id'];
$stateObj = new Admin;
$rdat = $post['opr'];
$rdtar = explode('.', $rdat);
$res = #mysql_fetch_row(mysql_query("Select * from ".$rdtar['1']." where id = ".$rdtar['0']));
$usts = $res['state'];
$result = $stateObj->selectQry(WMX_STATE,"country_id=$cId",'','');
$number = $stateObj->getTotalRow($result);
if($number > 0){
$getSelect ="<select name='state' id='state' class='textboxcss'>";
while($stateVal = $stateObj->getResultRow($result)){
$getSelect.="<option value='".$stateVal[state]."'>$stateVal[state]</option>";
}
$getSelect.="</select>";
}else{
if($usts!=''){
$getSelect = "<input type='text' name='state' id='state'class='textboxcss' value='$admnState'/>";
} else {
$getSelect = "<input type='text' name='state' id='state' class='textboxcss'/>";
}
}
echo $getSelect; }
In the Initial State Text box getting validate
but when the control comes with the Ajax Response Jquery wont validate it for Blank Entries
my Ajax Function:
function DataByPost(url,objId,postData,div_id){
var selId = objId.split('|');
var passData = postData;
var AJAX = null;
if (window.XMLHttpRequest) {
AJAX=new XMLHttpRequest();
} else {
AJAX=new ActiveXObject("Microsoft.XMLHTTP");
}
if (AJAX==null) {
alert("Your browser doesn't supportAJAX.");
return false
} else {
AJAX.open("POST",url,true);
AJAX.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
AJAX.onreadystatechange = function() {
if (AJAX.readyState==4 || AJAX.readyState=="complete"){
alert(AJAX.responseText);
var msg=AJAX.responseText;
var idary = new Array();
document.getElementById(selId).value = msg;
document.getElementById(selId).innerHTML = msg;
}
}
AJAX.send(passData);
}
}
//First Function
function showContent(url,arg,opr,sel_id,div_id)
{
var postData='';
var formVal=arg.split('|');
if(document.getElementById(div_id))
document.getElementById(div_id).style.display='';
if(document.getElementById(sel_id))
document.getElementById(sel_id).style.display='';
for(i=1;i<=formVal.length;i++)
var postData =postData + 'value'+i+'='+escape(formVal[i-1])+'&';
postData=postData + 'opr='+opr;
DataByPost(url,sel_id,postData,div_id);
}
I don't know exactly what is going on here without seeing the actual page, but a few things you might try:
Use jQuery to do your ajax since you're already using it. It is bug-free and cross platform, and that way you can be sure there are no bugs in the ajax part.
I would move the lines "var state = $("#state"); var stateInfo = $("#stateInfo");" inside of the function then declare the function outside of your document.ready block. That way you can be sure that every time the function gets called, it has access to the variables.
If your ajax call is replacing the input you're validating, you'll need to re-bind the events each time your ajax call finishes. With jQuery you can do this using the callback parameter.
I'm assuming number 3 is your problem, so try it first.

Solving Dual URL Problem..?

I am using cakephp I have 2 links:
<a href="#" tabindex="1" onclick="base_load_demo1('http://www.boxyourtvtrial.com/widget/beer/main/');" >beer</a>
cocktail
With the following JavaScript:
var Url1 = "http://www.boxyourtvtrial.com/widget/cocktail/main/";
var Url2 = "http://www.boxyourtvtrial.com/widget/beer/main/";
var Url3 = "http://www.boxyourtvtrial.com/widget/beer/mini/";
function base_load_demo(Url) {
remoteCall(Url1,"","mainLeftContent");
//remoteCall("SCRIPT_PATH","QUERY_STRING","TARGET_FUNCTION");
}
function base_load_demo1(Url2) {
remoteCall(Url2,"","mainLeftContent");
//remoteCall("SCRIPT_PATH","QUERY_STRING","TARGET_FUNCTION");
}
When I click on the first link it's showing its content through ajax call but when I click on the second link its giving error as follows:
Missing Controller
Error: Http:Controller could not be found.
Error: Create the class Http:Controller below in file: app/controllers/http:controller.php
<?php
class Http:Controller extends AppController {
var $name = 'Http:';
}
?>
Notice: If you want to customize this error message, create app/views/errors/missing_controller.ctp
and in FireFox console tab
POST http://www.boxyourtvtrial.com/widget/beer/main/http://www.boxyourtvtrial.com/widget/cocktail/main/
How can we solve this dual URL calling at the same time?
var xmlHttp;
var uri = "";
var callingFunc = "";
var sResponse = new Array();
function remoteCall(sUrl, sQueryStr, sCalledBy)
{
alert(sUrl);
var resStr = "";
var str = " { ";
if(sQueryStr != "") {
var arr1 = new Array();
arr1 = sQueryStr.split("&");
if(arr1){
for(i=0;i<=arr1.length;i++)
{
if(arr1[i] && arr1[i] != "")
{
var arr2 = new Array();
arr2 = arr1[i].split("=");
str += arr2[0]+":'"+arr2[1]+"' ,";
}
}
}
}
str += " tp: 'tp' } ";
$.ajax({
type: "GET",
url: sUrl,
data: sQueryStr,
dataType: "html",
success: function(data) {
$("#"+sCalledBy).html(data);
//jih(sCalledBy,data);
}
});
/* $.get(sUrl,sQueryStr,function(data) {
jih(sCalledBy,data);
});*/
}
function jih(divid,data)
{
if(document.getElementById(divid))
document.getElementById(divid).innerHTML=data;
}
After your first call to either of those pages it loads:
<script type="text/javascript" src="http://www.boxyourtvtrial.com/widget/cocktail/main/js/common.js"></script>
in the header. Inside common.js is a function called remoteCall, which is overwriting your local remoteCall function.
The remoteCall function inside common.js adds
var url= WIDGET_WEG_PATH+scr_url;
where WIDGET_WEG_PATH = "http://www.boxyourtvtrial.com/widget/beer/main/"
and scr_url = "http://www.boxyourtvtrial.com/widget/beer/main/" (the first parameter of the new remoteCall function)
This is why you are getting the url 'doubled' in the post.
Solution:
Rename local remoteCall function to something that is distinct.

Categories