Skip to content

Instantly share code, notes, and snippets.

@kangax
Last active October 17, 2015 05:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kangax/477f0233e9ab74669c7f to your computer and use it in GitHub Desktop.
Save kangax/477f0233e9ab74669c7f to your computer and use it in GitHub Desktop.
bacon vs. backbone vs. react (just seeing how bacon's paradigm compares with other approaches)
var RegisterForm = Backbone.View.extend({
ui: {
username: '.username',
fullname: '.fullname',
register: '.register-btn',
loader: '.loader',
feedback: '.feedback'
}
events: {
'input username, fullname': 'onInput',
'click register': 'onRegisterClick'
},
onInput: function() {
_.throttle(_.bind(function() {
this.ui.register.prop('disabled',
!this.ui.username.val() || !this.ui.fullname.val());
this.checkAvailability(this.ui.username.val());
}, this), 100);
},
checkAvailability: function(username) {
this.ui.loader.show();
this.ui.registerButton.hide();
$.get('/availability', { username: username })
.done(_.bind(function(result) {
this.ui.loader.hide();
this.ui.registerButton.show();
this.showAvailability(result);
this.applyAvailability(result);
}, this));
},
showAvailability: function(result) {
this.ui.feedback
.html(result ? 'Available' : 'Not available')
.toggle(result);
},
applyAvailability: function(result) {
this.ui.register.prop('disabled', result ? false : true);
},
onRegisterClick: function() {
this.ui.register.prop('disabled', true);
this.ui.loader.show();
$.post('/register', {
username: this.ui.username.val(),
fullname: this.ui.fullname.val()
})
.done(_.bind(function() {
this.ui.registerButton.prop('disabled', false);
this.ui.loader.hide();
this.ui.feedback.show();
}, this));
return false;
}
});
function nonEmpty(x) { return x.length > 0 }
function setVisibility(element, visible) {
element.toggle(visible)
}
function setEnabled(element, enabled) {
element.attr("disabled", !enabled)
}
$(function() {
$(".ajax").hide()
registerButton = $("#register button")
unavailabilityLabel = $("#username-unavailable")
usernameAjaxIndicator = $("#username .ajax")
registerAjaxIndicator = $("#register .ajax")
// Inputs
username = Bacon.UI.textFieldValue($("#username input"))
fullname = Bacon.UI.textFieldValue($("#fullname input"))
// Streams / Properties
usernameEntered = username.map(nonEmpty)
fullnameEntered = fullname.map(nonEmpty)
availabilityRequest = username.changes().map(function(user) {
var restUrl = ({ url: "/usernameavailable/" + user })
return restUrl
})
availabilityResponse = availabilityRequest.ajax()
usernameAvailable = availabilityResponse.toProperty(true)
buttonEnabled = usernameEntered.and(fullnameEntered).and(usernameAvailable)
// Side-effects
buttonEnabled.assign(setEnabled, registerButton)
usernameAvailable.not().assign(setVisibility, unavailabilityLabel)
})
var RegisterForm = React.createClass({
getInitialState: function() {
return {
username: '',
fullname: ''
}
},
checkAvailability: function() {
this.setState({ isFetching: true });
$.get('/availability', { username: this.state.username })
.done(function(result) {
this.setState({
isAvailable: result.isAvailable,
isFetching: false
});
}.bind(this));
},
componentWillMount: function() {
this.checkAvailability = _.debounce(this.checkAvailability, 100);
},
handleSubmit: function(e) {
e.preventDefault();
$.ajax({
url: this.props.url,
type: 'POST',
data: {
username: this.state.username,
fullname: this.state.fullname
},
success: _.bind(function(data) {
this.setState({ isAvailable: data.isAvailable });
}, this)
});
},
onUsernameChange: function(event) {
this.setState({ username: event.target.value });
},
onFullnameChange: function(event) {
this.setState({ fullname: event.target.value });
},
getUsernameStatus: function() {
return `Username ${ this.state.username } is
${ this.state.isAvailable ? 'available' : 'not available' }`;
},
render: function() {
return (
<form onSubmit={this.handleSubmit}>
<p>{this.getUsernameStatus()}</p>
<input value={this.state.username} onChange={this.onUsernameChange} />
<input value={this.state.fullname} onChange={this.onFullnameChange} />
<input type="submit" value="Register"
disabled={!this.state.isAvailable || this.state.isFetching} />
<p>{this.state.isFetching ? 'Fetching' : ''}</p>
</form>
);
}
});
ReactDOM.render(
<RegisterForm url="/register" />,
document.getElementById('container')
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment