webform_view.module in Webform view 7.4
Same filename and directory in other branches
Allows views to be embedded in webforms and used as submission data.
This does NOT save all that data in a fully webform-compatible way for reports, it just allows elements that were added on the fly to be processed as data for emails. Data is not available for later reporting.
USAGE.
Add a field 'can order' as a boolean flag on nodes that can be ordered.
Set its 'display' to be 'webform placeholder'
Make a view for the nodes you want to show on a webform. This view should display the 'webform placeholder' field.
Edit the webform and add this view as a webform field.
The placeholder on each node in the view will be replaced with a webform submission field.
File
webform_view.moduleView source
<?php
/**
* @file
* Allows views to be embedded in webforms and used as submission data.
*
*
* This does NOT save all that data in a fully webform-compatible way for
* reports, it just allows elements that were added on the fly to be processed
* as data for emails. Data is not available for later reporting.
*
* USAGE.
*
* Add a field 'can order' as a boolean flag on nodes that can be ordered.
*
* Set its 'display' to be 'webform placeholder'
*
* Make a view for the nodes you want to show on a webform.
* This view should display the 'webform placeholder' field.
*
* Edit the webform and add this view as a webform field.
*
* The placeholder on each node in the view will be replaced with a webform
* submission field.
*/
/**
* Declare our new component type for webform - an embedded view.
*
* Implements hook_webform_component_info().
*/
function webform_view_webform_component_info() {
$component_info = array(
'view' => array(
'label' => t('Embedded view'),
'description' => t('Allows a view to be embedded and each row in the view to be a selectable option.'),
'file' => 'webform_view.inc',
'features' => array(
'default_value' => FALSE,
'required' => TRUE,
'description' => FALSE,
'conditional' => FALSE,
'group' => TRUE,
'title_inline' => FALSE,
'css_classes' => FALSE,
'wrapper_classes' => FALSE,
),
),
);
return $component_info;
}
/**
* Declare our custom theme.
*
* Catch the rendering of an embedded view at the end.
*
* Implements hook_theme().
*/
function webform_view_theme() {
return array(
'webform_view_embedded' => array(
'render element' => 'element',
),
);
}
/**
* Implements hook_help().
*/
function webform_view_help($path, $arg) {
$modulename = 'webform_view';
switch ($path) {
case 'admin/help#' . $modulename:
$help_dir = drupal_get_path('module', $modulename) . '/help';
$text = file_get_contents("{$help_dir}/index.html");
$text = preg_replace('/(src|href)="([^\\/][^"]+)"/', '$1="' . url($help_dir) . '/$2"', $text);
return $text;
}
return FALSE;
}
/**
* Adjusts a webform_client_form.
*
* Calculates the unique key which is required later.
*
* Implements hook_form_BASE_FORM_ID_alter().
*/
function webform_view_form_webform_client_form_alter(&$form, &$form_state, $form_id) {
// Only process if there is submitted input.
if (empty($form_state['input']) || empty($form_state['input']['submitted'])) {
return;
}
$component_tree = $form_state['webform']['component_tree'];
foreach ($component_tree['children'] as $cid => $component) {
if ($component['type'] == 'view') {
// Current component is a webform_view.
$form_key = $component['form_key'];
$val = array();
$first_field = NULL;
// Can clear out blank values here.
// eg 'quantity';
$required_key = $component['extra']['filter_field_id'];
$inputs = $form_state['input']['submitted'];
if (is_array($inputs[$form_key])) {
foreach ($inputs[$form_key] as $nid => $values) {
if (is_numeric($nid)) {
// Iterate each node in the view.
$node = node_load($nid);
// Flatten the embedded view values.
if (is_array($component['children'])) {
foreach ($component['children'] as $key => $field) {
// If value was submitted, use it, else use default.
$v = isset($values[$field['form_key']]) ? $values[$field['form_key']] : $field['value'];
$val[$nid][$field['form_key']] = token_replace($v, array(
'node' => $node,
));
// Discover which was the first hidden field defined.
if ($first_field === NULL && $field['type'] == 'hidden') {
$first_field = $field['form_key'];
}
}
}
}
}
}
// This stores the submitted data in serialized format in the first
// hidden field.
if ($first_field !== NULL) {
// If required key is set, then rows without it are skipped.
foreach ($val as $nid => $v) {
if ($required_key != '<none>' && empty($v[$required_key])) {
unset($val[$nid]);
}
}
$form['submitted'][$form_key][$first_field]['#value'] = serialize($val);
}
}
}
// Add custom validation
$form['#validate'][] = 'webform_view_form_validate';
}
/**
* Form API #validate handler for the webform_client_form() form.
*/
function webform_view_form_validate($form, &$form_state) {
if ($form_state['webform']['preview'] && $form_state['webform']['page_count'] === $form_state['webform']['page_num']) {
// Form has already passed validation and is on the preview page.
return;
}
$component_tree = $form_state['webform']['component_tree'];
foreach ($component_tree['children'] as $cid => $component) {
if ($component['type'] == 'view') {
// Current component is a webform_view.
$form_key = $component['form_key'];
// If the required field is set, verify that at least one of the values
// is defined, and display an error if not
$required_key = $component['extra']['filter_field_id'];
if ($required_key != '<none>' && $component['required']) {
$ok = FALSE;
$inputs = $form_state['input']['submitted'];
if (is_array($inputs[$form_key])) {
foreach ($inputs[$form_key] as $nid => $values) {
if (is_array($values) && !empty($values[$required_key])) {
$ok = TRUE;
break;
}
}
}
if (!$ok) {
// Search for the right field in order to provide a nice name to the
// user in the validation failure message
foreach ($component['children'] as $ch_cid => $ch_component) {
if ($ch_component['form_key'] == $required_key) {
form_set_error('submitted][' . $form_key, t('!name field is required.', array(
'!name' => $ch_component['name'],
)));
break;
}
}
}
}
}
}
}
/**
* A special formatter to use as a placeholder to insert our view into a form.
*
* By declaring an alternative field formatter - to be used in place of the
* 'can order' flag, we can insert form elements into the view display
* and therefore into the webform.
*
* Field used on the content type must be a Boolean.
* If so, then we can replace that item with a custom display renderer.
*
* Implements hook_field_formatter_info().
*/
function webform_view_field_formatter_info() {
return array(
'webform_view_placeholder' => array(
'label' => t('A webform placeholder'),
'field types' => array(
'list_boolean',
),
),
);
}
/**
* Insert a PLACEHOLDER value as the text rendering of an item.
*
* The webform postprocess should replace this placeholder with the form element
*
* Implements hook_field_formatter_view().
*
* @see theme_webform_view_embedded()
*/
function webform_view_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
$element = array();
switch ($display['type']) {
case 'webform_view_placeholder':
foreach ($items as $delta => $item) {
// Don't even insert the placeholder if there is no value in the trigger
// element.
if (!empty($item['value'])) {
$key = $entity_type == 'node' ? $entity->nid : $entity->id;
$replace_pattern = "[webform_view_" . $key . "_placeholder]";
$element[$delta] = array(
'#type' => 'markup',
'#markup' => $replace_pattern,
);
}
else {
// Cannot order, return empty string.
$element[$delta] = array(
'#type' => 'markup',
'#markup' => '',
);
}
}
break;
}
return $element;
}
/**
* Implements hook_webform_csv_header_alter().
*/
function webform_view_webform_csv_header_alter(&$header, $component) {
$node = node_load($component['nid']);
if ($component['type'] == 'view') {
// This component is a webform_view, use name as header
$header[2] = t($component['name']);
}
else {
// Current component parent is a webform_view, hide headers
if ($node->webform['components'][$component['pid']]['type'] == 'view') {
$header[2] = NULL;
}
}
}
/**
* Implements hook_webform_csv_data_alter().
*/
function webform_view_webform_csv_data_alter(&$data, $component, $submission) {
$node = node_load($component['nid']);
if ($component['type'] == 'view') {
// This component is a webform_view
foreach ($node->webform['components'] as $cid => $comp) {
// Get the data from the first hidden field that is a child of this one
// and display each field separated with colon, and each item with a bar
if ($comp['pid'] == $component['cid'] && $comp['type'] == 'hidden') {
$values = array();
foreach (unserialize($submission->data[$cid][0]) as $val) {
$values[] = implode(':', $val);
}
$data = implode('|', $values);
break;
}
}
}
else {
// Current component parent is a webform_view, hide any data
if ($node->webform['components'][$component['pid']]['type'] == 'view') {
$data = NULL;
}
}
}
Functions
Name![]() |
Description |
---|---|
webform_view_field_formatter_info | A special formatter to use as a placeholder to insert our view into a form. |
webform_view_field_formatter_view | Insert a PLACEHOLDER value as the text rendering of an item. |
webform_view_form_validate | Form API #validate handler for the webform_client_form() form. |
webform_view_form_webform_client_form_alter | Adjusts a webform_client_form. |
webform_view_help | Implements hook_help(). |
webform_view_theme | Declare our custom theme. |
webform_view_webform_component_info | Declare our new component type for webform - an embedded view. |
webform_view_webform_csv_data_alter | Implements hook_webform_csv_data_alter(). |
webform_view_webform_csv_header_alter | Implements hook_webform_csv_header_alter(). |