-
-
Save jackrabbithanna/71e407d5ffb089b4a07778b47a5629b8 to your computer and use it in GitHub Desktop.
/** | |
* Implements hook_theme(). | |
* | |
* @return array | |
*/ | |
function webform_multi_theme() { | |
return array( | |
'webform_multi_url_params_field' => array( | |
'render element' => 'element', | |
), | |
); | |
} | |
/** | |
* Implements hook_element_info(). | |
* | |
* @return mixed | |
*/ | |
function webform_multi_element_info() { | |
$elements['webform_multi_url_params'] = array( | |
'#default_value' => '', | |
'#input' => TRUE, | |
'#process' => array('webform_multi_url_params_element_process'), | |
'#theme' => array('webform_multi_url_params_field'), | |
'#theme_wrappers' => array('form_element'), | |
'#tree' => TRUE, | |
'#value_callback' => 'webform_multi_url_params_element_value_callback', | |
); | |
return $elements; | |
} | |
/** | |
* Process callback for the webform_multi_url_params FAPI element | |
* | |
* @param $element | |
* @param $form_state | |
* @param $complete_form | |
*/ | |
function webform_multi_url_params_element_process($element, $form_state, $complete_form) { | |
$element_name = $element['#name']; | |
preg_match_all("/\[([^\]]*)\]/", $element_name, $matches); | |
if( count($matches) ) { | |
$temp_name = end($matches); | |
if(!empty($temp_name)) { | |
$element_name = $temp_name[0]; | |
} | |
} | |
// get settings from either form state storage, form state values, or from stored db values or variable values | |
if(!empty($form_state['webform_multi_url_param_settings'][$element_name])) { | |
$url_param_settings = $form_state['webform_multi_url_param_settings'][$element_name]; | |
} | |
else { | |
//first look for passed defaults | |
if(empty($form_state['input']) && !empty($element['#default_value'])) { | |
$url_param_settings = array(); | |
if(!empty($element['#default_value'])) { | |
foreach($element['#default_value']['webform_multi_url_params']['url_params'] as $count => $param) { | |
$url_param_settings[$count] = $param['param']; | |
} | |
} | |
$url_param_settings[] = array('source_param' => '', 'redirect_param' => ''); | |
} | |
else { | |
// if none, then setup a blank item | |
$url_param_settings = array( | |
0 => array('source_param' => '', 'redirect_param' => ''), | |
); | |
} | |
} | |
$element['webform_multi_url_params']['url_params'] = array( | |
'#type' => 'container', | |
'#tree' => TRUE, | |
'#prefix' => '<div id="webform-multi-url-params_' . $element_name . '">', | |
'#suffix' => '</div>', | |
'#attributes' => array( | |
'class' => array( | |
'webform-multi-url-params-container', | |
), | |
), | |
); | |
foreach($url_param_settings as $count => $settings) { | |
$element['webform_multi_url_params']['url_params'][$count]['param'] = array( | |
'#type' => 'container', | |
'#tree' => TRUE, | |
'#attributes' => array( | |
'class' => array('webform-multi-url-param-row'), | |
), | |
); | |
$element['webform_multi_url_params']['url_params'][$count]['param']['source_param'] = array( | |
'#type' => 'textfield', | |
'#size' => 30, | |
'#required' => $element['#required'], | |
'#title' => t('Source Parameter'), | |
'#title_display' => 'invisible', | |
'#theme_wrappers' => array(), | |
'#attributes' => array('placeholder' => 'source parameter'), | |
'#default_value' => $settings['source_param'], | |
); | |
$element['webform_multi_url_params']['url_params'][$count]['param']['redirect_param'] = array( | |
'#type' => 'textfield', | |
'#size' => 30, | |
'#required' => $element['#required'], | |
'#title' => t('Redirect Parameter'), | |
'#title_display' => 'invisible', | |
'#theme_wrappers' => array(), | |
'#attributes' => array('placeholder' => 'redirect parameter'), | |
'#default_value' => $settings['redirect_param'], | |
); | |
$element['webform_multi_url_params']['url_params'][$count]['param']['remove_param' . $count] = array( | |
'#parent_element_name' => $element_name, | |
'#parent_element_parents' => $element['#parents'], | |
'#name' => 'url-param-remove|' . $count . '|' . $element_name, | |
'#id' => 'url-param-remove-' . $count . '-' . $element_name, | |
'#type' => 'image_button', | |
'#button_type' => 'image-button', | |
'#src' => drupal_get_path('module', 'webform_multi') . '/img/delete.png', | |
'#default_value' => t('Remove'), | |
'#limit_validation_errors' => array(), | |
'#submit' => array('webform_multi_url_param_element_add_remove_value_submit'), | |
'#ajax' => array( | |
'wrapper' => 'webform-multi-url-params_' . $element_name, | |
'callback' => 'webform_multi_url_param_element_ajax_callback', | |
), | |
); | |
} | |
$element['webform_multi_url_params']['add_param_setting'] = array( | |
'#parent_element_name' => $element_name, | |
'#name' => 'add-param-setting' . '_' . $element_name, | |
'#id' => 'add-param-setting' . '_' . $element_name, | |
'#type' => 'submit', | |
'#default_value' => t('Add'), | |
'#submit' => array('webform_multi_url_param_element_add_remove_value_submit'), | |
'#ajax' => array( | |
'wrapper' => 'webform-multi-url-params_' . $element_name, | |
'callback' => 'webform_multi_url_param_element_ajax_callback', | |
), | |
); | |
$element['#attached']['css'][] = drupal_get_path('module', 'webform_multi') . '/css/url-param-element.css'; | |
return $element; | |
} | |
/** | |
* Add and Remove button submit callback | |
* | |
* @param $form | |
* @param $form_state | |
*/ | |
function webform_multi_url_param_element_add_remove_value_submit($form, &$form_state) { | |
if(!empty($_POST['_triggering_element_name'])) { | |
if(!preg_match('/^[a-zA-Z0-9_\-\|]+$/', $_POST['_triggering_element_name'])) { | |
return; | |
} | |
} | |
else { | |
$_POST['_triggering_element_name'] = $form_state['triggering_element']['#name']; | |
} | |
if (strpos($_POST['_triggering_element_name'], "url-param-remove") === 0) { | |
$name_array = explode('|', $_POST['_triggering_element_name']); | |
$index = $name_array[1]; | |
$parent_element_name = $name_array[2]; | |
$parents = $form_state['triggering_element']['#array_parents']; | |
//need this bit incase there are 2 element on the form and drupal gets the triggering_element wrong | |
foreach($parents as $count => $parent) { | |
if($parent == 'webform_multi_url_params') { | |
$parents[$count-1] = $parent_element_name; | |
break; | |
} | |
} | |
if($form_state['triggering_element']['#name'] == 'add-param-setting') { | |
array_pop($parents); | |
$parents[] = $parent_element_name; | |
} | |
else { | |
array_pop($parents); | |
array_pop($parents); | |
array_pop($parents); | |
} | |
if(isset($form_state['input'][$parents[0]])) { | |
$input =& drupal_array_get_nested_value($form_state['input'], $parents); | |
} | |
else { | |
$first_parent = array_shift($parents); | |
$input =& drupal_array_get_nested_value($form_state['input'], $parents); | |
} | |
unset($input[$index]); | |
$input = array_values($input); | |
drupal_array_set_nested_value($form_state['input'], $parents, $input); | |
$form_state['webform_multi_url_param_settings'][$parent_element_name] = array(); | |
foreach($input as $count => $settings) { | |
$form_state['webform_multi_url_param_settings'][$parent_element_name][$count] = $settings['param']; | |
} | |
} | |
elseif(strpos($_POST['_triggering_element_name'], "add-param-setting") === 0) { | |
$parents = $form_state['triggering_element']['#parents']; | |
array_pop($parents); | |
$input = drupal_array_get_nested_value($form_state['input'], $parents); | |
$form_state['webform_multi_url_param_settings'][$form_state['triggering_element']['#parent_element_name']] = array(); | |
foreach($input['url_params'] as $count => $settings) { | |
$form_state['webform_multi_url_param_settings'][$form_state['triggering_element']['#parent_element_name']][$count] = $settings['param']; | |
} | |
$form_state['webform_multi_url_param_settings'][$form_state['triggering_element']['#parent_element_name']][] = array('source_param' => '', 'redirect_param' => ''); | |
} | |
$form_state['rebuild'] = TRUE; | |
} | |
/** | |
* Add and remove button ajax callback | |
* | |
* @param $form | |
* @param $form_state | |
* @return array | |
*/ | |
function webform_multi_url_param_element_ajax_callback($form, &$form_state) { | |
if(!empty($_POST['_triggering_element_name'])) { | |
if(!preg_match('/^[a-zA-Z0-9_\-\|]+$/', $_POST['_triggering_element_name'])) { | |
return; | |
} | |
} | |
else { | |
$_POST['_triggering_element_name'] = $form_state['triggering_element']['#name']; | |
} | |
$commands = array(); | |
if (strpos($_POST['_triggering_element_name'], "url-param-remove") === 0) { | |
$name_array = explode('|', $_POST['_triggering_element_name']); | |
$index = $name_array[1]; | |
$parent_element_name = $name_array[2]; | |
$parents = $form_state['triggering_element']['#array_parents']; | |
//need this bit incase there are 2 element on the form and drupal gets the triggering_element wrong | |
foreach($parents as $count => $parent) { | |
if($parent == 'webform_multi_url_params') { | |
$parents[$count-1] = $parent_element_name; | |
break; | |
} | |
} | |
if(strpos($form_state['triggering_element']['#name'], 'add-param-setting') === 0) { | |
array_pop($parents); | |
} | |
else { | |
array_pop($parents); | |
array_pop($parents); | |
array_pop($parents); | |
} | |
$element = drupal_array_get_nested_value($form, $parents); | |
if($form_state['triggering_element']['#name'] == 'add-param-setting') { | |
$commands[] = ajax_command_html('#webform-multi-url-params_' . $parent_element_name, render($element['url_params'])); | |
} | |
else { | |
$commands[] = ajax_command_html('#webform-multi-url-params_' . $parent_element_name, render($element)); | |
} | |
} | |
elseif(strpos($_POST['_triggering_element_name'], "add-param-setting") === 0) { | |
$parents = $form_state['triggering_element']['#array_parents']; | |
array_pop($parents); | |
$element = drupal_array_get_nested_value($form, $parents); | |
$commands[] = ajax_command_html('#webform-multi-url-params_' . $form_state['triggering_element']['#parent_element_name'], render($element['url_params'])); | |
} | |
if (!empty($commands)) { | |
$commands[] = ajax_command_prepend('#webform-multi-url-params_' . $form_state['triggering_element']['#parent_element_name'], '<div id="messages">' . theme('status_messages') . '</div>'); | |
return array('#type' => 'ajax', '#commands' => $commands); | |
} | |
} | |
/** | |
* Theme callback for the webform_multi_url_params FAPI element type | |
* | |
* @param $variables | |
* @return string | |
*/ | |
function webform_multi_url_params_field($variables) { | |
$element = $variables['element']; | |
$output = drupal_render($element); | |
return $output; | |
} | |
/** | |
* Value callback for the webform_multi_url_params FAPI element type | |
* | |
* @param $element | |
* @param bool $input | |
* @param $form_state | |
* @return bool|void | |
*/ | |
function webform_multi_url_params_element_value_callback($element, $input = FALSE, &$form_state) { | |
if ($input !== FALSE) { | |
foreach($input['webform_multi_url_params']['url_params'] as $count => $param) { | |
if ($input['webform_multi_url_params']['url_params'][$count]['param']['source_param'] && !$input['webform_multi_url_params']['url_params'][$count]['param']['redirect_param']) { | |
$input['webform_multi_url_params']['url_params'][$count]['param']['source_param'] = ''; | |
} | |
if ($input['webform_multi_url_params']['url_params'][$count]['param']['redirect_param'] && !$input['webform_multi_url_params']['url_params'][$count]['param']['source_param']) { | |
$input['webform_multi_url_params']['url_params'][$count]['param']['redirect_param'] = ''; | |
} | |
} | |
return $input; | |
} | |
elseif (!empty($element['#default_value'])) { | |
return $element['#default_value']; | |
} | |
return; | |
} |
You can add multiple form elements of this custom type 'webform_multi_url_params' and the ajax works right
Although this element type was created for a custom webform integration module I am writing, but doesn't make a webform component type. This is a FAPI element type, like 'textfield', or 'select'
Keep playing with it, works good now for being in a parent #tree or not, multiple widgets on the same page, need to format the #default_value non optimally IMO
Its because the $element['webform_multi_url_params']['url_params'] container has #tree = TRUE
and the row container, 'params' also has #tree true
I would have not had that but I needed a way to control an id so I could use the ajax, but maybe it was unnecessary?
Is the two containers that the ajaxified buttons go in with #tree = TRUE related to sometimes Drupal not getting the $form_state['triggering_element'] right? This necessitated all the logic looking at $_POST['triggering_element_name']......
$form['redirect_settings']['url_params'] = array(
'#type' => 'webform_multi_url_params',
'#title' => 'URL Redirect Parameters',
'#required' => FALSE,
'#default_value' => array(
'webform_multi_url_params' => array(
'url_params' => array(
0 => array('params' => array('source_param' => 'someParam', 'redirect_param' => 'someParam')),
),
),
),
);
To use this in any form you are creating, you'd add something like this to your form definition: