execute function only when another has finished javascript/jquery - php

i have an application that runs continuously and updates itself if needed. It uses ajax to call a php file that will check some data on the database, if it has changed then we update the screen. The php seems to work just fine its the js that i'm having a problem with.
$(document).ready(function () {
$('.trade_window').load('signals.php?action=init', setInterval(function () {
for(var i = 1; i < 6; i++) {
console.log('market_name_' + i + " is " + $('.market_name_' + i).text().trim());
$.ajax({
url: 'signals.php?action=check&param=' + JSON.stringify({
'market_number': i,
'market_name': ('.trade_window .market_name_' + i).text().trim(),
'trade_type': $('.trade_window .status_' + i).text().trim(),
'trade_start_price': '1.1234',
'trade_open_time': '18:21:02'
}),
type: 'GET',
success: function (result) {
if(result.trim() === "false") {
console.log("RESULT IS " + result.trim());
} else {
$('.trade_window #market_1').html(result);
setTimeout(function () {
// This is to make it a little more visible
console.log(" ");
console.log(" ");
console.log("PAUSE!!!!");
console.log(" ");
console.log(" ");
}, 5000);
}
}
});
};
}, 2000));
});
So, what happens in the application is there are 6 elements (divs) within these we have a few pieces of information, these are compared with the data on the DB if they're different then the DB information needs to be shown.
Now the script above checks each element and then updates if it is needed, the problem is that the ajax call is done in the background and all the other stuff is executed while we're waiting for the ajax calls to complete so by the time tthey have completed the for loop is at the end so only element 6 will be updated even if element 1, 2, 3, 4 or 5 are changed.
What can i do to change this? is there a js/jquery method that can be used to check if the php file has finished loading?
Thanks for your time.

Collect the deferred (promise) return value of your $.ajax calls:
var def = [];
for (var i = 1; i < 6; ++i) {
def[i - 1] = $.ajax({ ... });
}
and then outside the loop use $.when() to wait for them all to complete:
$.when.apply($, def).done(function(r1, r2, r3, ...) {
...
});

Related

How do I display the amount without refresh?

I am using CodeIgniter.
I have a function called as reloadCart(). I have to reload this function every time because this function will reload the amount anything changes happened. This is working perfect but the issue is when I am refreshing the page then it displays the new amount.
$(document).ready(function(){
reloadCart();// function reload on page refresh
function reloadCart(){
$.ajax({
url: "<?php echo base_url(); ?>Member_controller/primaryCartload",
context: document.body,
success: function(data){
if (data !=0) {
var obj = JSON.parse(data);
if (obj.qty != 0) {
$('#totalDetails').html(obj.cart_total);
$('#totalQty').html(obj.totalQty);
}
}
else{
//alert('empty')
$('#totalDetails').html('0');
$('#totalQty').html('0');
}
}
});
}
});
Can we use something like?
load({
reloadCart();
});
You can just update your price by running that AJAX call time to time, for that you'll need to set a time after that specific time your call will be run again.
var count = 20;
setInterval(function () {
count--;
if (count === 0) {
count = 20;
reloadCart();
}
}, 1000);
So after every 20 sec this function will be called, you can amend it as required.

Playing sound when new message comes in

