form_builder.admin.inc in Form Builder 7
Same filename and directory in other branches
form_builder.admin.inc Administrative interface for editing forms.
File
includes/form_builder.admin.incView source
<?php
/**
* @file form_builder.admin.inc
* Administrative interface for editing forms.
*/
/**
* Main form building interface. Can be used as a menu callback.
*
* @param $form_type
* The type of form being edited. Usually the name of the providing module.
* @param $form_id
* The unique identifier for the form being edited with the type.
*/
function form_builder_interface($form_type, $form_id) {
module_load_include('inc', 'form_builder', 'includes/form_builder.api');
module_load_include('inc', 'form_builder', 'includes/form_builder.cache');
// Set the current form type (used for display of the sidebar block).
form_builder_active_form($form_type, $form_id);
// Create an internal state from the permanently stored form.
$loader = FormBuilderLoader::instance();
$form_obj = $loader
->fromStorage($form_type, $form_id);
$form_obj
->save();
$output = array();
$output[] = drupal_get_form('form_builder_preview', $form_obj, $form_type, $form_id);
$output[] = drupal_get_form('form_builder_positions', $form_obj, $form_type, $form_id);
return $output;
}
/**
* Menu callback for adding a field.
*/
function form_builder_add_page($form_type, $form_id, $element_type) {
_form_builder_add_element($form_type, $form_id, $element_type);
}
/**
* Menu callback for cloning a field.
*/
function form_builder_clone_page($form_type, $form_id, $element_id) {
_form_builder_add_element($form_type, $form_id, NULL, $element_id);
}
/**
* Menu callback helper for adding or cloning a field.
*
* If the $element_id parameter is provided, the new field will be cloned from
* the corresponding field (and the $element_type parameter will be ignored).
* Otherwise, a new field of type $element_type will be added from scratch.
*/
function _form_builder_add_element($form_type, $form_id, $element_type, $element_id = NULL, $sid = NULL, $return = FALSE) {
module_load_include('inc', 'form_builder', 'includes/form_builder.api');
module_load_include('inc', 'form_builder', 'includes/form_builder.cache');
$loader = FormBuilderLoader::instance();
$fields = $loader
->getElementTypeInfo($form_type, $form_id);
$form_obj = $loader
->fromCache($form_type, $form_id, $sid);
$element = NULL;
// Keep track of the number of elements added this requests.
$i =& drupal_static(__FUNCTION__, 1);
// If the field is being cloned, copy the original from the current form
// structure.
if (isset($element_id)) {
$element = $form_obj
->getElementArray($element_id);
if ($element) {
// @todo implement cloning as an element method.
// Remove the key so that a new one will be generated.
unset($element['#key']);
// Change the title to avoid confusion, and to avoid duplicate
// auto-generated machine names.
if (isset($element['#title'])) {
$element['#title'] = t('Copy of !title', array(
'!title' => $element['#title'],
));
}
// Set the element type to the correct value so it will be used
// consistently throughout this function.
$element_type = $element['#form_builder']['element_type'];
}
}
elseif (isset($fields[$element_type]['default'])) {
// @todo make this an element static method.
$element = $fields[$element_type]['default'];
}
if ($element) {
// @todo make this part of the element object's initialization.
$element_id = isset($_REQUEST['element_id']) ? $_REQUEST['element_id'] : 'new_' . REQUEST_TIME . $i++;
// Set the element ID to a hard-coded value if a unique field type.
if (isset($fields[$element_type]['unique']) && $fields[$element_type]['unique']) {
$element_id = $element_type;
}
$element['#key'] = $element_id;
$element['#form_builder']['element_id'] = $element_id;
$element['#form_builder']['is_new'] = TRUE;
$f = $form_obj
->getFormArray();
$element['#weight'] = count(element_children($f));
$element_id = $form_obj
->setElementArray($element, FORM_BUILDER_ROOT, TRUE);
$form_obj
->save();
if (isset($_REQUEST['js']) || $return) {
$form = drupal_get_form('form_builder_positions', $form_obj, $form_type, $form_id);
$data = array(
'formType' => $form_type,
'formId' => $form_id,
'elementId' => $element_id,
'html' => form_builder_field_render($form_type, $form_id, $element_id),
'positionForm' => drupal_render($form),
);
if ($return) {
return $data;
}
form_builder_json_output($data);
exit;
}
}
// Otherwise return to the previous page.
drupal_goto();
}
/**
* Menu callback for configuring a field.
*/
function form_builder_configure_page($form_type, $form_id, $element_id) {
$form = drupal_get_form('form_builder_field_configure', $form_type, $form_id, $element_id);
if (!isset($_REQUEST['js'])) {
return $form;
}
$commands[] = array(
'command' => 'formBuilder-displayForm',
'selector' => '#form-builder-element-' . $element_id,
'data' => drupal_render($form),
);
return array(
'#type' => 'ajax',
'#commands' => $commands,
);
}
/**
* Menu callback for removing a field.
*/
function form_builder_remove_page($form_type, $form_id, $element_id) {
$form = drupal_get_form('form_builder_field_remove', $form_type, $form_id, $element_id);
if (!isset($_REQUEST['js'])) {
return $form;
}
$commands[] = array(
'command' => 'formBuilder-displayForm',
'selector' => '#form-builder-element-' . $element_id,
'data' => drupal_render($form),
);
return array(
'#type' => 'ajax',
'#commands' => $commands,
);
}
/**
* Render the palette of fields to add to a form.
*/
function form_builder_field_palette() {
$active = form_builder_active_form();
$output = NULL;
if (isset($active)) {
$form_type = $active['form_type'];
$form_id = $active['form_id'];
$loader = FormBuilderLoader::instance();
$fields = $loader
->getElementTypeInfo($form_type, $form_id);
$groups = $loader
->getPaletteGroupInfo($form_type, $form_id);
// TODO: We shouldn't have to clear the cache here.
$form = $loader
->fromCache($form_type, $active['form_id'], NULL, TRUE);
$active_fields = $form
->getElementTypes();
foreach ($fields as $key => $field) {
if ($field['unique'] && in_array($key, $active_fields)) {
$fields[$key]['in_use'] = TRUE;
}
if ($field['addable'] == FALSE) {
unset($fields[$key]);
}
}
$output = theme('form_builder_field_palette', array(
'fields' => $fields,
'groups' => $groups,
'form_type' => $active['form_type'],
'form_id' => $active['form_id'],
));
}
return $output;
}
/**
* Form. Given a form array, present it for editing in a preview.
*/
function form_builder_preview($f, &$form_state, $form_obj, $form_type, $form_id) {
// @todo: think about this more. We basically get the form from outside, so
// while normally the first argument would be $form, we use the third, which
// is provided by the caller.
// Make modifications to all form elements recursively.
$element_ids = $form_obj
->getElementIds();
$form = $form_obj
->preview();
// Record all the element IDs within the entire form.
$form['#form_builder']['element_ids'] = $element_ids;
$form['#form_builder']['form_type'] = $form_type;
$form['#form_builder']['form_id'] = $form_id;
// Add a pre_render to the entire form itself.
$form['#pre_render'][] = 'form_builder_pre_render_form';
$form['#theme_wrappers'] = array(
'form_builder_wrapper',
);
// Add required jQuery UI elements.
$form['#attached']['library'][] = array(
'system',
'ui.draggable',
);
$form['#attached']['library'][] = array(
'system',
'ui.droppable',
);
$form['#attached']['library'][] = array(
'system',
'ui.sortable',
);
$form['#attached']['library'][] = array(
'system',
'form',
);
$form['#attached']['js'][] = drupal_get_path('module', 'form_builder') . '/form_builder.js';
// TODO: This JS file should be loaded dynamically as needed.
$form['#attached']['js'][] = drupal_get_path('module', 'options_element') . '/options_element.js';
// TODO: Use libraries if available. see http://drupal.org/node/954804
$form['#attached']['js'][] = 'misc/tabledrag.js';
$form['#attached']['js'][] = 'misc/jquery.cookie.js';
$form['#attached']['library'][] = array(
'system',
'form',
);
$form['#attached']['js'][] = 'misc/form.js';
$form['#attached']['js'][] = 'misc/collapse.js';
$form['#attached']['js'][] = drupal_get_path('module', 'filter') . '/filter.js';
$form['#attached']['css'][] = drupal_get_path('module', 'filter') . '/filter.css';
$form['#attached']['js'][] = array(
'data' => array(
'machineName' => array(),
),
'type' => 'setting',
);
$form['#attached']['js'][] = 'misc/machine-name.js';
$settings = array(
'emptyForm' => theme('form_builder_empty_form'),
'emptyFieldset' => theme('form_builder_empty_fieldset'),
'noFieldSelected' => theme('form_builder_no_field_selected'),
'fieldLoading' => theme('form_builder_field_loading'),
);
$form['#attached']['js'][] = array(
'data' => array(
'formBuilder' => $settings,
),
'type' => 'setting',
);
$form['#attached']['css'][] = drupal_get_path('module', 'form_builder') . '/form_builder.css';
$form['#attached']['css'][] = drupal_get_path('module', 'options_element') . '/options_element.css';
return $form;
}
/**
* Form containing all the current weights and parents of elements.
*/
function form_builder_positions($form, &$form_state, $form_obj, $form_type, $form_id) {
form_load_include($form_state, 'inc', 'form_builder', 'includes/form_builder.admin');
$form = array(
'#tree' => TRUE,
'#form_builder' => array(
'form_type' => $form_type,
'form_id' => $form_id,
),
);
foreach ($form_obj
->getElementIds() as $element_id) {
$element = $form_obj
->getElementArray($element_id);
$form[$element_id]['weight'] = array(
'#type' => 'hidden',
'#default_value' => isset($element['#weight']) ? $element['#weight'] : 0,
'#attributes' => array(
'class' => array(
'form-builder-weight form-builder-element-' . $element_id,
),
),
);
$form[$element_id]['parent'] = array(
'#type' => 'hidden',
'#default_value' => $element['#form_builder']['parent_id'],
'#attributes' => array(
'class' => array(
'form-builder-parent form-builder-element-' . $element_id,
),
),
);
}
// Drupal MUST have a button to register submissions.
// Add a button even though the form is only submitted via AJAX.
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Update'),
'#ajax' => array(
'callback' => 'form_builder_positions_ajax',
'wrapper' => 'form_builder_positions',
),
);
return $form;
}
/**
* AJAX callback for form_builder_positions.
*/
function form_builder_positions_ajax($form, &$form_state) {
// We don't want to change anything in the form.
return array(
'#type' => 'ajax',
'#commands' => array(),
);
}
/**
* Submit handler for the form_builder_positions form.
*/
function form_builder_positions_submit(&$form, &$form_state) {
module_load_include('inc', 'form_builder', 'includes/form_builder.api');
module_load_include('inc', 'form_builder', 'includes/form_builder.cache');
$form_type = $form['#form_builder']['form_type'];
$form_id = $form['#form_builder']['form_id'];
$form_cache = FormBuilderLoader::instance()
->fromCache($form_type, $form_id);
foreach (element_children($form) as $element_id) {
// Skip items without weight value (like the form token, build_id, etc).
if (!isset($form[$element_id]['weight'])) {
continue;
}
// Check for changed weights or parents if element has not been deleted in
// the meanwhile.
if ($element = $form_cache
->getElementArray($element_id)) {
$element['#weight'] = $form_state['values'][$element_id]['weight'];
$element['#form_builder']['parent_id'] = $form_state['values'][$element_id]['parent'];
$form_cache
->setElementArray($element);
}
}
// Save all the changes made.
$form_cache
->save();
// Don't redirect, which will cause an unnecessary HTTP request.
$form_state['redirect'] = FALSE;
}
/**
* Output the wrapper around the form_builder preview.
*
* Optionally outputs the field palette if it is not already available as a
* block.
*/
function theme_form_builder_wrapper($variables) {
$element = $variables['element'];
$output = '';
$output .= '<div id="form-builder-wrapper" class="' . ($element['#show_palette'] ? 'with-palette' : 'no-palette') . '">';
if ($element['#show_palette']) {
$output .= '<div id="form-builder-fields">';
$output .= '<div class="block">';
$output .= form_builder_field_palette();
$output .= '</div>';
$output .= '</div>';
}
$output .= '<div id="form-builder">';
if (isset($element['#title'])) {
$output .= '<h3 class="form-builder-title">' . $element['#title'] . '</h3>';
}
// Add the contents of the form and close the wrappers.
$output .= $element['#children'];
$output .= '</div>';
// #form-builder.
$output .= '</div>';
// #form-builder-wrapper.
return $output;
}
/**
* Output the wrapper around a form_builder element with configure/remove links.
*/
function theme_form_builder_element_wrapper($variables) {
$element = $variables['element'];
$removable = isset($element['#form_builder']['removable']) ? $element['#form_builder']['removable'] : TRUE;
$configurable = isset($element['#form_builder']['configurable']) ? $element['#form_builder']['configurable'] : TRUE;
$cloneable = form_builder_menu_field_access('clone', $element['#form_builder']['form_type'], $element['#form_builder']['form_id'], $element['#form_builder']['element_id']);
$output = '';
$output .= '<div class="form-builder-wrapper">';
if ($removable || $configurable) {
$output .= '<div class="form-builder-title-bar">';
$output .= '<span class="form-builder-links">';
if ($removable) {
$output .= l('<span class="remove">' . t('Remove') . '</span>', 'admin/structure/form-builder/remove/' . $element['#form_builder']['form_type'] . '/' . $element['#form_builder']['form_id'] . '/' . $element['#form_builder']['element_id'], array(
'html' => TRUE,
'attributes' => array(
'class' => array(
'remove',
),
'title' => t('Remove'),
),
'query' => drupal_get_destination(),
));
}
if ($removable && $configurable) {
$output .= ' ';
}
if ($configurable) {
$output .= l('<span class="configure">' . t('Configure') . '</span>', 'admin/structure/form-builder/configure/' . $element['#form_builder']['form_type'] . '/' . $element['#form_builder']['form_id'] . '/' . $element['#form_builder']['element_id'], array(
'html' => TRUE,
'attributes' => array(
'class' => array(
'configure',
),
'title' => t('Configure'),
),
'query' => drupal_get_destination(),
));
}
$output .= '</span>';
$output .= '</div>';
}
if ($cloneable) {
$output .= '<div class="form-builder-bottom-title-bar">';
$output .= '<span class="form-builder-bottom-links">';
$output .= l('<span class="clone">' . t('Copy') . '</span>', 'admin/structure/form-builder/clone/' . $element['#form_builder']['form_type'] . '/' . $element['#form_builder']['form_id'] . '/' . $element['#form_builder']['element_id'], array(
'html' => TRUE,
'attributes' => array(
'class' => array(
'clone',
),
'title' => t('Copy'),
),
'query' => drupal_get_destination(),
));
$output .= '</span>';
$output .= '</div>';
}
$output .= '<div class="form-builder-element form-builder-element-' . $element['#type'] . '" id="form-builder-element-' . $element['#form_builder']['element_id'] . '">';
// TODO: Overlay image: good idea or bad idea? Prevents any interaction with
// form elements in the preview.
//$output .= theme('image', drupal_get_path('module', 'form_builder') .'/images/blank.gif', '', '', array('width' => '1', 'height' => '1', 'class' => 'form-builder-disable'));
$output .= $element['#children'];
$output .= '</div></div>';
return $output;
}
/**
* Placeholder for an entirely empty form before any fields are added.
*/
function theme_form_builder_empty_form($variables) {
$output = '';
$output .= '<div class="form-builder-wrapper form-builder-empty-form form-builder-empty-placeholder">';
$output .= '<span>' . t('Drag a field from the palette to add it to this form.') . '</span>';
$output .= '</div>';
return $output;
}
/**
* Placeholder for empty fieldsets during drag and drop.
*/
function theme_form_builder_empty_fieldset($variables) {
$output = '';
$output .= '<div class="form-builder-wrapper form-builder-empty-placeholder">';
$output .= '<span>' . t('This fieldset is empty. Drag a form element into it.') . '</span>';
$output .= '</div>';
return $output;
}
/**
* Message shown in custom field configure forms when no field is selected.
*
* Note that this message is not displayed using the default field presentation.
* Modules or themes can set a custom field configuration form location by
* specifying a Drupal.settings.formBuilder.configureFormSelector value.
*/
function theme_form_builder_no_field_selected($variables) {
$output = '';
$output .= '<div class="field-settings-message">';
$output .= t('No field selected');
$output .= '</div>';
return $output;
}
/**
* Message shown in custom field configure forms when a field is loading.
*
* @see theme_form_builder_no_field_selected().
*/
function theme_form_builder_field_loading($variables) {
$output = '';
$output .= '<div class="field-settings-message">';
$output .= t('Loading...');
$output .= '</div>';
return $output;
}
/**
* Block for adding new fields.
*
* @param $vars['fields']
* A list of all fields can be added to the current form type.
* @param $vars['groups']
* A list of groups that fields may be sorted into. Each field is assigned
* a 'palette_group' property which corresponds to one of these groups.
* @param $vars['form_type']
* The form type to which these blocks apply.
* @param $vars['form_id']
* The form ID that is being edited.
*/
function theme_form_builder_field_palette($vars) {
extract($vars);
$output = '';
$lists = array();
foreach ($fields as $field_name => $field) {
$class = array(
'field-' . $field_name,
'form-builder-palette-element',
);
$style = '';
// If a field is unique, add a special class to identify it.
if ($field['unique']) {
$class[] = 'form-builder-unique';
$class[] = 'form-builder-element-' . $field_name;
// If already in use, do not display it in the list.
if (!empty($field['in_use'])) {
$style = 'display: none;';
}
}
$lists[$field['palette_group']]['#weight'] = $groups[$field['palette_group']]['weight'];
$lists[$field['palette_group']][] = array(
'data' => l($field['title'], 'admin/structure/form-builder/add/' . $form_type . '/' . $form_id . '/' . $field_name, array(
'query' => drupal_get_destination(),
)),
'class' => $class,
'style' => $style,
);
}
// Sort the lists by weight.
uasort($lists, 'element_sort');
$output .= '<div id="form-builder-field-palette">';
foreach ($lists as $group => $list) {
unset($list['#weight']);
$output .= theme('item_list', array(
'items' => $list,
'title' => count($lists) > 1 ? $groups[$group]['title'] : t('Add a field'),
'type' => 'ul',
'attributes' => array(
'class' => array(
'form-builder-fields',
'clearfix',
),
),
));
}
$output .= '</div>';
return $output;
}
/**
* Take a form structure and add a prebuild function to every element.
*/
function form_builder_pre_render($element) {
$element['#theme_wrappers'][] = 'form_builder_element_wrapper';
if ($element['#form_builder']['element_type'] == 'fieldset') {
$element['#attributes']['class'][] = 'form-builder-fieldset';
}
if (isset($element['#type']) && $element['#type'] == 'fieldset' && count(element_children($element)) == 0) {
$element['#children'] = theme('form_builder_empty_fieldset');
}
// Allow modules to make modifications to this element.
drupal_alter('form_builder_preview', $element, $element['#form_builder']['form_type'], $element['#form_builder']['form_id']);
return $element;
}
/**
* Pre-render function to alter the form being edited by Form builder.
*
* This function modifies the form element itself and sets a #title to label the
* form preview and an #show_palette property to indicate to the theme wrapper
* whether the field palette should be added.
*/
function form_builder_pre_render_form($form) {
global $theme;
// We can't have forms inside of forms, so change this entire form a markup.
$form['#type'] = 'markup';
// Set a title for the preview if none exists.
$form['#title'] = !isset($form['#title']) ? t('Form preview') : $form['#title'];
// Remove unnecessary FAPI elements.
unset($form['form_build_id']);
unset($form['form_token']);
unset($form['form_builder_preview']);
// Check if the Form Builder block is enabled.
// Otherwise make our own columns.
if (!isset($form['#show_palette'])) {
if (module_exists('block')) {
$form['#show_palette'] = !db_query("SELECT status FROM {block} WHERE module = 'form_builder' AND theme = :theme", array(
':theme' => $theme,
))
->fetchField();
}
else {
$form['#show_palette'] = TRUE;
}
}
if ($theme == 'garland' || $theme == 'minnelli') {
$form['#attached']['css'][] = drupal_get_path('module', 'form_builder') . '/form_builder.garland.css';
}
return $form;
}
function form_builder_after_build($element) {
$element['#attributes']['readonly'] = 'readonly';
foreach (element_children($element) as $key) {
$element[$key] = form_builder_after_build($element[$key]);
}
return $element;
}
/**
* Form for editing a field.
*/
function form_builder_field_configure($form, $form_state, $form_type, $form_id, $element_id) {
module_load_include('inc', 'form_builder', 'includes/form_builder.api');
module_load_include('inc', 'form_builder', 'includes/form_builder.cache');
$form_obj = FormBuilderLoader::instance()
->fromCache($form_type, $form_id);
$element_obj = $form_obj
->getElement($element_id);
$form['#attributes']['class'][] = 'form-builder-field-configure';
$form['#property_groups'] = module_invoke_all('form_builder_property_groups', $form_type);
$form = $element_obj
->configurationForm($form, $form_state);
$form['#_edit_form_type'] = $form_type;
$form['#_edit_form_id'] = $form_id;
$form['#_edit_element_id'] = $element_id;
$form['#pre_render'][] = 'form_builder_field_configure_pre_render';
$form['form_builder_submit'] = array(
'#type' => 'submit',
'#value' => t('Save configuration'),
'#weight' => 100,
);
return $form;
}
/**
* Pre-render function for the field configuration form.
*/
function form_builder_field_configure_pre_render($form) {
$groups = $form['#property_groups'];
foreach (element_children($form) as $key) {
// If no group is specified, put the element into the default group.
if (!isset($form[$key]['#form_builder']['property_group']) || !isset($groups[$form[$key]['#form_builder']['property_group']])) {
if (!isset($form[$key]['#type']) || isset($form[$key]['#type']) && !in_array($form[$key]['#type'], array(
'hidden',
'button',
'submit',
'value',
'token',
))) {
$form[$key]['#form_builder']['property_group'] = 'default';
}
}
if (isset($form[$key]['#form_builder']['property_group'])) {
$group = $form[$key]['#form_builder']['property_group'];
// We add "_property_group" to the field key to prevent conflicts of
// property names and group names.
if (!isset($form[$group . '_property_group'])) {
$form[$group . '_property_group'] = array(
'#type' => 'fieldset',
'#title' => $groups[$group]['title'],
'#weight' => $groups[$group]['weight'],
'#collapsible' => isset($groups[$group]['collapsible']) ? $groups[$group]['collapsible'] : FALSE,
'#collapsed' => isset($groups[$group]['collapsed']) ? $groups[$group]['collapsed'] : FALSE,
'#attributes' => array(
'class' => array(
'form-builder-group',
),
),
);
}
$form[$group . '_property_group'][$key] = $form[$key];
unset($form[$key]);
}
}
return $form;
}
function form_builder_field_configure_submit(&$form, &$form_state) {
list($form_type, $form_id, $element_id) = $form_state['build_info']['args'];
$form_obj = FormBuilderLoader::instance()
->fromCache($form_type, $form_id);
$element_obj = $form_obj
->getElement($element_id);
$element_obj
->configurationSubmit($form, $form_state);
// Update the form builder cache.
$form_obj
->save();
if (isset($_REQUEST['js'])) {
// Option A: Use the destination variable to do a drupal_goto(). Allows
// other submit handlers to add on extra functionality.
// The destination variable takes precedence over $form_state['redirect'].
//$_REQUEST['destination'] = 'admin/structure/form-builder/json/' . $form_type . '/' . $form_id . '/' . $element_id;
// Option B: Immediately print the JSON and exit. Faster and requires only
// one HTTP request instead of two. Other submit handlers must be before
// this on.
form_builder_field_json($form_type, $form_id, $element_id);
}
}
/**
* Form for removing a field.
*/
function form_builder_field_remove($form, $form_state, $form_type, $form_id, $element_id) {
$form_obj = FormBuilderLoader::instance()
->fromCache($form_type, $form_id);
$element_obj = $form_obj
->getElement($element_id);
$title = $element_obj
->title();
$question = t('Remove the field %title?', array(
'%title' => $title,
));
$path = isset($_GET['destination']) ? $_GET['destination'] : NULL;
$description = t('Remove the field %title? This field will not be permanently removed until the form configuration is saved.', array(
'%title' => $title,
));
$yes = t('Remove');
if ($_REQUEST['js']) {
$form['js'] = array(
'#type' => 'hidden',
'#value' => '1',
);
}
return confirm_form($form, $question, $path, $description, $yes);
}
function form_builder_field_remove_submit(&$form, &$form_state) {
list($form_type, $form_id, $element_id) = $form_state['build_info']['args'];
// Update the form builder cache.
form_builder_cache_field_delete($form_type, $form_id, $element_id);
if (isset($_REQUEST['js'])) {
// See form_builder_field_configure_submit() for comparison between using
// redirect and immediately printing the JSON.
//$form_state['redirect'] = 'admin/structure/form-builder/json/' . $form_type . '/' . $form_id . '/' . $element_id;
form_builder_field_json($form_type, $form_id, $element_id);
}
}
/**
* Render a single field independent of other settings.
*
* @todo form rendering a form method.
*/
function form_builder_field_render($form_type, $form_id, $element_id, $wrapper = FALSE) {
module_load_include('inc', 'form_builder', 'includes/form_builder.api');
module_load_include('inc', 'form_builder', 'includes/form_builder.cache');
// Load the current state of the form and prepare it for rendering.
$loader = FormBuilderLoader::instance();
$form_obj = $loader
->fromCache($form_type, $form_id);
if (!$form_obj) {
$form_obj = $loader
->fromStorage($form_type, $form_id);
$form_obj
->save();
}
$form_state = array(
'submitted' => FALSE,
'build_info' => array(
'args' => array(
$form_obj,
$form_type,
$form_id,
),
),
'values' => array(),
'method' => 'get',
);
$form = drupal_retrieve_form('form_builder_preview', $form_state);
drupal_prepare_form('form_builder_preview', $form, $form_state);
$form['#post'] = array();
$form = form_builder('form_builder_preview', $form, $form_state);
// Get only the element wanted and render it.
$element = form_builder_get_element($form, $element_id);
if ($wrapper) {
$element['#theme_wrappers'][] = 'form_builder_element_wrapper';
}
return drupal_render($element);
}
/**
* Menu callback to display a field as a JSON string.
*/
function form_builder_field_json($form_type, $form_id, $element_id) {
module_load_include('inc', 'form_builder', 'includes/form_builder.api');
module_load_include('inc', 'form_builder', 'includes/form_builder.cache');
$element = form_builder_cache_field_load($form_type, $form_id, $element_id);
$data = array(
'formType' => $form_type,
'formId' => $form_id,
'elementId' => $element_id,
'html' => !empty($element) ? form_builder_field_render($form_type, $form_id, $element_id) : '',
'errors' => form_get_errors(),
);
form_builder_json_output($data);
exit;
}
/**
* Generic function for outputing Form Builder JSON return responses.
*
* Adds status messages, settings, and timestamp to a form builder JSON response
* and outputs it.
*/
function form_builder_json_output($data) {
if (!isset($data['messages'])) {
$data['messages'] = theme('status_messages');
}
if (!isset($data['settings'])) {
$scripts = drupal_add_js();
if (!empty($scripts['settings'])) {
$data['settings'] = drupal_array_merge_deep_array($scripts['settings']['data']);
}
}
if (!isset($data['time'])) {
$data['time'] = time();
}
drupal_json_output($data);
}
Functions
Name | Description |
---|---|
form_builder_add_page | Menu callback for adding a field. |
form_builder_after_build | |
form_builder_clone_page | Menu callback for cloning a field. |
form_builder_configure_page | Menu callback for configuring a field. |
form_builder_field_configure | Form for editing a field. |
form_builder_field_configure_pre_render | Pre-render function for the field configuration form. |
form_builder_field_configure_submit | |
form_builder_field_json | Menu callback to display a field as a JSON string. |
form_builder_field_palette | Render the palette of fields to add to a form. |
form_builder_field_remove | Form for removing a field. |
form_builder_field_remove_submit | |
form_builder_field_render | Render a single field independent of other settings. |
form_builder_interface | Main form building interface. Can be used as a menu callback. |
form_builder_json_output | Generic function for outputing Form Builder JSON return responses. |
form_builder_positions | Form containing all the current weights and parents of elements. |
form_builder_positions_ajax | AJAX callback for form_builder_positions. |
form_builder_positions_submit | Submit handler for the form_builder_positions form. |
form_builder_preview | Form. Given a form array, present it for editing in a preview. |
form_builder_pre_render | Take a form structure and add a prebuild function to every element. |
form_builder_pre_render_form | Pre-render function to alter the form being edited by Form builder. |
form_builder_remove_page | Menu callback for removing a field. |
theme_form_builder_element_wrapper | Output the wrapper around a form_builder element with configure/remove links. |
theme_form_builder_empty_fieldset | Placeholder for empty fieldsets during drag and drop. |
theme_form_builder_empty_form | Placeholder for an entirely empty form before any fields are added. |
theme_form_builder_field_loading | Message shown in custom field configure forms when a field is loading. |
theme_form_builder_field_palette | Block for adding new fields. |
theme_form_builder_no_field_selected | Message shown in custom field configure forms when no field is selected. |
theme_form_builder_wrapper | Output the wrapper around the form_builder preview. |
_form_builder_add_element | Menu callback helper for adding or cloning a field. |