jQuery synchronous asynchronous requests in order - javascript

I have tasks that I want to do synchronously; but I don't want to freeze the browser. There could be 1---N tasks.
Below is the synchronous version. It works as expected but freezes the browser.
How can I do this using jQuery deferred object to do these task in order but not lock browser.
NOTE: The server I am request to does NOT allow for 2 requests at once. They need to run one after the other once the request is finished in exact order.
<?php
for ($k = 0;$k<count($partial_transactions);$k++)
{
?>
$("#formCheckout_<?php echo $k; ?>").ajaxSubmit({
success:function(response)
{
var data = response.split("&");
var processed_data = [];
for(var i = 0; i < data.length; i++)
{
var m = data[i].split("=");
processed_data[m[0]] = m[1];
}
$("#please_wait").hide();
if (processed_data.CmdStatus != 'Approved')
{
var message = decodeURIComponent(message);
message = processed_data.TextResponse.replace(/\+/g, ' ');
toastr['error'](<?php echo json_encode(lang('sales_attempted_to_reverse_partial_transactions_failed_please_contact_support'));?>, <?php echo json_encode(lang('common_error')); ?>);
}
else
{
toastr['success'](<?php echo json_encode(lang('sales_partial_credit_card_transactions_voided')); ?>, <?php echo json_encode(lang('common_success')); ?>);
}
},
cache: true,
headers: false,
async: false
});
<?php
}
?>

Try this:
var counter = 0;
// Build up an array of all forms that are to be submitted sequentially.
var forms = [
<?php
for ($k = 0;$k<count($partial_transactions);$k++){
if($k == 0){
echo "#formCheckout_{$k}";
}else{
echo ", #formCheckout_{$k}";
}
}
?>
];
// Start the request
make_next_request(forms[counter]);
function make_next_request(form){
form.ajaxSubmit({
success:function(response)
{
var data = response.split("&");
var processed_data = [];
for(var i = 0; i < data.length; i++)
{
var m = data[i].split("=");
processed_data[m[0]] = m[1];
}
$("#please_wait").hide();
if (processed_data.CmdStatus != 'Approved')
{
var message = decodeURIComponent(message);
message = processed_data.TextResponse.replace(/\+/g, ' ');
toastr['error'](<?php echo json_encode(lang('sales_attempted_to_reverse_partial_transactions_failed_please_contact_support'));?>, <?php echo json_encode(lang('common_error')); ?>);
}
else
{
toastr['success'](<?php echo json_encode(lang('sales_partial_credit_card_transactions_voided')); ?>, <?php echo json_encode(lang('common_success')); ?>);
}
// Now chain request onto next form.
if(counter < forms.length){
counter++;
make_next_request(forms[counter]);
}
},
cache: true,
headers: false,
async: false
});
}

You could just put it all in a web worker that handles all the data, so the UI thread doesn't get interrupted (but you'll have to give the user some indication that the data is loading.)
See the web worker API for more info, but basically, web workers are native browser objects that allow you to have multi-threaded operations. In other words, your operations can run in the background while the user still interacts with the web page, and then when the operations are complete, they can notify the UI thread (the thread the user is currently on.)
This CPU-intensive data loading that you're talking about seems like a perfect use case for such an API.

I ended up doing it like this. The intensive part is server side. So I took some suggestions and came up with this. (Using recursion)
<script>
var num_transactions_to_void = <?php echo count($partial_transactions); ?>;
var max_index = num_transactions_to_void - 1;
if (num_transactions_to_void > 0)
{
void_sale_request(0);
}
function void_sale_request(index)
{
if (index > max_index)
{
return;
}
$("#formCheckout_"+index).ajaxSubmit({
success:function(response)
{
var data = response.split("&");
var processed_data = [];
for(var i = 0; i < data.length; i++)
{
var m = data[i].split("=");
processed_data[m[0]] = m[1];
}
$("#please_wait").hide();
if (processed_data.CmdStatus != 'Approved')
{
var message = decodeURIComponent(message);
message = processed_data.TextResponse.replace(/\+/g, ' ');
toastr['error'](<?php echo json_encode(lang('sales_attempted_to_reverse_partial_transactions_failed_please_contact_support'));?>, <?php echo json_encode(lang('common_error')); ?>);
}
else
{
toastr['success'](<?php echo json_encode(lang('sales_partial_credit_card_transactions_voided')); ?>, <?php echo json_encode(lang('common_success')); ?>);
}
void_sale_request(index + 1);
},
cache: true,
headers: false
});
}
</script>

