Introduction

This module is intended to minimize the tedious work handling typical email forms and similar things that one often encounters on web pages.

The basic parts of this module dates back to the days of OpenCms 5. The functionality provided by the Structured Contents introduced in OpenCms 6 partly overlaps with the functionality provided by this module. But there are differences when it comes to how they solve the task at hand. The API in this module is simpler for simpler forms, but for more complex forms where you need "nested" values and likewise, you should use Structured Contents.
If you need to map the values from the forms to a database table, the included simple persistence layer may also prove to be a timesaver.

The module includes a couple JSPs in the elements-folder of the module-folder. Form.jsp and FormMail.jsp can be included in a template or likewise, and then be controlled by means of various properties (consult the JSP to see which properties can be set). FormMail.jsp is intended to make it easy to let visitors on the website to fill in form and have the result emailed to the given recipients.

Two of the major parts of the module are the form handling and persistence handling:

Form handling

A form is defined by an XML file, the format is fairly simple and readable:

<?xml version="1.0" encoding="UTF-8"?>
<form>
  <ident>DevNews</ident>
  <fields>
    <private>
      <name>active</name>
      <value>true</value>
    </private>
    <private>
      <name>newsletterType</name>
      <value>cd-developer</value>
    </private>
    <text>
      <name>email</name>
      <label>Your email address*</label>
      <validators>
        <required>
          <error>Please fill in the field.</error>
        </required>
        <email>
          <error>The email address is not valid.</error>
        </email>
      </validators>
    </text>
    <submit>
      <name>action</name>
      <label>Subscribe</label>
    </submit>
  </fields>
</form>

The API form.toHTML() renders the above as a form with one field and one button (the "private" fields are server-side only, as opposed to hidden fields which really are not so private):

form-render-example

Upon submit the values are collected from the request and validated with a couple of lines:

form.collectValues(request);
int errorCnt = form.validateValues();
The data collected by the form can be used to compose an email, it can be dumped as XML or it can be pushed to the database. The elements-folder in the module contains a couple of examples on how to do this.

Persistence handling

This is a simple abstraction layer intended to save one from the tedious work of mapping values to columns in the database, and the even worse task of writing the SQL.

If your are familiar with ORMs tools like Hibernate, Cayenne or Enterprise Objects (and others), you already know how much time these can save you. The abstraction layer in this module does not try to compete with any of them in terms of functionality, but was created to provide an easy way to persist data collected with the above mentioned forms functionality. Of course, it can be used to store similar types of data from other sources as well.

The basis is an entity description expressed in XML, which among other things tells how fields should mapped to columns:

<?xml version="1.0" encoding="UTF-8"?>
<entity>
  <name>Subscription</name>
  <class>com.codedroids.records.MapRecord</class>
  <table>cd_subscriptions</table>
  <ident scheme="sequence">id</ident>
  <fields>
    <field>
      <name>id</name>
      <type>Integer</type>
      <column>id</column>
    </field>
    <field>
      <name>active</name>
      <type>Boolean</type>
      <column>active</column>
    </field>
    <field>
      <name>email</name>
      <type>String</type>
      <column>email</column>
    </field>
    <field>
      <name>newsletterType</name>
      <type>String</type>
      <column>newsletter_type</column>
    </field>
  </fields>
</entity>
The class given is the type of object to persist, here it is basically a map. Usings maps allows for a fairly dynamic behaviour: add the field in the above file (which is stored in the virtual file system and add the column to the appropriate table and you are ready to store data in the new column, no need to restart the instance or the like.
You have to create the appropriate table in the database yourself so it matches the entity specification, but once that is done, you won't have to write another line of SQL...

Given a populated form like the above listed example you can save the contents of the form in the "subscriptions" table by using the above entity-example along with a few lines of code:

String file = "/some/vfspath/Subscriptions.rec.xml";
RecordFactory factory = OCRecordFactory.registerFactory(cmsObject, file);
I_Record cd = factory.getNewInstance();
form.pushToRecord(cd);
factory.saveRecord(cd);

This will save a new record in the table with a unique id.

To complement the persistence functionality there is an API for fetching data as well, including a way to build "where" clauses.

AndClause where = new AndClause();
where.addClause( new GenericClause(factory, "newsletterType", "=", "cd-developer") );
where.addClause( new GenericClause(factory, "active", "=", Boolean.TRUE) );
OrderBy orderBy = new DescendingOrderBy(factory, "email");
List subscriptions = factory.fetchRecords(where, orderBy);

The list returned by fetchRecords() contains objects with the class specified in the record XML file. In this example it is MapRecord's - basically maps, i.e. no structure besides what is defined in the record XML.

The persistence layer has been tested with MySQL 4.x and 5.

Documentation

The OpenCms User's Guide is licensed under the Creative Commons Attribution-No Derivative Works 2.5 License.

Documentation: forms-guide.pdf (appr. 250 KB).

License

This module and source code is licensed under the GNU Lesser General Public License, see http://www.gnu.org/licenses/lgpl.html for more information.

This module is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Download

For OpenCms 6:  com.codedroids.oc.forms_1.0.1.zip (appr. 176 KBytes).

Source code:  com.codedroids.oc.forms_1.0.1-src.zip (appr. 190 KBytes).

If you have comments or suggestions you are welcome to email them to us (support@codedroids.com) but we cannot guarantee that we will act upon them or even respond to them.
If you need to get some issue solved or a new feature added we do provide consulting and support at reasonable rates, you can contact us here.

If you want to be informed when a new version of this or other of our modules are released, you can sign up to receive our Tech newsletter.

Dependencies

This module requires some third-party jars which is not a part of the opencms 6 distribution:

json-lib-1.0.jar - download it from JSON-lib.
ezmorph-1.0.jar - download it from EZMorph.
commons-lang-2.2.jar - download it from Apache Jakarta Commons Lang.

Note that Apache commons HTTPClient 3.x is required in case authenticated access via the HTTPClient API is needed (OpenCms 6.0.x came with HTTPClient 2.x which fails to properly authenticate). This module does not itself require this functionality but other modules that depends on it may require it (such as the Newsletter module):

commons-httpclient-3.x - download it from Apache Jakarta Commons HttpClient.

Installation

Makes sure that the required jars are placed in ... opencms/WEB-INF/lib/-directory (replace "opencms" with whatever appropriate if you have installed OpenCms under a different name).

Then install this module via the Module Management in the Administrative view in OpenCms.

Restart the instance or you servlet container and you should be ready to go.