0

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.

4
  • Paste the whole code, this is not enough information to give nay advice.
    – user21641
    Commented Jul 27, 2017 at 12:42
  • The AJAX are in the form? Which extends FormBase? Something seems off here.
    – Kevin
    Commented Jul 27, 2017 at 13:18
  • @Kevin what do you mean? This code works fine for the rest of my forms but when it reloads the form with those hidden fields I have the problem. I guess that it has to do with the prepossessing as seems like the vars I set are empty when the form reloads.
    – Ismini
    Commented Jul 27, 2017 at 13:27
  • @Kevin the form is not just a custom form but a node edit form placed in a custom block.
    – Ismini
    Commented Jul 27, 2017 at 13:42

1 Answer 1

0

I managed to solve this without using template_preprocess_table. Instead I used created a custom module where I extend the twig in oder to have access to a function in my PHP. In my Twig I call that function and I get as a return the values so as I can display properly the fields needed.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.