Related

Error in AJAX code causing broswer to crash

Hello I have written an ajax script that grabs different pages and displays them for X amount of time and then switches to the next page. I use the setTimeout function to display the pages for the X amount of time. In order to grab each page I created a list of different pages in a database that my code looks at then calls the appropriate php function to grab the data.
What seems to be happening is that it causes firefox to crash after a couple of days because firefox seems to run out of memory. My guess is that my code is not efficient but, I am not sure how I can make it more efficient so it does not crash the browser. Any help would be greatly appreciated. Here is my code:
<?php $this->load->view('includes/header'); ?>
<div id="result">
</div>
<?php $this->load->view('includes/footer');?>
<?php $displayName = $this->input->get('name');?>
<script type="text/javascript">
var views = [];
var cell = '';
var i = 0;
var display = <?php echo json_encode($displayName); ?>;
var timeOut = 0;
$(function get_data() {
$.ajax({
url: "get_display_data/"+display,
type: "post",
cache: false,
success: function(data){
views = JSON.parse(data);
if (i >= views.display.length) {
i = 0;
} else if (views.display[i].view == 'Fabrication') {
var loadUrl = "<?php echo base_url();?>/index.php/Cells/FabricationStatus/"+views.display[i].view + "/"+ "display1?name="+display;
$("#result").empty().load(loadUrl+"#mainContent");
timeOut = 60;
i++;
} else if(views.display[i].view == 'CYLPLNGLCMSH') {
var loadUrl = "<?php echo base_url();?>/index.php/Cells/CYLPLNGLCMSHStatus/"+views.display[i].view + "/"+display;
$("#result").empty().load(loadUrl+"#mainContent");
timeOut = 60;
i++;
} else if(views.display[i].view == 'COTCTR') {
var loadUrl = "<?php echo base_url();?>/index.php/Cells/COTCTRStatus/"+views.display[i].view + "/"+display;
$("#result").empty().load(loadUrl+"#mainContent");
timeOut = 60;
i++;
} else {
var loadUrl = "<?php echo base_url();?>/index.php/Cells/Display/"+views.display[i].view + "/"+display;
$("#result").empty().load(loadUrl+".mainContent");
timeOut = 30;
i++;
}
setTimeout(get_data, (1000 * timeOut));
}
});
});

How to show the errors through ajax and Jquery in codeigniter

