1

Here is what happens: I've create a content type poll, which admin can create polling questions and answers. Then this polling node will be rendering in a new Page node with node reference (using paragraph).

I manage to create a paragraph preprocess on .theme which will pass the NID to the buildForm.

Here is how it looks like on preprocess:

function THEME_preprocess_paragraph__poll_and_sidebar(&$variables) {
  $paragraph = $variables['paragraph'];
  $poll_form = '';
  if (!$paragraph->field_poll_content->isEmpty()) {
    $node_id = $paragraph->field_poll_content->getValue();
    $nid = $node_id[0]['target_id'];
    $poll_form = \Drupal::formBuilder()->getForm('Drupal\mypoll\Form\PollForm', $nid);
  }
  $variables['poll_form'] = $poll_form;
}

The myPoll buildForm module:

 public function buildForm(array $form, FormStateInterface $form_state, $nid= null) {

if (!$nid == null) {

  // check if user have voted
    $get_count_voter = $this->queryVoter($_COOKIE['cusid'],$nid);

  // Function on node load
    $poll_form_result = $this->getPollDetail($nid); 

    $each_answer = [];

    foreach ($poll_form_result['answers'] as $answer_value) {
      $each_answer_id = $answer_value->id();
      $each_answer['answer'][$each_answer_id] = $answer_value->get('field_polling_answers')->value;
      $each_answer['calc'][$each_answer_id] = $answer_value->get('field_answers_calculation')->value;
    }

    $answer_type = 'checkboxes';

    if ($poll_form_result['poll_type'] == 'linear' || $poll_form_result['poll_type'] == 'multiple_2') {
      $answer_type = 'radios';
    }

    $form['poll_'.$nid] = [
      '#markup' => '',
    ];

    $form['poll_'.$nid]['headline'] = [
      '#markup' => '<h3>' . $poll_form_result['headline'] . '</h3>'
    ];

    $form['poll_'.$nid]['question'] = [
      '#markup' => '<p>' . $poll_form_result['question'] . '</p>'
    ];

    $form['poll_'.$nid]['sub_question'] = [
      '#markup' => '<p class="poll__question">' . $poll_form_result['sub_question'] . '</p>'
    ];

  if ($get_count_voter == true) {

    $form['poll_'.$nid]['answers'] = array(
      '#type' => $answer_type,
      '#options' => $each_answer['answer'],
    );

    $form['poll_'.$nid]['poll_type'] = [
      '#type' => 'hidden',
      '#value' => $poll_form_result['poll_type'],
    ];

    $form['poll_'.$nid]['poll_user_cookie'] = [
      '#type' => 'hidden',
      '#value' => $_COOKIE['cusid'],
    ];

    $form['poll_'.$nid]['poll_nid'] = [
      '#type' => 'hidden',
      '#value' => $nid,
    ];

     $form['poll_'.$nid]['actions']['#type'] = 'actions';
      $form['poll_'.$nid]['actions']['submit'] = array(
      '#type' => 'submit',
      '#value' => $this->t('Submit'),
      '#button_type' => 'primary',
      '#name' => 'submit-'.$nid,
      '#attributes' => array(
        'class' => array(
          'button--darkblue'
       ),
        'id' => array(
          'submit-'.$nid
        ),
      ),
   );

  } else {

    $form['poll_'.$nid]['result'] = [
    '#markup' => $this->t('RESULT'),
  ];

  }
    return $form;
}
}

On 1 page there will be more than 1 polls, for this example, I will have 2 sets of polling and it was successfully display 2 sets of forms but when I click submit button on the 2nd form , and trying to dump $form_state, it always pickup the 1st form value.

Is there a way I can define the Form ID by NID or any suggestion on fix?

Thanks, Queenie

1 Answer 1

4

You need to call your form like this:

$form = new Drupal\mypoll\Form\PollForm($nid);
$poll_form = \Drupal::formBuilder()->getForm($form);

Then add this methods to your form class:

protected $nid;

public function __construct($nid)
{
  $this->nid = $nid;
}

public function getFormId()
{
  return 'my_form-' . $this->nid;
}

And you need to make sure that $nid is different each time the form is on the page.

0

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.