Auto Submit Forms, No Double Sending With Feedback
Forked to handle change tracking, i.e. if 2 edits close together do NOT send first, also with UI feedback of progress. Update only after change, and lost focus, to facilities an "auto-save" like concept.
by NickJosevski
HTML
<form id="MyFormId">
<fieldset>
<legend>Some Form</legend>
<div id="last-action"><em>What's going on:</em><br /><br />
<div id="la-text"></div>
<div id="fast-bind"><em>Stats:</em><br /><span id="fast-span"></span></div>
</div>
<!-- NOTE: after 8 attempts the div will overflow, I chose not to handle this :p -->
<div class="editor-label">
<label for="GUID">GUID</label>
</div>
<div class="editor-field">
<label id="GUID">29e3a04a-a7fe-41dc-974a-9285d3872cfe</label>
</div>
<div class="editor-label">
<label for="Deadline">Deadline</label>
</div>
<div class="editor-field">
<input id="Deadline" name="Deadline" type="text" value="" />
<img src="http://nickjosevski.wordpress.com/wp-admin/images/wpspin_light.gif"
class="ajax-loading" id="Deadline-loading" alt="">
</div>
<div class="editor-label">
<label for="Name">Task Name</label>
</div>
<div class="editor-field">
<input id="Name" name="Name" type="text" value="" />
<img src="http://nickjosevski.wordpress.com/wp-admin/images/wpspin_light.gif"
class="ajax-loading" id="Name-loading" alt="">
</div>
<div class="editor-label">
<label for="Description">Description</label>
</div>
<div class="editor-field">
<input id="Description" name="Description" type="text" value="" />
<img src="http://nickjosevski.wordpress.com/wp-admin/images/wpspin_light.gif"
class="ajax-loading" id="Description-loading" alt="">
</div>
</fieldset>
</form>
CSS
div#last-action
{
float:right;
margin-right:50px;
height:200px;
width:200px;
background-color:navy; color:white;
}
div#fast-bind
{
margin-right:50px;
margin-top:190px;
height:450px;
width:200px;
background-color:#8064A2; color:black;
}
fieldset
{
margin: 1em 0;
padding: 1em;
border: 1px solid #CCC;
}
fieldset p
{
margin: 2px 12px 10px 10px;
}
.display-label,
.editor-label,
.display-field,
.editor-field
{
margin: 0.5em 0;
}
.text-box
{
width: 30em;
}
JavaScript
var activeInputs;
var check = 'http://upload.wikimedia.org/wikipedia/commons/d/d9/Green_check.png';
var busy = 'http://nickjosevski.wordpress.com/wp-admin/images/wpspin_light.gif';
var redX = 'http://upload.wikimedia.org/wikipedia/commons/7/7e/Red_x.png';
(function($) {
activeInputs = {};
$(':input').change(function() {
var c = $(this);
$.when(
c.focusout()).then(function() {
pushToControlList(c);
startCountDownAndSendData(c, 5); //delay by 5 seconds
});
});
})(jQuery);
function getInputId(c){
return c.attr('id');
}
function showSuccess(data) {
//var feedbackItem = data[i] + '-loading';
//$('.process').append('<img id="checkmark" src="/Content/check.png" />');
var msgs = "";
for (var i = 0; i < data.length; i++) {
msgs += data[i] + "<br />";
}
$('#fast-bind').html(msgs);
}
function pushToControlList(c){
var elemId = getInputId(c);
var countVal = pushModifiedControlOnProcessingStack(elemId);
$('#fast-span').append('added ' + elemId + ' with # ' + countVal + '<br />');
}
function pushModifiedControlOnProcessingStack(elemId){
var countVal = 1;
if(activeInputs[elemId] == null)
activeInputs[elemId] = 1;
else
{
activeInputs[elemId] = countVal = activeInputs[elemId] + 1;
}
return countVal;
}
function popProcessedControlFromStack(elemId){
var countVal = -1;
if(activeInputs[elemId] == null)
return -1; //erorr state
if(activeInputs[elemId] > 1)
{
countVal = activeInputs[elemId];
activeInputs[elemId] = activeInputs[elemId] - 1;
}
else
{
countVal = activeInputs[elemId];
//is this enough? we check for null in the push method, so for now ok...
activeInputs[elemId] = null;
}
return countVal;
}
function startCountDownAndSendData(c, waitDuration) {
function go() {
if (waitDuration <= 0)...