This is my ajax call
function exportCSV(){
var sampleid = $("#sampleid").val();
var scheme = $("#scheme").val();
var v = $("#v").val();
var date = $("#date").val();
var assignedvalue = $("#assignedvalue").val();
var units = $("#units").val();
var assayvalue = $("#assayvalue").val();
var analyte = $("#analyte").val();
var filename=$("#filename").val();
var sample_error=$("#sample_error").val();
$.ajax({
type: "POST",
url: "<?php echo base_url(); ?>" + "import/validate_file",
dataType: 'json',
data: {
sampleid: sampleid,
scheme: scheme,
v: v,
date: date,
assignedvalue: assignedvalue,
units: units,
assayvalue: assayvalue,
analyte: analyte,
filename:filename,
sample_error: sample_error
},
success: function (data) {
console.log(data); //as a debugging message.
}
});
}
and this is my controller
<?php
if (!empty($unit_check) and !empty($analyt) and !empty($sch) and count($sample_id) == count(array_unique($sample_id)) and $assigned_check == '1' and $assay_check == '1') {
for ($row = 2; $row <= $lastRow; $row++) {
$data['sample_id'] = $worksheet->getCell($sampleid . $row)->getValue();
$data['scheme'] = $worksheet->getCell($scheme . $row)->getValue();
$data['v'] = $worksheet->getCell($v . $row)->getValue();
$data['units'] = $worksheet->getCell($unit . $row)->getValue();
$data['date'] = $worksheet->getCell($date . $row)->getFormattedValue();
$data['assay_value'] = $worksheet->getCell($assayvalue . $row)->getValue();
$data['assigned_value'] = $worksheet->getCell($assignedvalue . $row)->getValue();
$data['analyte'] = $worksheet->getCell($analyte . $row)->getValue();
$data['trace_id'] = $insert_id;
$this->import_model->insert_data($data);
$response['success'] = true;
}
} else {
$data['sample_id'] = '';
$data['analyte'] = '';
$data['unit_check'] = '';
$data['sch'] = '';
$data['assigned_value'] = '';
$data['assay_value'] = '';
if (count($sample_id) != count(array_unique($sample_id))) {
$data['sample_id'] = '1';
}
if (empty($analyt)) {
$data['analyte'] = '1';
}
if (empty($unit_check)) {
$data['unit_check'] = '1';
}
if (empty($sch)) {
$data['sch'] = '1';
}
if ($assigned_check == '') {
$data['assigned_value'] = '1';
}
if ($assay_check == '') {
$data['assay_value'] = '1';
}
$data['file_name'] = '';
}
?>
I have to show the errors and success message on ajax call.
Right now I'm succeeded in valuating the data and putting it in the database.
But I want to show the success message at the end of the page by clicking the submit button.
And if there is validations error it must shows the errors in that fields at the end of the page
Any help would be appreciated.
Here inside your success method of ajax
success: function (data) {
$("#resultDiv").html(data)
}
Return some real data from your controller in both case success and failed. and based on your data inside success method show your message.
Like:
success: function (data) {
$("#resultDiv").html(data.success) //this requires string to convert your result in string if neccessary
//But you should return a JSON data as msg from your controller
}
You should put a result HTML element for example:
<div id='resultDiv'></div> <!-- to match with #resultDiv -->
Put response data in both condition if success=true and else success=false
In your controller
if(.....){
//what ever check you wanna do
..........
..........
$response['msg']='success';
header('Content-Type', 'application/json');
echo json_encode($response);
}
else{
$response['msg']='failed';
header('Content-Type', 'application/json');
echo json_encode($response);
}
In your ajax
success: function (data) {
$("#resultDiv").html(data.msg)
}
Try something like:
$response = array(
'errCode' = 0,
'errMsg' = 'msg'
);
return this kind of array by json_encode() from php to ajax() call and use it in ajax() success like:
var data = JSON.parse(response);
alert(data.errMsg);
You can also put a check on errCode like:
if(errCode == 0) { something }
if(errCode == 1) { something }

Displaying multiple images with an ajax response

I am trying to display multiple images coming from a remote server on a single page, the page is a html file where putting php blocks wouldn't be doing anything to get thing I want
Using PHP version 5.6, the code for the php is
$dir = "uploads/image/dashed/";
$files = scandir($dir);
foreach ($files as $file)
{
if ( is_file($dir. $file) ){
echo $file;
}
}
the ajax response code is:
$(document).ready(function(){
$.ajax({
async: true,
type: 'POST',
url: 'folder.php',
success: function(data){
$("#imageContent").html(data).append("<br/>");
var images = data.split("\n");
for (var i = 0, j = images.length; i < j; i++){
$("#imageContent").append("<img src='uploads/image/dashed/" + images[i] + "' width='300'>");
}
}
});
});
all I keep getting from the server is
1354876944ABF.jpg_MG_0085.jpg
and an empty image place holder (not two, just the one) for where the image
and the image address is showing two image names stuck together in one link
uploads/image/dashed/1354876944ABF.jpg_MG_0085.jpg
where the response link should be on two (for this example) different lines and images where the <img> is on the html inside the ajax call
Try This,
$dir = "uploads/image/dashed/";
$files = scandir($dir);
$i = 1;
$count = count($files);
foreach ($files as $file){
if(is_file($dir. $file)){
if($i == $count){
echo $file;
}else{echo $file.'|||';
}
}
$i++;}
and change ajax to:
$(document).ready(function(){
$.ajax({
async: true,
type: 'POST',
url: 'folder.php',
success: function(data){
$("#imageContent").html(data).append("<br/>");
var images = data.split("|||");
for (var i = 0, j = images.length; i < j; i++){
$("#imageContent").append("<img src='uploads/image/dashed/" + images[i] + "' width='300'>");
}
}
});
});
thats using ||| as a delimiter.
EDIT: now it should work properly,
EDIT2: changed $i = 0 order, added $i++; at the end
scandir() is already giving you an array, so why not just json_encode it and return this? unset() any output that is not a valid file:
$files = scandir($dir);
$count = count($files);
for($i = 0; $i < $count; $i++) {
if ( !is_file($dir. $file) ){
unset($files[$i]);
}
}
echo json_encode($files);
then in your success block:
success: function(data){
$("#imageContent").html(data).append("<br/>");
var i,
json = JSON.parse(data);
for (i in json){
$("#imageContent").append("<img src='uploads/image/dashed/" + json[i] + "' width='300'>");
}
}

