JSFiddle - React, Tailwind, and code Playground
by mibrahim01
HTML
<!-- We could possibly store data like this in local storage too, after being pulled from the database -->
<datalist id="manufacturers">
<option value="Windows Direct Ltd">
<option value="Heating Supplies Ltd">
<option value="Wood Supplies and Design Ltd">
<option value="Spare Parts">
<option value="Fireplaces T/A Fire for Campervans">
<option value="Windows Direct">
</datalist>
<datalist id="features">
<option value="18' alloy wheels">
<option value="Upgraded tyres">
<option value="Water heater">
<option value="Solar panels">
<option value="Glass roof">
<option value="Sports exhaust">
</datalist>
<div id="isOnline">Your navigator is</div>
<div>
<pre>Use Chrome Inspect > Network > Offline to go offline. Turning wifi off does not work in this example (polling a live service or use of service workers may be needed in the actual app)
Inspect > Application > Local Storage will show all stored data when offline
Network > XHR will show the post requests once back online</pre>
</div>
<h2>My form</h2>
<form action="/echo/json/" method="post" id="myForm">
<p>
<label>Manufacturer
<input type="text" list="manufacturers" placeholder="Enter value" name="manufacturer" />
</label>
</p>
<p>
<label>Feature
<input type="text" list="features" placeholder="Enter value" name="feature" />
</label>
</p>
<p>
<label>Optional
<input type="checkbox" name="optional" />
</label>
<label>Standard
<input type="checkbox" name="optional" />
</label>
</p>
<p>
<label>Score
<input type="text" name="score" size="3" />
</label>
</p>
<p>
<input type="submit" value="Send form" />
</p>
</form>
<h2>Log : </h2>
<div id="log"></div>
CSS
#isOnline {
background: #E22;
color: white;
text-align: center;
padding: 10px;
}
#isOnline:after {
content: ' offline';
}
#isOnline.online {
color: black;
background: #3D3;
}
#isOnline.online:after {
content: ' online. Try to turn it off before submitting the form.';
}
#myForm {
border: 1px solid black;
padding: 10px;
text-align: center;
}
#log {
border: 1px solid black;
padding: 10px;
min-height: 150px;
}
pre {
margin-left: 40px;
background: #CCC;
padding: 10px;
word-wrap: break-word;
white-space: pre-wrap; word-break: keep-all;
}
JavaScript
(function(e) {
function r() {
form = e(this);
if (navigator.onLine) {
if (n.onlineAjaxSend) {
if (n.beforeOnlineAjaxSend) {
n.beforeOnlineAjaxSend()
}
e.ajax({
type: form.attr("method"),
url: form.attr("action"),
data: form.serialize(),
success: function(e) {
if (n.onlineAjaxCallback) {
n.onlineAjaxCallback(e)
}
}
}).fail(function(e) {
if (n.onError) n.onError(e);
return false
});
return false
}
return true
}
action = form.attr("action");
if (action === "") action = document.location.href;
if (localStorage[n.key] === undefined) {
localStorage[n.key] = JSON.stringify([])
}
data = JSON.parse(localStorage[n.key]);
if (data.length) {
e.each(data, function(e, t) {
if (t === null) {
data.splice(e, 1)
}
})
}
if (n.beforeStorage) n.beforeStorage(data.length, data);
data.push({
action: action,
urlEncoded: form.serialize(),
method: form.attr("method")
});
if (n.onStorage) n.onStorage(data.length, data);
localStorage[n.key] = JSON.stringify(data);
return false
}
var t = {
key: "offlineForm",
classname: "offlineForm",
onlineAjaxSend: false,
autoSync: true,
beforeSync: null,
afterSync: null,
onSync: null,
beforeStorage: null,
onStorage: null,
onError: null,
beforeOnlineAjaxSend: null,
onlineAjaxCallback: null
};
var n = t;
var i = {
init: function(t) {
return this.each(function() {
n = e.extend(n, t);
form = e(this);
if (!form.hasClass(n.classname)) {
form.on("submit", r);
form.addClass(n.classname)
}
})
},
sync: function() {
if (localStorage[n.key] === undefined) return false;
else data = JSON.parse(localStorage[n.key]);
...