GithubHelp home page GithubHelp logo

zippy / metaform Goto Github PK

View Code? Open in Web Editor NEW
16.0 7.0 3.0 1.39 MB

A domain specific language for creating complex forms with separate data, presentation and workflow abstractions, for rails apps.

Home Page: http://hbe.lighthouseapp.com/projects/24508/home

License: MIT License

Ruby 97.29% CSS 0.30% JavaScript 2.42%

metaform's Introduction

Metaform

Metaform is a rails engine that provides a system for defining and generating forms for complex data-collection using a domain specific language (dsl) to create:

  • a data model and a specification of how that data is constrained
  • a presentation specification about how fields from forms will appear when displayed
  • workflows that specify the states a form can go through and actions that move a form from one state to another
  • listings to retrieve groups of forms based on arbitrary criteria
  • reports to retrieve aggregate information across forms
  • complex validation which includes the ability to not reject "invalid entries" but store them and record them as invalid
  • conditional data relations for creating "branching forms"

The system also includes a "widget" system that pre-defines a number of html widgets including radio-button and check-box groups, text-based date entry, etc.. which all include javascript handling for in browser use of widget values regardless of how they are displayed. For example, a date widget might be displayed as three text input boxes, but the widget generates javascript to get the true date value out of the widget directly.

Installation

Add this line to your application's Gemfile:

gem 'metaform'

And then execute:

$ bundle

Or install it yourself as:

$ gem install metaform

Then:

  1. Use the generator:

    $ bundle exec rails g metaform

This will add:

  • two migrations (which you need to rake db:migrate for)
  • the "forms" directory where you will define your forms using the metaform DSL (see below)
  • a javascript file to your public/javascripts
  • the default css stylesheet to public/stylesheets
  • records/show.html.erb and records/new.html.erb to app/views/ as sample views that use metaform to create forms
  1. Include the following helper in the head of your application layout: <%= include_metaform_assets %> This will load the javascripts and the stylesheets when needed. To tell this function when to load the assets simply add: <%@metaform_include_assets = true%> to the top of the view that shows a form.

Database dependencies

Currently Metaform can use mysql, postgres or sqlite 3 and detects which is in use on initialization. If you are using metaform to collect substantial amounts of data we recommend using postgres as it scales the best. In the works is converting Metaform to work with no-SQL databases (probably couchDB to start with) which should make Metaform truly scalable.

The Metaform Domain Specific Language (DSL)

Metaform defines an abstraction that separates data definition from data display. Much like you are used to in rails data model and views. To use the metaform definition language simply create a +forms+ directory in your rails app, with a file in it that ends in "form.rb" Metaform will auto-create a form class by the name of the file from definitions in the file.

Defining the data model-- fields with constraints, and workflows

fields

def_fields <field_options> do
	f <field_name>,<field_options>
end

<field_options> are: :type => <field_type> :constrants => :default => true | false :indexed_default_from_null_index => true|false :followups => { | ! | // => f(<field_name>, <field_options>) }

are a hash of key value pairs: 'required' => true | false 'regex' => '' 'range' => '-' 'set' => <value_label_pairs> 'enumeration' => <value_label_pairs>

<value_label_pairs> are an array of key value pairs of the form: [{ => <human_label>},...]

workflows

def_workflows <work_flow_name> do
	action <name>,[<legal_states>...] do |meta|
	  # the meta hash provides access to various things:
  # meta[:request] the request object
  # meta[:session] the session object
  # meta[:record] the record object
		...
		state <state_name>  # set the next state to go to
	end
end

directives

To load additional form definitions use:

include_definitions()

To load definitions at the class level (constants, helper methods etc) use:

include_helpers()

Defining display appearance == presentations, questions, and tabs

presentation <presentation_name>,<options (:legal_state, :indexed)> do ...

... end

Listings

Record has several methods for creating filtered lists of records. Record.search uses sql filters to have the database perform the filtering. Record.locate uses ruby filters, with an optional sql_prefilter. Record.locate first calls Record.search to process the sql_prefilter, if any. Then Record.locate calls Record.gather to perform the actual ruby filtering. If you have not passed an sql_prefilter to Record.locate, then Record.gather will do its ruby filtering on the entire database, which is time intensive. It may be fastest to use only one field_id in the sql_prefilter, so use the biggest limiter there and save the other limiting field_ids for the ruby filter.

Record.gather can also be called directly on a list of FormInstances which you pass in as a parameter or can be given a proc to create the list of FormInstances.

Record.search always returns an array of FormInstances, where Record.gather/locate can also return an answers hash. An answers hash will allow the handling of indexed fields.

Contributing

  1. Fork it
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create new Pull Request

Testing

Metaform uses RSpec for testing. The gem contains a dummy app with a couple of forms that exercise metaforms features and functionality. To setup the gem to run the specs:

  1. cd into the gem root directory
  2. run the bundle command to set up the development dependencies
  3. cd spec/dummy
  4. rake db:migrate
  5. rake db:test:prepare

Then from the gem root you can run the specs with:

bundle exec rspec spec

metaform's People

Contributors

somanyfish avatar zippy avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

Forkers

sourceops

metaform's Issues

test

test issue for metaform.

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.