Why is my code not passing to my div?

I'm trying to create a gameserver query for my website, and I want it to load the content, save it, and echo it later. However, it doesn't seem to be echoing. It selects the element by ID and is supposed to echo the content of the VAR.
Here's my HTML code:
<center><div id="cstrike-map"><i class="fa fa-refresh fa-spin"></i> <b>Please wait ...</b><br /></div>
JavaScript:
<script type="text/javascript">
var map = "";
var hostname = "";
var game = "";
var players = "";
$.post( "serverstats-cstrike/cstrike.php", { func: "getStats" }, function( data ) {
map = ( data.map );
hostname = ( data.hostname );
game = ( data.game );
players = ( data.players );
}, "json");
function echoMap(){
document.getElementByID("cstrike-map");
document.write("<h5>Map: " + map + "</h5>");
}
</script>
PHP files:
query.php
/* SOURCE ENGINE QUERY FUNCTION, requires the server ip:port */
function source_query($ip)
{
$cut = explode(":", $ip);
$HL2_address = $cut[0];
$HL2_port = $cut[1];
$HL2_command = "\377\377\377\377TSource Engine Query\0";
$HL2_socket = fsockopen("udp://".$HL2_address, $HL2_port, $errno, $errstr,3);
fwrite($HL2_socket, $HL2_command); $JunkHead = fread($HL2_socket,4);
$CheckStatus = socket_get_status($HL2_socket);
if($CheckStatus["unread_bytes"] == 0)
{
return 0;
}
$do = 1;
while($do)
{
$str = fread($HL2_socket,1);
$HL2_stats.= $str;
$status = socket_get_status($HL2_socket);
if($status["unread_bytes"] == 0)
{
$do = 0;
}
}
fclose($HL2_socket);
$x = 0;
while ($x <= strlen($HL2_stats))
{
$x++;
$result.= substr($HL2_stats, $x, 1);
}
$result = urlencode($result); // the output
return $result;
}
/* FORMAT SOURCE ENGINE QUERY (assumes the query's results were urlencode()'ed!) */
function format_source_query($string)
{
$string = str_replace('%07','',$string);
$string = str_replace("%00","|||",$string);
$sinfo = urldecode($string);
$sinfo = explode('|||',$sinfo);
$info['hostname'] = $sinfo[0];
$info['map'] = $sinfo[1];
$info['game'] = $sinfo[2];
if ($info['game'] == 'garrysmod') { $info['game'] = "Garry's Mod"; }
elseif ($info['game'] == 'cstrike') { $info['game'] = "Counter-Strike: Source"; }
elseif ($info['game'] == 'dod') { $info['game'] = "Day of Defeat: Source"; }
elseif ($info['game'] == 'tf') { $info['game'] = "Team Fortress 2"; }
$info['gamemode'] = $sinfo[3];
return $info;
}
cstrike.php
include('query.php');
$ip = 'play1.darkvoidsclan.com:27015';
$query = source_query($ip); // $ip MUST contain IP:PORT
$q = format_source_query($query);
$host = "<h5>Hostname: ".$q['hostname']."</h5>";
$map = "<h5>Map: ".$q['map']."</h5>";
$game = "<h5>Game: ".$q['game']."</h5>";
$players = "Unknown";
$stats = json_encode(array(
"map" => $map,
"game" => $game,
"hostname" => $host,
"players" => $players
));
You need to display the response in the $.post callback:
$.post( "serverstats-cstrike/cstrike.php", { func: "getStats" }, function( data ) {
$("#map").html(data.map);
$("#hostname").html(data.hostname);
$("#game").html(data.game);
$("#players").html(data.players);
}, "json");
You haven't shown your HTML, so I'm just making up IDs for the places where you want each of these things to show.
There are some things that I can't understand from your code, and echoMap() is a bit messed up... but assuming that your php is ok it seems you are not calling the echomap function when the post request is completed.
Add echoMap() right after players = ( data.players );
If the div id you want to modify is 'cstrike-map' you could use jQuery:
Change the JS echoMap to this
function echoMap(){
$("#cstrike-map").html("<h5>Map: " + map + "</h5>");
}
So what I did was I had to echo the content that I needed into the PHP file, then grab the HTML content and use it.
That seemed to be the most powerful and easiest way to do what I wanted to do in the OP.
<script type="text/javascript">
$(document).ready(function(){
$.post("stats/query.cstrike.php", {},
function (data) {
$('#serverstats-wrapper-cstrike').html (data);
$('#serverstats-loading-cstrike').hide();
$('#serverstats-wrapper-cstrike').show ("slow");
});
});
</script>
PHP
<?php
include 'query.php';
$query = new query;
$address = "play1.darkvoidsclan.com";
$port = 27015;
if(fsockopen($address, $port, $num, $error, 5)) {
$server = $query->query_source($address . ":" . $port);
echo '<strong><h4 style="color:green">Server is online.</h4></strong>';
if ($server['vac'] = 1){
$server['vac'] = '<img src="../../images/famfamfam/icons/tick.png">';
} else {
$server['vac'] = '<img src="../../images/famfamfam/icons/cross.png">';
}
echo '<b>Map: </b>'.$server['map'].'<br />';
echo '<b>Players: </b>'.$server['players'].'/'.$server['playersmax'].' with '.$server['bots'].' bot(s)<br />';
echo '<b>VAC Secure: </b> '.$server['vac'].'<br />';
echo '<br />';
} else {
echo '<strong><h4 style="color:red">Server is offline.</h4></strong>';
die();
}
?>

