1

I want to refresh a web page until the download is done.After the download is complete,I don't want to refresh a page.How can I achieve this ? can anyone please help me out ...

My code:

<body onload="timedRefresh(10000);">

<script type="text/javaScript">
    function timedRefresh(timeoutPeriod) {
     setTimeout("window.location.reload(true);",timeoutPeriod);
    }
</script>

My app.js:

var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var fs = require('fs');
var request = require('request');
var progress = require('request-progress');
var targz = require('tar.gz');

var DOWNLOAD_DIR = '/usr/local/';
var file_name = 'googlenew.png' 


var routes = require('./routes/index');
var users = require('./routes/users');


var app = express ();
var http = require('http').createServer(app);
var io = require('socket.io')(http);


http.listen(8085, function(){
    console.log('listening on *:8085');
});

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');

// uncomment after placing your favicon in /public
//app.use(favicon(__dirname + '/public/favicon.ico'));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

app.use('/', routes);
app.use('/users', users);

app.get('/get', function (req, res) {
 res.sendfile('views/index.html');

});



var callback = function(state){
    console.log('received size in bytes', state.received);
    console.log('total size in bytes', state.total);
    console.log('percent', state.percent);
    io.of('/socket_issue').on('connection', function (socket) {
    console.log("Socket connected :"+socket.id);
 socket.emit('message', JSON.stringify({size: state.total, received: state.received, percent: state.percent, fileName: file_name}));
});

} 

progress(request('https://nodejs.org/dist/v0.12.7/node-v0.12.7.tar.gz'), {
    throttle:0,   
    delay: 0       
})
.on('progress', callback) 

.pipe(fs.createWriteStream(DOWNLOAD_DIR + file_name))
.on('error', function (err) {
 console.log("error");  
})
.on('close', function (err){
console.log("Download Complete"); 
})


// catch 404 and forward to error handler
app.use(function(req, res, next) {
    var err = new Error('Not Found');
    err.status = 404;
    next(err);
});

// error handlers

// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
    app.use(function(err, req, res, next) {
        res.status(err.status || 500);
        res.render('error', {
            message: err.message,
            error: err
        });
    });
}

// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
    res.status(err.status || 500);
    res.render('error', {
        message: err.message,
        error: {}
    });
});


module.exports = app;

My index.html :

<html>
<head>

<style>
    #progressbar {
        width: 400px;
        height: 22px;
        border: 1px solid #111;
        background-color: #292929;
    }
    #progressbar div {
        height: 100%;
        color: #fff;
        text-align: right;
        line-height: 22px; /* same as #progressBar height if we want text middle aligned */
        width: 0;
        background-color: #0099ff;

    }
</style>
</head>

<body onload="timedRefresh(10000);">

<script type="text/javaScript">
    function timedRefresh(timeoutPeriod) {
     setTimeout("window.location.reload(true);",timeoutPeriod);
    }
</script>
<script src="http://localhost:8085/javascripts/socket.js"></script>
<script src="https://code.jquery.com/jquery-1.10.2.js"></script>
<script src="http://localhost:8085/javascripts/bootstrap.js"></script>
<script src="http://localhost:8085/javascripts/bootstrap-progressbar.js"></script>
<script src="http://code.jquery.com/ui/1.10.4/jquery-ui.js"></script>
<link href="http://code.jquery.com/ui/1.10.4/themes/ui-lightness/jquery-ui.css" rel="stylesheet">
<link rel="stylesheet" type="text/css" href="http://localhost:8085/stylesheets/bootstrap.css" />

    <div id="progressbar"><div></div></div>

<script type="text/javascript">
var socket = io('http://localhost:8085/socket_issue');
  socket.on('connect', function(){ console.log('connected to socket'); });
  socket.on('error', function(e){ console.log('error' + e); });
  socket.on('message', function(data){
   console.log(data);


       function progress(percent, $element) {
        var progressBarWidth = percent * $element.width() / 100;
        $element.find('div').animate({ width: progressBarWidth }, 500).html(percent + "% ");
    }
    progress(JSON.parse(data).percent, $('#progressbar'));


  });
  socket.on('disconnect', function(){});
</script>
</body>
</html>

Here,the page is refreshing even though the download is complete.I don't want to refresh the page once the download is done. I'm trying to show the progress bar in the browser.

enter image description here

