GithubHelp home page GithubHelp logo

bureaucrat's Introduction

Bureaucrat

Form handling for Ruby inspired by Django forms.

Description

Bureaucrat is a library for handling the processing, validation and rendering of HTML forms.

Structure of a Form

                 Form ----> valid?, errors/cleaned_data
            ______|________
          /       |         \
      Field     Field      Field  ----> clean
        |         |          |
      Widget    Widget     Widget ----> render

Form: Collection of named Fields, handles global validation and the last pass of data conversion. After validation, a valid Form responds to cleaned_data by returning a hash of validated values and an invalid Form responds to errors by returning a hash of field_name => error_messages.

Field: Handles the validation and data conversion of each field belonging to the Form. Each Field is associated to a name on the parent Form.

Widget: Handles the rendering of a Form field. Each Field has two widgets associated, one for normal rendering, and another for hidden inputs rendering. Every type of Field has default Widgets defined, but they can be overriden on a per-Form basis.

Usage examples

require 'bureaucrat'
require 'bureaucrat/quickfields'

class MyForm < Bureaucrat::Forms::Form
  extend Bureaucrat::Quickfields

  string  :nickname, max_length: 50
  string  :realname, required: false
  email   :email
  integer :age, min_value: 0
  boolean :newsletter, required: false

  # Note: Bureaucrat doesn't define save
  def save
    user = User.create!(cleaned_data)
    Mailer.deliver_confirmation_mail(user)
    user
  end
end

# A Form initialized without parameters is an unbound Form.
unbound_form = MyForm.new
unbound_form.valid? # => false
unbound_form.errors # => {}
unbound_form.cleaned_data # => nil
puts unbound_form.as_p
# Prints:
# <p><label for="id_nickname">Nickname:</label> <input type="text" name="nickname" id="id_nickname" maxlength="50" /></p>
# <p><label for="id_realname">Realname:</label> <input type="text" name="realname" id="id_realname" /></p>
# <p><label for="id_email">Email:</label> <input type="text" name="email" id="id_email" /></p>
# <p><label for="id_age">Age:</label> <input type="text" name="age" id="id_age" /></p>
# <p><label for="id_newsletter">Newsletter:</label> <input type="checkbox" name="newsletter" id="id_newsletter" /></p>

invalid_bound_form = MyForm.new(nickname: 'bureaucrat', email: 'badformat', age: '30')
invalid_bound_form.valid? # => false
invalid_bound_form.errors # {email: ["Enter a valid e-mail address."]}
invalid_bound_form.cleaned_data # => nil
puts invalid_bound_form.as_table
# Prints:
# <tr><th><label for="id_nickname">Nickname:</label></th><td><input type="text" value="bureaucrat" name="nickname" id="id_nickname" maxlength="50" /></td></tr>
# <tr><th><label for="id_realname">Realname:</label></th><td><ul class="errorlist"><li>This field is required</li></ul><input type="text" name="realname" id="id_realname" /></td></tr>
# <tr><th><label for="id_email">Email:</label></th><td><ul class="errorlist"><li>Enter a valid e-mail address.</li></ul><input type="text" value="badformat" name="email" id="id_email" /></td></tr>
# <tr><th><label for="id_age">Age:</label></th><td><input type="text" value="30" name="age" id="id_age" /></td></tr>
# <tr><th><label for="id_newsletter">Newsletter:</label></th><td><input type="checkbox" name="newsletter" id="id_newsletter" /></td></tr>

valid_bound_form = MyForm.new(nickname: 'bureaucrat', email: '[email protected]', age: '30')
valid_bound_form.valid? # => true
valid_bound_form.errors # {}
valid_bound_form.cleaned_data # => {age: 30, newsletter: false, nickname: "bureaucrat", realname: "", :email = >"[email protected]"}
puts valid_bound_form.as_ul
# Prints:
# <li><label for="id_nickname">Nickname:</label> <input type="text" value="bureaucrat" name="nickname" id="id_nickname" maxlength="50" /></li>
# <li><ul class="errorlist"><li>This field is required</li></ul><label for="id_realname">Realname:</label> <input type="text" name="realname" id="id_realname" /></li>
# <li><label for="id_email">Email:</label> <input type="text" value="[email protected]" name="email" id="id_email" /></li>
# <li><label for="id_age">Age:</label> <input type="text" value="30" name="age" id="id_age" /></li>
# <li><label for="id_newsletter">Newsletter:</label> <input type="checkbox" name="newsletter" id="id_newsletter" /></li>

valid_bound_form.save # A new User is created and a confirmation mail is delivered

Examples of different ways of defining forms

require 'bureaucrat'
require 'bureaucrat/quickfields'

class MyForm < Bureaucrat::Forms::Form
  include Bureaucrat::Fields

  field :nickname, CharField.new(max_length: 50)
  field :realname, CharField.new(required: false)
  field :email, EmailField.new
  field :age, IntegerField.new(min_value: 0)
  field :newsletter, BooleanField.new(required: false) 
end

class MyFormQuick < Bureaucrat::Forms::Form
  extend Bureaucrat::Quickfields

  string  :nickname, max_length: 50
  string  :realname, required: false
  email   :email
  integer :age, min_value: 0
  boolean :newsletter, required: false
end

def inline_form
  f = Class.new(Bureaucrat::Forms::Form)
  f.extend(Bureaucrat::Quickfields)
  yield f
  f
end

form_maker = inline_form do |f|
  f.string  :nickname, max_length: 50
  f.string  :realname, required: false
  f.email   :email
  f.integer :age, min_value: 0
  f.boolean :newsletter, required: false
end

bureaucrat's People

Contributors

foca avatar gonz avatar neaf avatar rfc6919 avatar tizoc avatar

Stargazers

 avatar  avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.