Trying to convert jQuery to prototype... jQuery causing issues

I have the following code:
<script type='text/javascript' src='js/jquery.js'></script>
<script type='text/javascript'>
var last_song = '$song[1]';
var jqy = jQuery.noConflict()
var change_radio = setInterval(function ()
{
jqy.ajax({
url : 'modules/ajax/refresh.php',
type : 'GET',
data : {lastsong: 'last_song'},
success: function(data)
{
last_song = data;
jqy('#radio').html(last_song);
}
});
}, ($refresh*1000));
change_radio;
</script>
refresh.php
<?php
$lastsong = $_GET['lastsong'];
$timeout = "2"; // Number of seconds before connecton times out.
$ip[1] = "198.101.13.110"; // IP address of shoutcast server
$port[1] = "8000"; // Port of shoutcast server
//$song = [];
//$msg = [];
//END CONFIGURATION
$servers = count($ip);
$i = "1";
while ($i <= $servers)
{
$fp = #fsockopen($ip[$i], $port[$i], $errno, $errstr, $timeout);
if (!$fp)
{
$listeners[$i] = "0";
$msg[$i] = "<span class=\"red\">ERROR [Connection refused / Server down]</span>";
$error[$i] = "1";
}
else
{
fputs($fp, "GET /7.html HTTP/1.0\r\nUser-Agent: Mozilla\r\n\r\n");
while (!feof($fp)) $info = fgets($fp);
$info = str_replace('<HTML><meta http-equiv="Pragma" content="no-cache"></head><body>', "", $info);
$info = str_replace('</body></html>', "", $info);
$stats = explode(',', $info);
if (empty($stats[1]))
{
$listeners[$i] = "0";
$msg[$i] = "<span class=\"red\">ERROR [There is no source connected]</span>";
$error[$i] = "1";
}
else
{
if ($stats[1] == "1")
{
$song[$i] = $stats[6];
$listeners[$i] = $stats[4];
$max[$i] = $stats[3];
// Both IFs the same? Please check that and make one only if its the case
if ($stats[0] == $max[$i]) $msg[$i] = "<span class=\"red\">";
if ($stats[0] == $max[$i]) $msg[$i] .= "</span>";
}
else
{
$listeners[$i] = "0";
$msg[$i] = " <span class=\"red\">ERROR [Cannot get info from server]</span>";
$error[$i] = "1";
}
}
}
$i++;
}
if($song[1] != "")
{
echo $song[1];
exit();
}
echo uriencode($lastsong);
?>
And I want to change it to use prototype instead. I use prototype and jQuery already, and this is conflicting as written. I've no idea where to begin, but any assistance would be appreciated... especially since there are a lot of folks in my situation. Thanks so much.

Categories