I've created a sample NodeJS application that uses a lot of the same concepts (using Express and some jQuery on the client-side).
WORKING EXAMPLE: http://runnable.com/U3JEKcrGzPc1V8eQ/promises-w-bluebird-for-node-js-and-express
Using a basic Express application where an initial form is rendered using EJS
(this is the GET
request on /
). Form submissions return a POST
request to the same URL and are handled with a 2s delay to simulate a database action.
/**
* Create a global storage variable as a example of an
* attached local database
*/
GLOBAL.linkStorage = [];
app.route('/')
.post(function(req, res){
console.log("Submission: " + req.body);
GLOBAL.linkStorage.push(req.body.link);
renderDelayedResponse(res);
})
.get(function(req, res){
res.render('form.ejs');
});
app.route('/2')
.get(function(req, res) {
// No need to pass in GLOBAL.linkValue since it's checked automatically
res.render('submission.ejs');
});
/**
* Delay the response by a few seconds to simulate a database
* create/update action
*/
function renderDelayedResponse(respWriter) {
setTimeout(function() {
GLOBAL.viewCount++;
respWriter.send('Action Completed');
}, 2000);
}
There are going to be problems with calling window.open()
after an asynchronous action, the popup blocker fires in all cases through my tests. To workaround this, you can see that the example has an embedded IFRAME
that refreshes (after the 2 second database save completes) and displays the submitted value.
The complexity is mostly handled through jQuery where the IFRAME
refresh occurs after we know that the POST
request has submitted:
<!doctype html>
<html>
<head>
<style>
.busy {
cursor: wait !important;
}
</style>
<script type="text/javascript" src="http://code.jquery.com/jquery-git.js"></script>
<script type="text/javascript">
$('document').ready(function () {
function refreshViewer() {
window.open("/2", "viewer");
document.getElementById('submissionFrame').contentWindow.location.reload(true);
}
$('form input#submitLink').on('click', function () {
var linkValue = $('input#link').serialize();
$('body').addClass('busy');
$.post('/', linkValue)
.done(function(data) {
$('body').removeClass('busy');
$('input#link').val('');
refreshViewer();
});
return false;
});
});
</script>
</head>
<body>
<div class="container">
<form id="urlarticle" method="POST">
<input type="text" name="link" placeholder="Link" id="link" />
<input type="button" value="Submit" id="submitLink" />
</form>
<iframe id="submissionFrame" src="/2" seamless="seamless" width="50%" style="margin-top:100px">
</iframe>
</div>
</body>
</html>