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>
Related
I'm trying to understand the relationship between a PHP script I'd like to run to keep track of progress and the front end work that has taken place. Its 2 clues in a game practice. Once the clue is inputted correctly everything occurs as below and I want to add a script that sends to MYSQL.
I'm working on the script now, but I'm trying to figure out at what point I'd introduce this. Is there anything I'd need within my PHP to distinguish it as AJAX. As in to run it in the background? Do I just "include" it as I would part of another larger PHP script?
The script in my mind will send a 1 if correct or 0 if still wrong. This way I can easily determine without having to deal with clues. The clues are irrelevant in my thinking, but what is your opinion on this?
// =====clue 1====================////////////////// clue 1 **************
//**********************************========================
$(document).on('click', '.btn-clue', function(){
if($i!=1){
$.ajax({
type: "POST",
url: "includes/post_clue_progress",
data: { clueTwo: "1", usernameClue: "<?php echo $manager; ?>" }
})
.done(function( msg ) {
// msg is any data that is echoed in the php script or output to screen is some way
$("#clueWrongTwo").hide();
$("#mySecondDivClueTwo").remove();
$("#clueTwo").remove();
$("#clue2Input").remove();
$two.show();
$("#clueTwoInputCorrect").slideDown('slow').show();
$i++;
});
} else {
$("#mySecondDiv").remove();
var mySecondDiv = $('<div id="mySecondDiv"><img src="images/check-x-mark.png" /></div>').show('slow');
$('#clueWrongOne').append(mySecondDiv);
}
}
});
// =====clue 2====================////////////////// clue 2*********=========
$(document).on('click', '.btn-clueTwo', function(){
if($i!=1){
//checking if textbox has desired value (1 in this case),
//in your application you would be passing the textbox value to
//ajax here and making the check at server side
var $two = $('#twoClueShow');
var x = $("#clueTwoInput").find('input[type=text]').val();
if(x == 'C' || x == 'CS') {
// if answer correct you should load data from ajax
// and append it to a container
$("#clueWrongTwo").hide();
$("#mySecondDivClueTwo").remove();
$("#clueTwo").remove();
$("#clue2Input").remove();
$two.show();
$("#clueTwoInputCorrect").slideDown('slow').show();
$i++;
} else {
$("#mySecondDivClueTwo").remove();
var mySecondDivClueTwo = $('<div id="mySecondDivClueTwo"><img src="images/check-x-mark.png" /></div>') .show('slow');
$('#clueWrongTwo').append(mySecondDivClueTwo);
}
}
});
Above is where I've been able to get. Now here is where I'm getting confused. I now want to send to the database that the answer has been answered correctly through AJAX, correct? Would I just include_once my php script in the commented area.
I was thinking of creating a script that filled a 1 if correct and 0 if not correct to make life easier. Let this do the work as I don't need to reintroduce the inputs or re use. This way once the page has reloaded I could simply not output the inputs again and use this info to determine what is displayed and where they are at in the clue game. Basically saving progress.
Is there something specific to use when building my normal PHP. I guess that and where to "include" it is where I'm confused.
MY button for reference
<div id="clueOneInput">
<input type="text" id="clue1" class="clue-text form-control" placeholder="Enter Clue 1 here and check"/>
</div>
<input type="button" id="clue1Input"class="btn btn-primary btn-clue" value="Check">
Update :
// =====clue 1====================////////////////// clue 1**********************************************************************========================
$(document).on('click', '.btn-clue', function(){
if($i!=1){
//checking if textbox has desired value (1 in this case),
//in your application you would be passing the textbox value to ajax here and making the check at server side
var $one = $('#oneClueShow');
var x = $("#clueOneInput").find('input[type=text]').val();
if(x == 'd' || x == 'dr')
{
//if answer correct you should load data from ajax and append it to a container
$.ajax({
type: "POST",
url: "includes/post_clue_progress",
data: { clueOne: "1", usernameClue: "<?php echo $manager; ?>" }
})
.done(function( msg ) {
// msg is any data that is echoed in the php script or output to screen is some way
$("#clueWrongOne").hide();
$("#mySecondDiv").remove();
$("#clueOne").remove();
$("#clue1Input").remove();
$one.show();
$("#clueOneInputCorrect").slideDown('slow').show();
$i++;
});
}
else
{
$("#mySecondDiv").remove();
var mySecondDiv = $('<div id="mySecondDiv"><img src="images/check-x-mark.png" /></div>').show('slow');
$('#clueWrongOne').append(mySecondDiv);
}
}
});
// =====clue 2====================////////////////// clue 2**********************************************************************========================
$(document).on('click', '.btn-clueTwo', function(){
if($i!=1){
var $two = $('#twoClueShow');
var x = $("#clueTwoInput").find('input[type=text]').val();
if(x == 'CS' || x == 'CSU')
{
$.ajax({
type: "POST",
url: "includes/post_clue_progress",
data: { clueTwo: "1", usernameClue: "<?php echo $manager; ?>" }
})
.done(function( msg ) {
// msg is any data that is echoed in the php script or output to screen is some way
$("#clueWrongTwo").hide();
$("#mySecondDivClueTwo").remove();
$("#clueTwo").remove();
$("#clue2Input").remove();
$two.show();
$("#clueTwoInputCorrect").slideDown('slow').show();
$i++;
});
}
else
{
$("#mySecondDivClueTwo").remove();
var mySecondDivClueTwo=$('<div id="mySecondDivClueTwo"><img src="images/check-x-mark.png" /></div>').show('slow');
$('#clueWrongTwo').append(mySecondDivClueTwo);
}
}
});
In your Jquery
$.ajax({
type: "POST",
url: "yourScriptToUpdateDB.php",
data: { clue: "Wrong", user: "JoeBob" }
})
.done(function( msg ) {
// msg is any data that is echoed in the php script or output to screen is some way
$("#clueWrongOne").hide();
});
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¶m=' + 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, ...) {
...
});
I have added an ajax loader to my code below. The problem is when the data from database is over, still the scroll function is going to an infinite loop and also the ajax scroll image is displayed. I want to stop the scroll function once the data is finished and also disable the ajax loader image. THis is my code
var counter=25;
$(window).on('scroll',function(){
if($(window).scrollTop()==($(document).height()-$(window).height())){
$('div#lastPostsLoader').html('<img src="loading-icon.gif">');
//Get older posts
$.ajax({
type: 'POST',
url: 'getdata.php?start_row=' + counter,
success: function(oldposts){
if(oldposts)
{
//Append #postsDiv
$('#data').append(oldposts);
counter += 15;
}
else
{
$('#lastPostsLoader').hide();
}
}
});
}
});
Try with this:
var counter = 25;
$(window).on('scroll', function () {
if ($(window).scrollTop() == ($(document).height() - $(window).height())) {
$(document).ajaxStart(function() {
$('div#lastPostsLoader').html('<img src="loading-icon.gif">');
});
$.ajax({
type: 'POST',
url: 'getdata.php?start_row=' + counter,
success: function (oldposts) {
if ($('#data')) {
$('#data').append(oldposts);
counter += 15;
}
}
});
$(document).ajaxComplete(function() {
$('div#lastPostsLoader').find('img[src^="loading"]').remove();
});
}
});
If i am not wrong, in the success function, if you get the data, you should hide the loader there itself. I am not getting what is the purpose of hiding the $('#lastPostsLoader') in the else part ???
From what I understand is that you are hiding the loader if you dont get any data.
#pavan
if ($('#data')) {
//if you have data process your business logic.
}
else
{
//Hide the loader.
//remove the event handler you can use .off for it.
}
For removing event handler http://api.jquery.com/off/
I have a pinterest style site and made a jquery script that spaces the cubes evenly no matter how big the browser is. For some reason on page load it has some overlapping cubes which didn't exist before. I talked with the guy that helped me make it and he said it's probly because of the code before the code that creates the blocks and positions them. It crashes the javascript.
I think it's because of the $(window).scroll ajax loading code but I can't seem to pinpoint the problem. I tried moving positionBlocks(); around and nothing changes. If you load the page in your browser and then change your browser size then it positions them correctly but obviously I want it to look right when the user first gets there.
function setupBlocks() {
windowWidth = $(window).width();
blocks = [];
// Calculate the margin so the blocks are evenly spaced within the window
colCount = Math.floor(windowWidth/(colWidth+margin*2));
spaceLeft = (windowWidth - ((colWidth*colCount)+margin*2)) / 2;
spaceLeft -= margin;
for(var i=0;i<colCount;i++){
blocks.push(margin);
}
positionBlocks();
}
function positionBlocks() {
$('.block').each(function(i){
var min = Array.min(blocks);
var index = $.inArray(min, blocks);
var leftPos = margin+(index*(colWidth+margin));
$(this).css({
'left':(leftPos+spaceLeft)+'px',
'top':min+'px'
});
blocks[index] = min+$(this).outerHeight()+margin;
});
}
// Function to get the Min value in Array
Array.min = function(array) {
return Math.min.apply(Math, array);
};
var curlimit=<?php echo $curlimit; ?>;
var totalnum=<?php echo $num_rws; ?>;
var perpage=<?Php echo $perpage ?>;
var working_already=false;
$(document).ready(function() {
//($(window).scrollTop() + $(window).height() )> $(document).height()*0.8
// old ($(window).scrollTop() + $(window).height() == $(document).height())
$(window).resize(setupBlocks);
$(window).scroll(function() {
if(($(window).scrollTop() + $(window).height() )> $(document).height()*0.90 && totalnum>0 && working_already==false ) {
} else return false;
working_already=true;
$("div#loading_bar").fadeIn("slow");
curlimit=curlimit+perpage;
$("div#loading_data_location").html("");
$.get('get_cubes.php?page=<?php echo $_GET['page'] ?>&curlimit='+curlimit, function(response) {
$("div#loading_data_location").html(response);
$("div#ColumnContainer").append($("div#loading_data_location").html());
$("a#bigpic").fancybox({
'onComplete' : imageLoadComplete,
'onClosed' : imageClosed,
'type': 'ajax' });
if ($("div#loading_data_location").text()=="")
totalnum=0;
else
totalnum=<?php echo $num_rws; ?>;
$('.like:not(.liked)').click(like_box);
$('.save:not(.saved)').click(save_box);
$('.follow:not(.following)').click(follow);
$("div#loading_bar").fadeOut("fast");
$("div#loading_data_location").html('');
setupBlocks();
working_already=false;
});
});
I had to add this to the end of my script:
<script language="javascript">
$(window).bind("load", function() {
setupBlocks();
});
</script>
and then this to the end of the on scroll ajax load. Sometimes jquery just needs a little kick in the face haha:
setTimeout(function(){setupBlocks();},100);
I have this
"fsField" is the class of all elements in the form. So whenever the user blurs to another field it submits the form using the function autosave() - given below. It saves data when the user blurs but when the user clicks the button with class "save_secL" to go to next page it does not save.
$('.fsField').bind('blur', function()
{
autosave();
}
});
but when i use this code
$('.save_secL').click(function()
{
var buttonid = this.id;
{
var answer = confirm("You have left some questions unanswered. Click OK if you are sure to leave this section? \\n Click CANCEL if you want stay in this section. ");
if(!answer)
{
var spl_items = valid().split(',');
$(spl_items[0]).focus();
return false;
}
else
{
$('#hidden_agree').append('<input id="secLuseragreed" name="secL_user_agreed" value="unanswered" type="hidden" />');
autosave();
window.location= buttonid+".php"
}
}
else
{
$('#hidden_agree').append('<input id="secLuseragreed" name="secL_user_agreed" value="answered all" type="hidden" />');
autosave();
window.location= buttonid+".php"
}
}
});
**autosave_secL.php is the php source thats saving the data in the database. I ran it independently and it does save data okay. **
function autosave()
{
var secL_partA_ques_1_select = $('[name="secL_partA_ques_1_select"]').val();
var secL_partA_ques_1 = $('[name="secL_partA_ques_1"]:checked').val();
var secL_partA_ques_2_select = $('[name="secL_partA_ques_2_select"]').val();
$.ajax(
{
type: "POST",
url: "autosave_secL.php",
data: "secL_partA_ques_1_select=" + secL_partA_ques_1_select + "&secL_partA_ques_1=" + secL_partA_ques_1 + "&user_id=<?php echo $row_token[user_id]?>" + "&updated_by=<?php echo $member."-".$key;?>",
cache: false,
success: function()
{
$("#timestamp").empty().append('Data Saved Successfully!');
}
});
}
**
valid() is a validation function that checks if any field is empty and returns a value if there is an empty field.**
function valid()
{
var items = '';
$('.fsField').each(function()
{
var thisname = $(this).attr('name')
if($(this).is('select'))
{
if($(this).val()=='')
{
var thisid = $(this).attr('id')
items += "#\"+thisid+\",";
$('[name=\"'+thisname+'\"]').closest('td').css('background-color', '#B5EAAA');
}
}
else
{
$('[name=\"'+thisname+'\"]').closest('td').css('background-color', '');
}
});
return items;
}
Can anyone please help? i am stuck for a day now. Can't understand why it saves when the user goes field to field but does not save when button is clicked with validation.
Tested with Firefox. this line appears in red with a Cross sign beside when the button(save_secL class) is clicked. I am using a ssl connection.
POST https://example.com/files/autosave_secL.php x
Here is the modified code trying to implement the solution
$('#submit_survey_secL').click(function()
{
if(valid() !='')
{
var answer = confirm("You have left some questions unanswered. Are you sure you want to Submit and go to Section B? ");
if(!answer)
{
var spl_items = valid().split(',');
$(spl_items[0]).focus();
return false;
}
else
{
$('#hidden_agree').append('<input id=\"secLuseragreed\" name=\"secL_user_agreed\" value=\"unanswered\" type=\"hidden\" />');
autosave(function(){
window.location= "part1secM.php?token=1&id=4"
});
}
}
else
{
$('#hidden_agree').append('<input id=\"secLuseragreed\" name=\"secL_user_agreed\" value=\"unanswered\" type=\"hidden\" />');
autosave(function(){
window.location= "part1secM.php?token=1&id=6"
});
}
});
function autosave(callback)
{
var secL_partL_ques_1_select = $('[name="secL_partL_ques_1_select"]').val();
var secL_partL_ques_1 = $('[name="secL_partL_ques_1"]:checked').val();
var secL_partL_ques_2_select = $('[name="secL_partL_ques_2_select"]').val();
$.ajax(
{
type: "POST",
url: "autosave_secL.php",
data: "secL_partL_ques_1_select=" + secL_partL_ques_1_select + "&secL_partL_ques_1=" + secL_partL_ques_1 + "&user_id=<?php echo $row_token[user_id]?>" + "&updated_by=<?php echo $member."-".$key;?>",
cache: false,
success: function()
{
$("#timestamp").empty().append('Data Saved Successfully!');
if($.isFunction(callback))
{
callback();
}
}
});
}
I don't understand why this doesn't work as callback should totally work. Firebug does not show POST https://example.com/files/autosave_secL.php in red any more but it shows that it has posted but I think the callback is not triggering for some reason
$('.save_secL').click(function() {
//...
//start autosave. Note: Async, returns immediately
autosave();
//and now, before the POST request has been completed, we change location...
window.location= buttonid+".php?token=$row_token[survey_token]&$member=$key&agr=1"
//....and the POST request gets aborted :(
Solution:
function autosave(callback)
{
//...
$.ajax(
{
//...
success: function()
{
$("#timestamp").empty().append('Data Saved Successfully!');
if($.isFunction(callback))
callback();
}
});
}
//and
autosave(function(){
window.location= buttonid+".php?token=$row_token[survey_token]&$member=$key&agr=1"
});
By the way, your autosave function is pretty hard for your server. Did you consider using localStorage + a final POST request containing all data?
I got the solution.
It might be one of the several. scr4ve's solution definitely helped. So here are the points for which I think its working now.
Moved "cache: false, " and removed "async:false" before url: in the ajax autosave function. Before I was putting it after "data: "
Added a random variable after autosave_secL.php/?"+Match.random()
Added scr4ve's solution so that POST is completed before redirect