Skip to content

Instantly share code, notes, and snippets.

@mattpodwysocki
Created April 2, 2012 23:36
Show Gist options
  • Save mattpodwysocki/2288047 to your computer and use it in GitHub Desktop.
Save mattpodwysocki/2288047 to your computer and use it in GitHub Desktop.
<!DOCTYPE html>
<head>
<style type="text/css">
.saved { border: 3px solid green; }
.unsaved { border: 3px solid red; }
</style>
<script src="jquery-1.7.2.min.js"></script>
<script src="rx.js"></script>
<script src="rx.time.js"></script>
<script src="rx.jquery.js"></script>
<script>
// Shim for local storage as observable
var draftServer = (function (global, root) {
var key = "RXJS-DRAFTKEY123"
, globalStorage = {}
, getDraft = function () {
var text = !global.localStorage
? globalStorage[key]
: JSON.parse(global.localStorage.getItem(key));
text || (text = { text: '', date: new Date() });
return root.Observable.returnValue(text);
}
, saveDraft = function (text) {
var item = { text: text, date: new Date() };
if (!global.localStorage) {
globalStorage[key] = item;
} else {
localStorage.setItem(key, JSON.stringify(item));
}
return this.getDraft();
};
return {
getDraft: getDraft,
saveDraft: saveDraft
};
})(window, Rx);
$(function () {
var textArea = $('#myText')
// Capture the text on keyup
, textObseravble = textArea.onAsObservable('keyup').select(function(x) {
return $(x.currentTarget).val();
})
// Save either by distinct throttled text or save button
, saveBehavior = Rx.Observable.merge(
textObseravble.throttle(2000).distinctUntilChanged(),
$('#saveButton').onAsObservable('click')
)
// Populate the initial value
, initialValue = draftServer.getDraft().select(function (x) {
return x.text;
});
initialValue.subscribe(function (initial) {
// Populate initial field
textArea.val(initial);
$('#curDraft').html(initial);
// Save draft and repopulate the saved draft
saveBehavior.selectMany(function () {
return draftServer.saveDraft(textArea.val());
}).subscribe(function (x) {
$('#curDraft').html(x.text);
});
// merge saved and unsaved behaviors only when things change
var statusBehaviors = Rx.Observable.merge(
textObseravble.distinctUntilChanged().select(function () {
return 'unsaved';
}),
saveBehavior.select(function () { return 'saved'; })
).startWith('saved');
// Update class based upon status
statusBehaviors.subscribe(function (x) {
textArea.removeClass().addClass(x);
});
});
});
</script>
</head>
<body>
<p>Drafts are associated with your current session and are stored on the
server. Sessions last for an hour. Drafts are saved every five seconds and
whenever you click <i>Save Now</i>. If you reload the page, the draft will be
loaded from the server.</p>
Last Saved: <span id='savedTime'></span>
<form>
<span id="inputPlaceholder"><textarea id="myText" rows="10" cols="50"></textarea></span><br/>
<input type='button' id='saveButton' value='Save Now'/>
</form>
<p>The currently saved draft is:</p>
<div><span class="block" id="curDraft"></span></div>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment