Jan 11 2008

SMERF Homepage Finished

etienne @ 2:17 pm

I’ve now completed the SMERF web site. On the site you will find details about SMERF including documentation, download information and so on. To go to the site now click on this link.


Jan 09 2008

SMERF Released!

etienne @ 5:21 pm

 

Update 11 January 2008: SMERF web site completed.

I’m happy to announce the release of SMERF V0.0.1!

I’m still in the process of setting up the official web site but the source is now available for download. The README file contains a lot of information about the plugin including installation and configuration notes. You can also checkout the documentation in the rdoc directory which includes the API docs and the README in a more readable format.

There are several ways to download SMERF:

Direct download

Get it from RubyForge

Subversion

**Create a new smerf directory in your /vendor/plugins directory and change into the new directory

Check out the stable release

svn checkout http://smerf.rubyforge.org/svn/stable .

or Check out a particular release

svn checkout http://smerf.rubyforge.org/svn/tags/REL-0.0.1 .

or Check out the development code

svn checkout http://smerf.rubyforge.org/svn/trunk .

See the README for details of how to install and configure the plugin.

Until I get my bug tracker sorted out if you have any problems please feel free to contact me on smerf at cascadia dot com dot au.

Enjoy!

 


Jan 02 2008

Announcing SMERF - Simple MEta Rails Form

etienne @ 6:18 pm

 

Update 11 January 2008: SMERF web site completed.

Update 9 January 2008: SMERF Released! 

Update 8 January 2008: I’ve completed the documentation and testing. I’ve created a project on RubyForge which is waiting approval. If this is not ready by tomorrow I will make an alternate link available for download, so if all goes well I should have a download available tomorrow.

I am putting the final touches to a new plugin called SMERF which stands for Simple MEta Rails Form. The plugin is a result of me extracting the code I used for one of my projects which I discussed in an earlier article Ruby on Rails Survey Builder.

I’ve spend the past few weeks rewriting parts of it to make it more generic so that it can be used for all sorts of things including survey’s, questionnaires, data collection forms and so on. Some of the important changes I’ve made include

  • Allow question validations to be written using Ruby code. You can now create your own validation methods as required, there are also a couple of standard system validation methods that come with the plugin. You can specify any number of validation methods for a question by comma separating each method name, e.g. validation: validate_mandatory_question, validate_date_format
  • User responses are now stored in a DB table allowing you to perform analysis on the question responses using SQL.

ToDo V0.2

  • Currently there are no tests
  • Allow forms to be broken into smaller forms, currently you get all questions on a single form
  • Allow the save of user responses as you move from form to form

I’m currently writing a plugin generator that will make installation of the plugin easier, hopefully I’ll have this done very soon. I then need to finish the documentation which is mostly done.

I will keep you informed and let you know when the plugin will be available.

 


Oct 21 2007

Ruby on Rails Survey Builder

etienne @ 7:17 pm

 

Update 9 January 2008: SMERF Released!

Update 2 January 2008: Announcing SMERF - Simple MEta Rails Form plugin

Over the past few weeks I have been developing a general purpose survey/questionnaire builder that makes it easy to create a new survey, present it to the user, record the user’s responses in a database, and allow the user to recall and update the responses. It’s still in it’s infancy and I will add more functionality as required, for now it’s functional enough to meet all the requirements of the current project.

To create a new survey we define the content of the survey using a YAML file. I decided to use YAML as it seems to be the defacto standard for Rails, it’s simple and has a nice hierarchical structure which suits the way surveys are structured.

Survey Structure

Each survey is made up of any number of question groups, within each group there are any number of questions. Questions can accept free form text or present a list of options to the user. In some cases a particular answer may require additional information, this can be done using subquestions. Subquestions can be nested to any depth, i.e. a subquestion can present a set of answers, which in turn can present another subquestion with another set of answers and so on. The diagram below shows the structure of a survey:

  Survey Structure

 

Defining the Survey

When setting up a new survey the first thing we do is define some settings for the survey as a whole. Currently the following items can be defined for the survey:

  • name: Name of the survey (mandatory)
  • welcome: Message displayed at the start of the survey (optional)
  • thank_you: Message displayed at the end of the survey (optional)
  • group_sort_order_field: Nominates which group field to use when sorting groups for display (mandatory)
  • groups: Defines the question groups within the survey (mandatory)

Here is the definition for our demo survey:


survey:
  name: Demo

  welcome: |
    <b>Welcome:</b><br>
    Thank you for taking part in our demo survey we appreciate your
    input.<br><br>

    <b>PRIVACY STATEMENT</b><br>
    We will keep all the information you provide private and not share
    it with anyone else….<br>

  thank_you: |
    <b>Thank you for your input.</b><br><br>

    Should you wish to discuss this survey please contact<br>
    Joe Bloggs<br>
    Tel. 12 345 678<br>
    e-mail <A HREF=\"
mailto:jbloggs@xyz.com.au\">Joe’s email</A><br><br>
 
    February 2007

  group_sort_order_field: code-

  groups:
  …

 As you can see from the example you are able to embed any HTML code within the text.

Defining Groups

Each survey is divided up into groups of questions, you must have at least one group per survey. Here are the fields that are currently available when defining a group:

  • code: This code must be unique for all groups within the survey as it is used to identify each group (mandatory)
  • name: The name of the group, this is displayed as the group heading (mandatory)
  • description: Give a more detailed description/instructions for the group (optional)
  • questions: Defines all the questions contained within this group (mandatory)

Here is the definition for the Personal Details group of the Demo survey:

  groups:
    personal_details:
      code: 1
      name: Personal Details
      description: | A brief description of this group…
      questions:
      …

Group example

 

Defining Questions 

A group can contain any number of questions, there must be at least one question per group. When defining a question you must specify the question type, the type determines the type of form field that will be created. There are currently four types that can be used, this will be expanded as needed. The current question types are:

  • multiplechoice: Allows the user to select all of the answers that apply from a list of possible choices, check boxes are used for this question type as multiple selections can be made
  • singlechoice: Allows the user to select one answer from a list of possible choices, radio buttons are used for the question type as only a single answer can be selected
  • textbox: Allows the user to enter a large amount of free text, the size of the text box can be specified
  • textfield: Allows the user to enter a small amount of free form text, the size of the text field can be specified

Question types

The following fields can be used to define a question:

  • code: Unique code that will identify the question, the code must be unique within a survey (mandatory)
  • type: Specifies the type of field that should be constructed on the form for this question, see above list for current types (mandatory)
  • question: The text of the question, this field is optional as subquestions do not have to have question text
  • textbox_size: Specifies the size of the text box to construct, rows x cols, defaults to 30×5 (optional)
  • textfield_size: Specified the size of the text field that should be constructed, specified in the number of visible characters, default to 30 (optional)
  • header: Specifies a separate heading for the question. The text will be displayed above the question allowing questions to be broken up into subsections (optional)
  • required: Specifies that an answer is required for this question
  • sort_order: Specifies the sort order for the question
  • help: Help text that will be displayed below the question
  • answers: Defines the answers to the question if the question type displays a list of possibilities to the user

 Below is an example question definition:

      questions:
        which_industry:
          code: g2q1
          type: multiplechoice
          sort_order: 1
          question: | Which industries have you worked in 
          help: | Mark <b>all</b> that apply                
          answers:
          …

Question example

 

Defining Answers

If the question presents a list of possible answers to the user then we can easily define these answers by using the following fields:

  • code: Code to uniquely identify the answer, code needs to be unique for each question (mandatory)
  • answer: The text that will be displayed to the user (mandatory)
  • default: If set to Y then this answer will be selected by default (optional)
  • sort_order: The sort order for this answer (mandatory)
  • subquestions: Some answers may need additional information, another question can be defined to obtain this information. To define a subquestions the same fields that define a normal question is used (optional)

Here is an example answer definition:

           answers:
            it:
              code: 1
              answer: | Information Technology
              sort_order: 1
              default: N
              subquestions:
              …

Defining Subquestions 

Additional questions can be defined for an answer if more information is required if the user selects the answer. For example you may have an answer ‘Other’ that required additional information from the user. A subquestion can be defined for the ‘Other’ answer that takes an additional input from the user. To define a subquestion you use the same fields as for a normal question (Refer to the Defining Question section above).

Below is an example subquestion definition:

              subquestions:
                other_industries:
                    code: g2q1a4s1
                    type: textbox
                    sort_order: 1
                    question:
                    help: | Please specify
                    textbox_size: 30×3
 

Subquestion example

 

 

Data Store

There are three tables used by the survey builder, a surveys table that stores the survey details, a surveys_users table that stores a users answers for a survey and finally the users table.

When a user selects to view a survey the system checks the survey definition file to see if any changes have been made since the last time the survey was loaded, if it has the survey definition file is processed and validated. A set of classes and objects are created that describes the survey including SurveyFile, SurveyGroup, SurveyQuestion, SurveyAnswer, these are serialized to YAML format and stored in a single database field within the surveys table. If no changes have been made to the definition file then the survey is simply read from the surveys table and serialized from YAML with all classes and objects reconstructed.

User survey answers are stored  in the surveys_users table in a single field within the table. The answers are serialized to YAML and stored in the database field, the classes and objects are reconstructed when the record is retrieved.

Validation and Errors

The only validation currently performed  is to check that mandatory questions have been answered. In the near future I will be expanding validations by adding the ability to use regular expressions to validate the format of answers. I’m also thinking about allowing Ruby code to be specified to construct validation code that can be executed to check answers.

When an error is detected, a summary of the errors are displayed at the top of the form, additionally an error message is displayed for each question that has an error. This makes it very easy for the user to see which question they need to fix.

Error example

 

 Complete Example

Here is the complete survey definition fie for the Demo survey:


survey:
  name: Demo
  welcome: |
    <b>Welcome:</b><br>
    Thank you for taking part in our demo survey we appreciate your
    input.<br><br>

    <b>PRIVACY STATEMENT</b><br>
    We will keep all the information you provide private and not share
    it with anyone else….<br>

  thank_you: |
    <b>Thank you for your input.</b><br><br>

    Should you wish to discuss this survey please contact<br>
    Joe Bloggs<br>
    Tel. 12 345 678<br>
    e-mail <A HREF=\"
mailto:jbloggs@xyz.com.au\">Joe’s email</A><br><br>
 
    February 2007
  group_sort_order_field: code

  groups:
   
personal_details:
      code: 1
      name: Personal Details
      description: | A brief description of this group…
      questions:
       
specify_your_age:
          code: g1q1
          type: singlechoice
          sort_order: 1
          question: | Specify your age 
          help: | Select the <b>one</b> that apply
          required: Y
          answers:
            1_20:
              code: 1
              answer: | 1-20
              sort_order: 1
              default: N
           
21_40:
              code: 2
              answer: | 21_40
              sort_order: 2
              default: N
            >40:
              code: 3
              answer: | > 40
              sort_order: 3
              default: N
              subquestions:
               
>40:
                  code: g1q1a3s1
                  type: singlechoice
                  sort_order: 1
                  question: | Are you aged over 40
                  help: | Select the <b>one</b> that apply
                  answers:
                    41_50:
                      code: 1
                      answer: | 41-50
                      sort_order: 1
                      default: N
                    51_60:
                      code: 2
                      answer: | 51_60
                      sort_order: 2
                      default: N
                    >61:
                      code: 3
                      answer: | > 61
                      sort_order: 3
                      default: N

        are_you_married:
          code: g1q2
          type: singlechoice
          sort_order: 2
          question: | Are you married 
          help:
          required: N
          answers:
            no:
              code: 1
              answer: | No
              sort_order: 1
              default: Y
            yes:
              code: 2
              answer: | Yes
              sort_order: 2
              default: N

    employment_details:
      code: 2
      name: | EMPLOYMENT DETAILS
      description: | Brief description of the employment details group 
      question_sort_order_field: sort_order
      questions:
        which_industry:
          code: g2q1
          type: multiplechoice
          sort_order: 1
          question: | Which industries have you worked in 
          help: | Mark <b>all</b> that apply               
          answers:
            it:
              code: 1
              answer: | Information Technology
              sort_order: 1
              default: N
            accounting:
              code: 2
              answer: | Accounting
              sort_order: 2
              default: N
            finance:
              code: 3
              answer: | Finance
              sort_order: 3
              default: N
            other:
              code: 4
              answer: | Other
              sort_order: 4
              default: N
              subquestions:
                other_industries:
                    code: g2q1a4s1
                    type: textbox
                    sort_order: 1
                    question:
                    help: | Please specify
                    textbox_size: 30×3

        how_many_years:
          code: g2q3
          type: textfield
          sort_order: 3
          header:
          question: | How many years have you worked in the industry
          textfield_size: 10
          help:

Complete example