I'm currently working on a D8 project and I'm displaying a node edit form in a block. I use template_preprocess_table in order to pass some parameters to my theme but when I submit the form using ajax the form is reloaded and the parameters are lost so I don't get the correct form format.
Update:
In my MYTHEME.theme file:
function MYTHEME_preprocess_table(&$variables) {
if($variables['attributes']['id'] == 'field-completion-milestones-values'){
$element = $variables['rows'];
foreach( $element as $key => $milestones){
$completion_milestone = $milestones['cells'][1]['content'];
if(isset($completion_milestone['field_milestone'])){
$milestone_id = $completion_milestone['field_milestone']['widget']['#default_value'][0];
$default_completion_milestone = array('name' => $milestone_id);
$type_id = milestoneGetTypeId($default_completion_milestone);
if($type_id == 156) {//Milestones with links - create button
$variables['rows'][$key]['cells'][1]['content']['test_button'] = TRUE;
}
else if($type_id == 155){//Milestones with upload document button
$variables['rows'][$key]['cells'][1]['content']['test_upload'] = TRUE;
}
else if($type_id == 154){//Milestones without link or upload buttons
$variables['rows'][$key]['cells'][1]['content']['test_plain'] = TRUE;
}
}
}
}
}
And in my table.html.twig file:
{% set milestone_id = cell.content.field_milestone['widget']['#default_value'][0] %}
{% if(milestone_id) %}
<div class="delivery__completed-milestones__field">
<label>{{ cell.content.field_milestone['widget']['#options'][milestone_id] }}</label>
<span class="status-marker delayed">D</span>
{% if cell.content.field_tip['widget'][0]['value']['#default_value'] %}
<span class="custom-tooltip"><span title="{{ cell.content.field_tip['widget'][0]['value']['#default_value'] }}">?</span></span>
{% endif %}
{% if cell.content.test_button %}
{% set custom_url = cell.content.field_url['widget'][0]['uri']['#default_value'] %}
{% if cell.content.field_url['widget'][0]['title']['#default_value'] %}
{% set link_text = cell.content.field_url['widget'][0]['title']['#default_value'] %}
{% else %}
{% set link_text = cell.content.field_url['widget'][0]['uri']['#default_value'] %}
{% endif %}
<a class="button" href ="{{ custom_url }}">{{ link_text }}</a>
{% endif %}
{% if cell.content.test_upload %}
{{ cell.content.field_milestone_completion_up }}
{% endif %}
<div class="hidden">
{{ cell.content.field_delivery_status }}
</div>
</div>
{% endif %}
My form submit function:
public static function ajaxFormEntityFormSubmit($form, &$form_state) {
$entity = $form_state->getBuildInfo()['callback_object']->getEntity();
// Clear user input.
$input = $form_state->getUserInput();
// We should not clear the system items from the user input.
$clean_keys = $form_state->getCleanValueKeys();
$clean_keys[] = 'ajax_page_state';
foreach ($input as $key => $item) {
if (!in_array($key, $clean_keys) && substr($key, 0, 1) !== '_') {
unset($input[$key]);
}
}
// Store new entity for display in the AJAX callback.
$input['entity'] = $entity;
$form_state->setUserInput($input);
// Rebuild the form state values.
$form_state->setRebuild();
$form_state->setStorage([]);
}
And my callback:
public static function ajaxFormEntityCallback(&$form, \Drupal\Core\Form\FormStateInterface $form_state) {
// If errors, returns the form with errors and messages.
if ($form_state->hasAnyErrors()) {
return $form;
}
// Else show the result.
else {
$userInputs = $form_state->getUserInput();
$entity = $userInputs['entity'];
$entity_type = $entity->getEntityTypeId();
$configurations = $form_state->getValue('ajax_form_entity');
$response = new AjaxResponse();
// Get messages even if not shown.
$status_messages = array('#type' => 'status_messages');
$message = \Drupal::service('renderer')->renderRoot($status_messages);
// Reload the form.
$response->addCommand(new ReplaceCommand($configurations['form_selector'], $form));
return $response;
}
}
In my hook_form_alter :
$form['#attributes']['class'][] = $ajax_id;
$form['actions']['submit']['#submit'][] = 'Drupal\MY_MODULE\Plugin\Form\FormAlter::ajaxFormEntityFormSubmit';
$form['actions']['submit']['#ajax'] = array(
'callback' => 'Drupal\MY_MODULE\Plugin\Form\FormAlter::ajaxFormEntityCallback',
'wrapper' => $ajax_id,
'effect' => 'fade',
);
$form['ajax_form_entity'] = [
'#type' => 'hidden',
'#value' => [
'reload' => '.reload',
'form_selector' => '.' . $ajax_id,
'show_message' => TRUE,
]
];
What I'm doing is to show/hide fields from a field collection field based on a taxonomy term value. Maybe this is not the best solution but I didn't find any other way to solve my problem.
Is it possible to store those vars somehow after ajax submit?
Thanks in advance.