dev333
  • 713
  • 2
  • 17
  • 38
  • could you able to call a another function after complete download – Shailendra Sharma Nov 19 '15 at 08:59
  • http://stackoverflow.com/questions/11265917/javascript-source-file-download-progress – Vishnu Nov 19 '15 at 09:00
  • 1
    Where is your code for downloading? You need a callback or promise to achieve your goal... – Beat Nov 19 '15 at 09:00
  • A refresh of page will cause `Item to be download multiple time` beacuse it is a `HttpPost` request .. Try to show a wait screen instead – Moumit Nov 19 '15 at 09:00
  • You can't do this in pure Javascript. You'll need to query a server to tell you if the download finished. Check this question: http://stackoverflow.com/questions/1106377/detect-when-browser-receives-file-download – tb11 Nov 19 '15 at 09:01
  • yes Moumit Mondal,the item is downloading multiple times.What should I do in order to avoid this ? – dev333 Nov 19 '15 at 09:05
  • If the page is built with PHP, for example, you can write the JavaScript refresh code to the page if the download isn't ready yet. Then when the download is ready, the next time PHP encounters the user's session, you simply don't write the JavaScript to the page and instead give them a link to the download. – Ultimater Nov 19 '15 at 09:05
  • If the item is downloading multiple times, use the POST/REDIRECT/GET trick. – Ultimater Nov 19 '15 at 09:05
  • can u please edit the code here using promise (or) callback.I'm really stuck over here – dev333 Nov 19 '15 at 09:12

1 Answers1

1

Just check if the progress in 100%, then stop the timer.

<body>
<script type="text/javaScript">
var myVar;

function startTimer() {
    myVar = setTimeout(function(){ window.location.reload(true); }, 10000);
}
startTimer();
function myStopFunction() {
    clearTimeout(myVar);
}
</script>


<script type="text/javascript">
var socket = io('http://localhost:8085/socket_issue');
  socket.on('connect', function(){ console.log('connected to socket'); });
  socket.on('error', function(e){ console.log('error' + e); });
  socket.on('message', function(data){
   console.log(data);


       function progress(percent, $element) {
        if(percent==100)//Donwload complete
           myStopFunction();
        var progressBarWidth = percent * $element.width() / 100;
        $element.find('div').animate({ width: progressBarWidth }, 500).html(percent + "% ");
    }
    progress(JSON.parse(data).percent, $('#progressbar'));


  });
  socket.on('disconnect', function(){});
</script>

Emitting Event properly. I am not sure whether this code works, There might be scope issues, Just try.

io.of('/socket_issue').on('connection', function (socket) {
        console.log("Socket connected :"+socket.id);
    });
var callback = function(state){
    console.log('received size in bytes', state.received);
    console.log('total size in bytes', state.total);
    console.log('percent', state.percent);

     io.of('/socket_issue').emit('message', JSON.stringify({size: state.total, received: state.received, percent: state.percent, fileName: file_name}));

} 
Vishnu
  • 11,614
  • 6
  • 51
  • 90
  • Thanks a lot vishnu.It worked for me.Can't we get the gmail type of loading.Is there any possibility that without refreshing a html page,can we get the progress asynchronously. – dev333 Nov 19 '15 at 09:35
  • No need to refresh the page if you are using socket.io. Just emit the socket event from the server to the client, In client on message event change the progressbar percentage. – Vishnu Nov 19 '15 at 10:57
  • In the above,I just did the same.But the animation is not happening over thereIt is just sticking at one % .If I do a refresh of a html page,I'm getting the current progress % – dev333 Nov 19 '15 at 11:09
  • Just check your server code, You are emitting `mesage` event when a client is connected. If you refresh the page client gets connected and he will get the progress event. – Vishnu Nov 19 '15 at 11:43
  • Ya I'm getting the progress in the html page .do we need to refresh the html page ? Because I'm trying to have gmail type of progress bar – dev333 Nov 19 '15 at 12:04
  • no need you have to code correctly. Just see the updated answer. Change the callback function code. – Vishnu Nov 19 '15 at 12:07
  • progressBarWidth is not updating properly.If I refresh the page ,It is working properly – dev333 Nov 19 '15 at 12:35
  • Even though it finished 100%,it is showing as in the screen shot – dev333 Nov 19 '15 at 12:42
  • That is a UI problem, add a new question someone might help :-) – Vishnu Nov 19 '15 at 13:36
  • Hi vishnu,can u please check this link : http://stackoverflow.com/questions/33865515/how-to-get-the-progress-status-in-the-status-column-of-a-datatable-using-socke – dev333 Nov 23 '15 at 07:43