eForm - Examples


Using eForm's eformOnBeforeMailSent event


This example/ tutorial will show you how to call an external function using the onBeforeMailSent event and what you can do with such an event.

The scenario is a continuation from our last example. To fill you in or refresh your memory, we set up a job request form for a translation agency where clients can either type in an article into a text box or attach a text file. A second form in on the same page allowed existing clients to request a progress report, for which they needed a job number. In the example the translation agency would receive an email and would then have to assign a job number and follow up manually.

With eForm we can do better. We're going to extend eForm using it's events structure to provide the jobNumber automatically and have this included in the report which is sent to the office and to the client. Below is a repeat of the original job request form and a slightly enhanced report. The second form from the previous example has been ignored in this example.

The Job Request Form

View or hide an image of the form.

The form Template

<form action="[~[*id*]~]" method="post" enctype="multipart/form-data">
    <input type="hidden" name="formid" value="newJob" />
        <legend>Your personal details</legend>
            <input class="field" type="text" name="fullName" maxlength="60" eform="Your Name:string:1:Your Full Name is required" />
            <input class="field" type="text" name="email" size="40" maxlength="40" eform="Email Address:email:1" />
        <legend>Article Details</legend>
        <p class="explain">You can provide a summary and the main article below or alternatively supply the material
        in an attachment. Currently we support the following formats: Ms Word, Adobe Acrobat (pdf), html or plain text.</p>
        <textarea class="field" name="summary" eform="Summary:html:1" rows="3" cols="30"></textarea></p>
        <textarea class="field" name="article" eform="Article:html:1" rows="10" cols="30"></textarea></p>
        <p><label for="attachment">Attachment</label>       
        <input class="field" type="file" name="attachment" accept="text/plain,application/msword,application/rtf,application/pdf,text/html" eform="Attachment:file:0" /></p>
            <input type="radio" name="format" value="legal" eform="Return Format::1" >&nbsp;Legal       
            <input type="radio" name="format" value="formal">&nbsp;Formal       
            <input type="radio" name="format" value="loose" checked="checked"">&nbsp;Informal
            <select name="language" eform="language::1>
                <option value=""></option>
                <optgroup label="English">
                    <option value="en-au">Australian</option>
                    <option value="en-gb">UK English</option>
                    <option value="en-us">US English</option>
                <optgroup label="French">
                    <option value="fr">France</option>
                    <option value="fr-be">Belgian French</option>
                    <option value="fr-ca">Canadien French</option>
                    <option value="fr-ch">Swiss French</option>
                    <option value="fr-gp">Guadaloupe French</option>
                    <option value="fr-gy">Guyana French</option>
                    <option value="fr-mr">Martinique French</option>
        <p class="explain">       
            <input type="submit" name="frmGo" value="Send Job" />

Note! In the above template we use a hidden field for the formid: <input type="hidden" name="formid" value="newJob" />
If you are using eForm 1.4 you can instead use the id attribute of the form tag itself and leave out the hidden field: <form id="newJob" action="[~[*id*]~]" method="post" enctype="multipart/form-data">. Either way will work

The (adjusted) Report template

<p>Here are the details for <strong>[+subject+]</strong> with Job Number: <strong>[+jobNumber+]</strong></p>
	<tr valign="top"><td>Client Name:</td><td>[+fullName+]</td></tr>
	<tr valign="top"><td>Client Email:</td> <td>[+email+]</td></tr>
	<tr valign="top"><td>Summary:</td> <td>[+summary+]</td></tr>
	<tr valign="top"><td>Article:</td> <td>[+article+]</td></tr>
	<tr valign="top"><td>Attachment:</td> <td>[+attachment+]</td></tr>
	<tr valign="top"><td>Create translation in format:</td> <td>[+format+]</td></tr>
	<tr valign="top"><td>Destination language:</td> <td>[+language+]</td></tr>
	<tr valign="top"><td>Job Number:</td> <td>[+jobNumber+]</td></tr>

The eformOnBeforeMailSent and eformOnMailSent events

We can intercept the flow of eForm using the 2 events eForm exposes via the &eFormOnBeforeMailSent and &eFormOnMailSent parameters. When you set these to a function name eFrom will try to call this function. The events are triggered as follows:

The function should accept one parameter, the $fields array. The $fields array contains all the form values and other placeholder content with the field names as the key. The function should return either a true or false value. Currently when a false is returned eForm will return immediately without outputting the form or any messages however this may change in the future.

It is important that you declare the $fields parameter as a reference inside the function so that you manipulate the original values otherwise the function would be working on a copy of the array and changes you make would be lost once the function exits.(if you're getting confused by now, stop reading this and open the php manual at www.php.net/manual/language.references.php

//$fields as a reference
function someFunction( &$fields ){ ... }

Well be adding an extra value instead of changing any form values. We'll write a simple function that creates a job number based on the clients initials and the current date/time and add this to the $fields array under the key 'jobNumber'. If you look at the report template above you'll notice there's an extra placeholder for this.

	//create job number based on initials and current date/time
	function createJobNumber( &$fields ){
		$jobNum = '';
		foreach{ explode(' ',$fields['fullName'],3) as $nm)
			$jobNum .= strtoupper(substr($nm,0,1));
		$jobNum .= date('ymdHi');
		//set extra value in fields array
		$fields['jobNumber']= $jobNum;
		//return succes
		return true;

All very well that we've written a function but how do we get it into MODx? I'm sure there's multiple ways of doing that but I've simply created an extra snippet called eFormEvent with the 'createJobNumber' function as the only content. That way it's only loaded when using the form. To make it available to eForm we place a call to this snippet on the same page, just before we call the eForm snippet (It needs to be first as otherwise it's not parsed by the time eFrom needs it).

All that remains is to add the &eformOnBeforeMailSent parameter to the eform snippet call with the function name. To finish this example off here are the eFormEvent snippet and both snippet calls that need to reside on the form page.

NOTE! Just a reminder that this will only work in eFrom version 1.3.1 and above! In earlier versions the &eformOnBeforeMailSent and &eformOnMailSent parameters were not available! (Although I've made the events work in earlier versions by tweaking eForm a bit I ran into trouble with more then one form on the same page.)

Snippet eFormEvent

//functions for eForm events
function createJobNumber( &$fields ){
	//rest of function code as above
//return empty string
return ''; 

The snippet calls

	[!eForm? &formid=`newJob` &subject=`New Translation Job` &sendirect=`1` &eformOnBeforeMailSent=`createJobNumber` &tpl=`jobForm` &report=`jobReport` &noemail=`1` &thankyou=`jobReport`!]

Note that I've added the &noemail=`1` &thankyou=`jobReport` parameters. They're not necessary but I use them to see the result in the browser while testing instead of having to wait for emails. Remove them if you want to see the actual generated emails coming into your mailbox.

We could take this approach a lot further offcourse. You could for instance store the information in a database or filter the values but we'll leave that to your own imagination.


Jelle Jager