Created
February 14, 2012 22:44
-
-
Save clarkf/1831242 to your computer and use it in GitHub Desktop.
Backbone FormView Helper
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /*! | |
| * Backbone BootstrapForm | |
| * Copyright (c) 2012 Clark Fischer <[email protected]> | |
| * V0.0.1 | |
| * MIT Licensed | |
| * | |
| * This extension depends on Backbone.FormView.js: | |
| * <https://gist.github.com/1831242#file_backbone.form_view.js> | |
| */ | |
| /*global Backbone, $*/ | |
| /*jslint browser: true, indent: 4, sloppy: true */ | |
| //BootStrapForm extension of FormView | |
| Backbone.BootstrapForm = Backbone.FormView.extend({ | |
| //Show alert -- prepends a div.alert.alert-error to the form | |
| showAlert: function (msg) { | |
| var $form = this.$('form'), | |
| $alert = $form.find('.alert'); | |
| if (!$alert.length) { | |
| $alert = $('<div />') | |
| .addClass('alert alert-error') | |
| .css('display', 'none'); | |
| $form.prepend($alert); | |
| $alert.slideDown('fast'); | |
| } | |
| $alert.html(msg); | |
| }, | |
| //markField - Marks the .control-group instead of the actual form element | |
| markField: function ($field, status, message) { | |
| var $e = $field.siblings('.help-inline'), | |
| $group = $field.parents('.control-group'); | |
| if (!status) { | |
| if (!$e.length) { | |
| $e = $('<div />') | |
| .addClass('help-inline') | |
| .css('display', 'none'); | |
| $field.after($e); | |
| $e.slideDown('fast'); | |
| } | |
| $e.html(message); | |
| $group.addClass('error'); | |
| } else { | |
| $group.addClass('success'); | |
| if ($e.length) { | |
| $e.slideUp('fast', $e.remove); | |
| } | |
| } | |
| }, | |
| //unmarkField - Removes the mark | |
| unmarkField: function ($field) { | |
| $field.parents('.control-group').removeClass('error warning success'); | |
| } | |
| }); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /*! | |
| * Backbone FormView | |
| * Copyright (c) 2012 Clark Fischer <[email protected]> | |
| * V0.0.1 | |
| * MIT Licensed | |
| */ | |
| /*global Backbone, $*/ | |
| /*jslint browser: true, indent: 4, sloppy: true */ | |
| Backbone.FormView = Backbone.View.extend({ | |
| //Validation bootstrapper -- This should be called once the form is | |
| //attached to the DOM. | |
| addValidation: function () { | |
| this.$('input').blur(this.validate.bind(this)); | |
| this.$('form').submit(this.submit.bind(this)); | |
| }, | |
| //Mark a field - Mark `$field` as `status` (ie valid or not). Optional | |
| //`message`. | |
| markField: function ($field, status, message) { | |
| var $e = $field.siblings('.message'); | |
| if (!status) { | |
| if (!$e.length) { | |
| $e = $('<div />').addClass('message').css('display', 'none'); | |
| $field.after($e); | |
| $e.slideDown('fast'); | |
| } | |
| $e.html(message); | |
| $field.addClass('error'); | |
| } else { | |
| $field.addClass('success'); | |
| if ($e.length) { | |
| $e.slideUp('fast', $e.remove); | |
| } | |
| } | |
| }, | |
| //Unmark the field - Resets the field to its original state | |
| unmarkField: function ($field) { | |
| $field.removeClass('error warning success'); | |
| }, | |
| //Show an alert message | |
| showAlert: function (e) { | |
| var $form = this.$('form'), | |
| $a = $form.find('.alert'); | |
| if (!$a.length) { | |
| $a = $('<div />') | |
| .addClass('alert') | |
| .css('display', 'false'); | |
| $form.prepend($a); | |
| $a.slideDown('fast'); | |
| } | |
| $a.html(e); | |
| }, | |
| //Validate the form. Does not check for required fields | |
| validate: function () { | |
| var valid = true, | |
| self = this; | |
| this.$('input').each(function () { | |
| var $i = $(this), | |
| id = $i.attr('name'), | |
| val = $i.val(), | |
| v; | |
| self.unmarkField($i); | |
| if (self.validators[id] && val.length) { | |
| v = self.validators[id](val); | |
| self.markField($i, !!v[0], v[1]); | |
| valid = valid && !!v[0]; | |
| } | |
| }); | |
| return valid; | |
| }, | |
| //Check required fields | |
| checkRequired: function () { | |
| var self = this, | |
| valid = true; | |
| $.each(this.required, function (i, rf) { | |
| var $field = self.$('input[name="' + rf + '"]'), | |
| pass = !!$field.val().length; | |
| if (!pass) { | |
| self.markField($field, false, 'Required field'); | |
| } | |
| valid = valid && pass; | |
| }); | |
| return valid; | |
| }, | |
| //Submission handler. Basically, before submission is sent, it validates | |
| //the form and checks for required fields. | |
| submit: function (event) { | |
| event.stopPropagation(); | |
| if (this.validate() && this.checkRequired()) { | |
| //Submit | |
| this.performSubmission(); | |
| } | |
| return false; | |
| }, | |
| //Performs the submission. Turns form into AJAXy form. | |
| performSubmission: function () { | |
| var self = this, | |
| $form = self.$('form'); | |
| $.ajax({ | |
| type: $form.attr('method'), | |
| url: $form.attr('action'), | |
| data: $.param($form.find('input, select, checkbox, option, radio')) | |
| }) | |
| .done(this.submissionSuccess.bind(this)) | |
| .fail(this.submissionFailure.bind(this)); | |
| }, | |
| //Submission success handler -- Please override this | |
| submissionSuccess: function (data) { | |
| throw new Error("Backbone.FormView#submissionSuccess must be " + | |
| " overridden!\nReturned data: " + data); | |
| }, | |
| //Submission failure -- Please override this | |
| submissionFailure: function (xhr, status, error) { | |
| throw error; | |
| } | |
| }); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| //MyForm -- a simple example of a registration form. Make sure we extend | |
| //`Backbone.FormView`. If you use Twitter's awesome Bootstrap, extend the | |
| //`Backbone.BootstrapForm` object. | |
| var myForm = Backbone.FormView.extend({ | |
| tagName: 'div', | |
| template: app.templates.myForm, | |
| //Validators | |
| //Validators receive the value of the field and return an array. The first | |
| //element in the array is true/false, indicating whether or not the field | |
| //is valid. The second element is optional, and designates a message to | |
| //be shown next to the field. | |
| //The key of the validation function should map to the `name` attribute of | |
| //the input. | |
| validators: { | |
| username: function (v) { | |
| if (v == 'root') { | |
| //This will mark the field as invalid, and display a message | |
| //next to it. | |
| return [false, "Nice try, buddy"]; | |
| } | |
| if (/[^a-z0-9-]/i.test(v)) { | |
| //See above | |
| return [false, "Username must be alphanumeric!"]; | |
| } | |
| return [true]; | |
| }, | |
| //We'll exclude the password field, since we'll accept any kind of | |
| //password | |
| confirm: function (v) { | |
| if (this.$('input#password').val() !== v) { | |
| //The password confirmation does not equal the password! | |
| return [false, "Passwords don't match"]; | |
| } | |
| return [true]; | |
| }, | |
| email: function (v) { | |
| if (/\@aol\.com/i.test(v)) { | |
| return [false, "Get a new email address. It's not 1992 anymore"]; | |
| } | |
| return [true]; | |
| } | |
| birthYear: function (v) { | |
| if (+v > ((new Date).getFullYear() - 13)) { | |
| return [false, "You must be at least 13 to use this site."] | |
| } | |
| return [true]; | |
| } | |
| }, | |
| //Required | |
| //Required is simply an array of the `name` attributes of the required | |
| //fields. | |
| required: ['username', 'password', 'confirm', 'email', 'birthYear', | |
| 'gender', 'receiveNewsletter', 'hairColor', | |
| 'preferredDietBeverage'/*, etc...*/], | |
| submissionSuccess: function (data) { | |
| //`data` now contains whatever the server returned. Do something cool. | |
| this.$('form').slideUp(); | |
| this.$el.append("Hey, you signed up. Choose your own adventure!"); | |
| showAdventureChoiceDialogue(); | |
| }, | |
| submissionFailure: function (xhr, status, error) { | |
| this.showAlert("It looks like something went wrong somewhere.<br>" + | |
| "The server sent us some garbage. We'll look into it."); | |
| }, | |
| render: function () { | |
| this.$el.html(this.template.render()); | |
| } | |
| }); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment