QuickForm Reference¶
Background¶
Data-entry forms in CiviCRM use an extended variation of PEAR's HTML_QuickForm system. In QuickForm, a web developer defines a new form by creating a "Form" class which implements certain methods (such as "buildForm") and which calls methods to add new form fields (or "elements"). Reference materials for the main QuickForm system can be found online:
- HTML_QuickForm Documentation Home
- HTML_QuickForm Tutorial
- HTML_QuickForm Element List
- (Old Blog) Summary of Page Processing Tools in CiviCRM
- Koumbit QuickForm Cheatsheet
The Basics¶
A typical form in CiviCRM looks like this:
class CRM_Example_Form extends CRM_Core_Form {
/**
* @var string - Note make variables public to allow form hooks access
*/
public $_foo;
/**
* This function is called prior to building and submitting the form
*/
public function preProcess() {
// Perform any setup tasks you may need
// often involves grabbing args from the url and storing them in class variables
$this->_foo = CRM_Utils_Request::retrieve('foo', 'String');
}
/**
* Will be called prior to outputting html (and prior to buildForm hook)
*/
public function buildQuickForm() {
// Add elements to the form
$this->add('text', 'my_text_field', ts('Enter Some Text'));
}
/**
* If your form requires special validation, add one or more callbacks here
*/
public function addRules() {
$this->addFormRule(array('CRM_Example_Form', 'myRules'));
}
/**
* Here's our custom validation callback
*/
public static function myRules($values) {
$errors = array();
if ($values['foo'] != 'abc') {
$errors['foo'] = ts('You entered the wrong text!');
}
return empty($errors) ? TRUE : $errors;
}
/**
* Called after form is successfully submitted
*/
public function postProcess() {
// get the submitted values as an array
$vals = $this->getSubmittedValues();
// Save to the database
civicrm_api3('foo', 'create', $vals);
}
}
Retrieving values from the form¶
In general you should stick to using functions tagged with @api to get functions from forms if
you are accessing them from outside the form.
The preferred methods to get the submitted values are $form->getSubmittedValues and $form->getSubmittedValue(). These methods will pass any fields identified as money fields
through a function to remove money formatting. Note that accessing ->_submitValues directly
is the same as checking $_POST - it bypasses any security.
In addition we try to add standard functions to core forms to get ids
-
ie
-
getEventID() getParticipantID()getContactID()getContributionPageID()getContributionID()getPriceSetID()getDiscountID()
And more recently in some forms
- getContactValue()
- getParticipantValue()
- getEventValue()
builQuickForm v buildForm
In CiviCRM Core, sometimes in sub classes e.g. in the Custom Search Sub classes, the function buildForm is used instead of buildQuickForm, However there will be a call in the parent function for buildQuickForm which then includes the subClasses buildForm. This is not standard for new form classes.
Form Elements¶
Basic Types¶
These basic elements can be added using CRM_Core_Form()->add()
| Type | Notes |
|---|---|
| text | Simple text box |
| textarea | Multirow text region. Good for fields like description |
| select | give it css class "crm-select2" to add select2 widget |
| advcheckbox | like "checkbox" element but normalizes data in postProcess |
| radio | Radio options |
| group | mainly useful to contain radios, see addRadio extended method |
| hidden | does not need to be added to the template |
| advmultiselect | takes up a lot of space - consider using select.crm-select2 |
| submit | Buttons generally used to either submit or cancel the form |
| password | Add a password field. The display will be replaced with dots |
Extended Types¶
CRM_Core_Form includes methods to add special types or sets of form elements not included in basic quickform. See code-level function documentation for details.
| Method | Used For | Notes |
|---|---|---|
| addButtons | form submit buttons | |
| addRadio | set of radio buttons | |
| addYesNo | radio buttons with preset 'Yes' & 'No' options | |
| addCheckbox | set of checkboxes | |
| addDateRange | set of "to" and "from" dates | requires an extra template to be included |
| addSelect | autogenerate a select, fetching title and option list from metadata | uses "select2" widget. also adds an "edit options" button visible to admin users note: to add a select2 that references an entity, see *addEntityRef** below* |
| addProfileSelector | widget by which users can select, create and edit a profile form | requires extra javascript files added using CRM_Core_Resources |
| addSelectOther | select or other option | requires extra javascript in the template |
| addUploadElement | file upload | |
| addCurrency | select currency | |
| addMoney | money field + select currency | |
| addEntityRef | autocomplete select of contacts, tags, events, etc. | EntityRef documentation |
Deprecated Form Elements¶
| Method | Was Used For | Notes |
|---|---|---|
| Datepicker Element | Use $form()->add('datepicker', ...) instead. |
|
| Datepicker with time Element | Use $form()->add('datepicker', ...) instead. |
|
| Rich text Area | Removed: Use $form()->add("wysiwyg", ... ) instead. |
|
| Country Select Field | Removed. Use AddSelect instead or addEntityRef |
Request Lifecycle¶

CiviCRM provides a more nuanced request lifecycle than traditional HTML_QuickForm. This extended request lifecycle allows the original web developer to create the form using a class – and allows third-party developers to modify the form using hooks. The request lifecycle is divided into a few phases, and each phase may have multiple steps. The phases and steps are presented in sequence:
Build Phase¶
Generate a set of HTML form fields ($form->addElement(), $form->add(), etc) and validation rules ($form->addFormRule()) to the form. (Note: The "Build" phase runs during the initial GET request and the subsequent POST request.)
| Step | Audience | Comments |
|---|---|---|
CRM_Core_Form::preProcess (override) |
Original Developer | In any subclass of CRM_Core_Form, the preProcess() function can be overridden. |
CRM_Core_Form::buildQuickForm (override) |
Original Developer | In any subclass of CRM_Core_Form, the buildQuickForm() function can be overridden. |
| hook_civicrm_buildForm | Third-Party Developer | |
CRM_Core_Form::addRules (override) |
Original Developer | In any subclass of CRM_Core_Form, the addRules() function can be overridden. |
Validate Phase¶
Examine submitted form data to determine validity. (Note: The "Validation" phase runs during the POST request.)
| Step | Audience | Comments |
|---|---|---|
| (Process rules) | Original Developer & Third-Party Developer | Iteratively process any rules added during the "build" phase (i.e. call any callbacks registered via $form()->addFormRule()). |
| hook_civicrm_validate | Third-Party Developer | (Note: This is similar to hook_civicrm_validateForm but older) |
| hook_civicrm_validateForm | Third-Party Developer | (Note: This is similar to hook_civicrm_validate; added in CiviCRM v4.2) |
Process Phase¶
Save the data, execute business logic, etc. (Note: The "Process" phase runs during the POST request – but only if the "Validation" was successful)
| Step | Audience | Comments |
|---|---|---|
CRM_Core_Form::postProcess (override) |
Original Developer | In any subclass of CRM_Core_Form, the postProcess() function can be overridden. |
| hook_civicrm_postProcess | Third-Party Developer |
Render Phase¶
Generate HTML using Smarty.
Note
The "Render" phase does not provide events or hooks to the PHP controller.