I am making chat for my student group, and I am using AJAX to get my messages like this
//Initial call i make so user do not wait 2 seconds for messages to show
function marko() {
$("#porukice").load("messages.php"); //Load the content into the div
}
marko();
//autorefresh every 2 seconds
var auto_refresh = setInterval(
(function () {
$("#porukice").load("messages.php"); //Load the content into the div
}), 2000);
To send messages I am also using ajax, like this
var frm = $('#form1');
frm.submit(function (ev) {
$.ajax({
type: frm.attr('method'),
url: frm.attr('action'),
data: frm.serialize(),
success: function (data) {
document.getElementById("message").value = "";
document.getElementById('play').play();
}
});
ev.preventDefault();
});
This is part of message.php (where messages are generated)
$sql = $conn->query('(SELECT * FROM chat ORDER BY time desc limit 0, 10) ORDER BY time');
while($row = mysqli_fetch_array($sql))
{
$rows[] = $row;
}
foreach($rows as $row){
$time = date('H:i:s', strtotime($row['2']));
echo '['.$time.'] <b>'.$row['0'].'</b>: '.stripslashes($row['1'])."<br/>";
}
I am trying to play a sound when new message arrives>
only solution I came up with is to play a sound when message is sent with
document.getElementById('play').play();
as you can see in above code. I have no clue how to play it when messages are coming, when mysql row is updated.
I saw other answers on stackoverflow but they are not helping me.
NOTICE: $row['1'] is message, $row['0'] is user name and $row['2'] is time.
You could pass, from the PHP script that gets the messages, the value of the last id you got. Then, store it in a jQuery variable, and after you reload the messages, check if the ids are different, if they are (that means a new message came up), play the sound.
For example, after the foreach loop:
return json_encode(array('last_time' => $rows[count($rows)-1][2]));
On your jQuery:
var last_time = 0; // <--- New
var new_time = 0; // <--- New
// Initial call i make so user do not wait 2 seconds for messages to show
function marko() {
$("#porukice").load("messages.php"); //Load the content into the div
// New
if (last_time < new_time) {
document.getElementById('play').play();
last_time = new_time;
}
}
marko();
//autorefresh every 2 seconds
setInterval(function () { // <--- Some edits here
marko(); // <--- Some edits here
}, 2000);
// ....
var frm = $('#form1');
frm.submit(function (ev) {
$.ajax({
type: frm.attr('method'),
url: frm.attr('action'),
data: frm.serialize(),
success: function (data) {
document.getElementById("message").value = "";
last_time = new_time; // <--- New
new_time = data.last_time; // <--- New
}
});
ev.preventDefault();
});
I've not tested this, but you're free to do it and let me know.
EDITED to use time instead of id
I fixed this problem by creating separate file called sound.php
Sound.php is answering to get request with json response including date and time of last message
{"last_time":"2017-02-25 17:45:55"}
Then I am calling this file every 2 seconds with ajax, and if last_time has changed i play a sound
var skipped_once = false;
var old_time = 0
var auto_refresh = setInterval(function() {
$.get("sound.php", function(data) {
// if old_time different than last_time play sound
if (old_time != data.last_time) {
//do not play sound on first page load
if (skipped_once) {
document.getElementById('play').play();
out.scrollTop = out.scrollHeight - out.clientHeight;
}
skipped_once = true;
old_time = data.last_time;
}
});
}, 2000);

Count number of jQuery $.get success responses

I have a jQuery function that loads a PHP file (which gets a JSON response from an application) every 100ms. What I am trying to do is have two different counters, one which will increment every time a request is sent and another counter which will increment as soon as it gets a JSON response. At the moment I have the following which is not working, they are both just counting the number of requests being sent:-
JQUERY
$(function() {
var MAXNUM = 9;
var count = 0;
var countSuccess = 0;
function newAsyncRequest() {
setTimeout(function() {
newAsyncRequest();
count++;
$(".request").html(count);
$.get('test.php', function(data) {
countSuccess++;
$( ".log" ).html(countSuccess);
});
}, 100);
}
newAsyncRequest();
});
PHP
require_once('scripts/php/controllers/curl.controller.php');
$postcode = 'LE11 5';
$postcode = rawurlencode($postcode);
$uri = 'http://192.168.1.110:8290/?pc='.$postcode; // Home
$response = CurlController::request($uri);
So my question is basically, how can I count the number of successful responses I am getting from .$get command?
Need to print count to .request, you were using countSuccess in both the statements
$(function() {
var MAXNUM = 9;
var count = 0;
var countSuccess = 0;
function newAsyncRequest() {
setTimeout(function() {
newAsyncRequest();
count++;
$(".request").html(count);
//need to print here
$.get('test.php', function(data) {
countSuccess++;
$( ".log" ).html(countSuccess);
});
}, 100);
}
newAsyncRequest();
});
You can use $.ajax's success parameter. The function passed to this parameter will only run if an ajax request is successful.
$.ajax({
url:"",
type: "get",
beforeSend: function(){ requestCounter++ },
success: function(){ successCounter++ }
});
What are you defijning as a success?
The .get 'success' is that the server responded which it hopefully always will do.
If you are definign success as somthign working in the PHP script then in the PHP then in the jquery success function check what was returned in 'data' to see if it was succesful.
I generally return a Json encoded array with an element called 'result' that is either set to ture or false by the PHP and the jquery can simple act on that record.

Installation progress bar php

