0

I've built a super simple form in D8 meant to check the format of the field then when submitted the form data is placed in the DB. I check the format using a Ajax call -- yes, I know js is a better solution but there will be future needs for this solution. The Ajax event is 'change'.

If I use this procedure the form works as needed:

  1. Enter data in textfield
  2. Click outside the textfield
  3. Ajax Call Occurs
  4. Click Save
  5. Submit function called w/ good data

This procedure fails:

  1. Enter data in textfield
  2. Click Save
  3. Ajax Call Occurs
  4. Form gets redrawn
  5. Submit function called w/ empty data

Is there a customary design rule I'm unaware for handling this?

    <?php

/**
 * @file
 * Contains \Drupal\example\Form\ExampleForm.
 */
namespace Drupal\ssForm\Form;

use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use PDO;
use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\CssCommand;
use Drupal\Core\Ajax\HtmlCommand;

include 'ssForm.config';

/**
 * Implements an example form.
 */
class ssForm extends FormBase
{
/**
 * {@inheritdoc}
 */
public function getFormId()
{
    return 'ssForm';
}

/**
 * {@inheritdoc}
 */
public function buildForm(array $form, FormStateInterface $form_state)
{
    $a = 1;
    $form['protocol_name'] = array(
      '#type' => 'textfield',
      '#title' => $this->t('Your Protocol Number.'),
      '#id' => 'protocol_id',
      '#ajax' => [
        'callback' => array($this, 'validateProtocolNameAjax'),
        'event' => 'change',
        'progress' => array(
          'type' => 'throbber',
          'message' => t('Verifying protocol...'),
        ),
      ],
      '#suffix' => '<span class="protocol-valid-message"></span>'
    );

    $form['actions']['submit'] = array(
      '#type' => 'submit',
      '#value' => $this->t('Save'),
      '#button_type' => 'primary',
    );
    return $form;
}

/**
 * {@inheritdoc}
 */
public function validateForm(array &$form, FormStateInterface $form_state)
{
    $a = 1;
}

/**
 * {@inheritdoc}
 */
public function submitForm(array &$form, FormStateInterface $form_state)
{
    try
    {
        $dbName = 'CRUD_boogie';
        $pdo = new PDO("mysql:host=localhost;dbname=CRUD_boogie", 'root', 'root');
        $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    }
    catch (PDOException $e)
    {
        die("DB ERROR: " . $e->getMessage());
    }

    // Build a Prepared Statement
    $stmt = $pdo->prepare("INSERT INTO REGISTRY (name, value, phone, protocol) VALUES (:name, :value, :phone, :protocol)");
    $stmt->bindParam(':name', $name);
    $stmt->bindParam(':value', $value);
    $stmt->bindParam(':phone', $phone);
    $stmt->bindParam(':protocol', $protocol);

    // insert one row
    $name = 'one';
    $value = 1;
    $phone = 'phone_number';
    $protocol = $form_state->getValue('protocol_name');
    $stmt->execute();
}

/**
 * Ajax callback to validate field.
 */
public function validateProtocolNameAjax(array &$form, FormStateInterface $form_state)
{
    $fieldValue = $form_state->getValue('protocol_name');
    $fieldPattern = '/^\d\d-\d\d\d$/';

    $valid = preg_match($fieldPattern, $fieldValue);

    if ($valid) {
        $css = ['border' => '1px solid green'];
        $message = $this->t('Protocol Name Valid.');
    }
    else {
        $a = 2;
        $css = ['border' => '1px solid red'];
        $message = $this->t('Protocol Name Not Valid.');
        $a = 1;
    }

    $testAry = array('test' => 'data'); //added-edit
    $form_state->setStorage($testAry);

    $response = new AjaxResponse();
    $response->addCommand(new CssCommand('#protocol_id', $css));
    $response->addCommand(new HtmlCommand('.protocol-valid-message', $message));
    return $response;
}

}

  • drupal.stackexchange.com/questions/188730/… point #7 – user21641 Mar 9 '16 at 23:07
  • Jaros, did you mean: "in the form definition, get the....." or "always use buttons to....." – Mike Mar 9 '16 at 23:36
  • Just to be clear, I'm not trying to submit w/ Ajax; just not sure how to keep the data in the form_state until it's submitted. Thanks – Mike Mar 9 '16 at 23:40
  • Doesn't matter. Once you are working with core's form ajax you have to use form state storage and submit handlers. – user21641 Mar 10 '16 at 7:09
  • Jaros, I tired to use the form_state[storage] (see the commented lines: added-edit) to hold the data as you mention in point #3 but that doesn't seem to work. Any ideas? – Mike Mar 10 '16 at 20:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.