I have a simple installer that's divided in segments, not by syntax, but just by logic. Here's how it works:
if ($_POST['install'] == "Install")
{
// fetches user values
// creates tables
// creates some files
// creates some emails
// inserts relevant stuff into the database
// finishes
}
The code is too long and unnecessary for this question. Each of those steps counts as 20% complete for the installation, how would I make a progress bar displaying the info to the user? I'd like this for two reasons, one is for them to keep track, other is for them to know they shouldn't close the browser tab before it's done.
Now my idea is to assign a variable to each part of the code, for instance $done = 20% in the first, $done = 40% in the second etc, and simply show progress bar based on that variable. The the only thing I don't know is how to show the progress bar?
Thanks
My recommended solution:
Create separate ajax requests for each step in your process like so...
// do first step
$.ajax({
url: myUrl + '?step=1',
success: function() {
// update progress bar 20%
}
});
// do second step
$.ajax({
url: myUrl + '?step=2',
success: function() {
// update progress bar 40%
}
});
// etc.
If you want to be DRY, try this:
var steps = 5;
for (var i = 1; i <= steps; i++) {
$.ajax({
url: myUrl + '?step=' + i;
success: function() {
// update success incrementally
}
});
}
With jQuery UI progressbar:
$(function() {
$("#progressbar").progressbar({
value: 0
});
var steps = 5;
for (var i = 1; i <= steps; i++) {
$.ajax({
url: myUrl + '?step=' + i;
success: function() {
// update success incrementally
$("#progressbar").progressbar('value', i * 20);
}
});
}
});
Ref. http://jqueryui.com/progressbar/#default
The best practice is to store the progress value in a db or a key-value storage system such as APC, Memcache or Redis. And then retrieve the progress with an ajax query.
A good jquery plugin is progressbar bar from jQuery-ui, and you can use json to encode the progress value:
// GET /ajax/get-status.json
{
"progress":10,
"error":"",
"warning":""
}
The page:
<div id="error" style="color: red"></div>
<div id="warning" style="color: yellow"></div>
<div id="message"></div>
<div id="progressbar"></div>
<script type="text/javascript">
jQuery(document).ready(function() {
$("#progressbar").progressbar({ value: 0 });
$.ajaxSetup({ cache: false });
function updateProgress() {
jQuery.getJSON("/ajax/get-status.json", function(response) {
if (response.error) {
$("#error").html( response.error );
return;
} else {
$("#progressbar").progressbar( 'value', parseInt( response.progress ) ); // Add the new value to the progress bar
$("#message").html( response.message );
$("#warning").html( response.warning );
if(parseInt( response.progress ) < 100){
setTimeout(updateProgress, 1);
}
}
});
}
updateProgress();
});
</script>
You can use an HTML5 progress bar.
Send ajax request and return the percent complete.
Change the progress tag's value.
<progress id='p' max="100" value="50"></progress>

getJSON Loop Until Response

I have a PHP process which updates files, and writes a status report with each file.
While that is happening, I was hoping to update the user's browser until the final response.
Unless there is a better way, I simply wanted some advice on how to loop infinitely refreshing getJSON() results until the ajax response comes.
What is the best way to do this?
This ended up being the solution I used:
$(document).on('click', "#ss_batch_edit_processing", function (e) {
var ids = get_selected();
var status_location = '<?php echo symbiostock_TMPDIR . '/report.txt' ?>';
if(ids == 0){
return;
}
$('.' + loading_icon_small).show();
var data = {
action: 'ss_professional_ajax',
security: '<?php echo $ajax_nonce; ?>',
reprocessing_action: $('input:radio[name=ss_reprocessing_action]:checked').val(),
ids: ids,
};
var completed = 0;
$.post(ajaxurl, data, function (response) {
$('.' + loading_icon_small).hide();
completed = 1;
});
var get_update = function(){
$.getJSON(status_location, function (data) {
var update = '<ul><li><strong>'+data['title']+'</strong></li><li><strong>Count:</strong> '+data['count']+' / '+data['total']+'</li><li><strong>Last processed</strong>: Image # '+data['last_id']+'</li></ul>';
$('#ss-reprocessing-results').html(update).delay(1000);
});
if(completed == 1){
clearInterval(timed_requests)
return false;
}
};
var interval = 1000; // every 1 second
var timed_requests = setInterval(get_update, interval);
});

Categories