Multiple form buttons with AJAX, how to update form state storage data? I have a form built with the Form API that has multiple button form elements. I don't want any of these to submit the form normally, I want them to utilize #ajax and callbacks to update the display. I feel like I run into this on every so often and can't quite remember how to make it work.

When the form first loads, I want half of the buttons to be disabled. When one of the buttons is clicked, I want to be able to detect this in buildForm so I can set form defaults and remove the disable property so other buttons can now be used.

I thought I could set storage in the callback and read it back the next time the form is built:

// Relevant bit of the form...
$form['#prefix'] = '&lt;div id="my-form-wrapper"&gt;';
$form['#suffix'] = '&lt;/div&gt;';

$form['actions']['#type'] = 'actions';

$form['actions']['update'] = [
  '#type' =&gt; 'button',
  '#value' =&gt; $this-&gt;t('Start Form'),
  '#ajax' =&gt; [
    'wrapper' =&gt; 'my-form-wrapper',
    'callback' =&gt; [$this, 'update'],
    'method' =&gt; 'replace',
  ]
];

$form['actions']['reset'] = [
  '#type' =&gt; 'button',
  '#value' =&gt; $this-&gt;t('Reset Form'),
  '#ajax' =&gt; [
    'wrapper' =&gt; 'my-form-wrapper',
    'callback' =&gt; [$this, 'reset'],
    'method' =&gt; 'replace',
  ],
  '#disabled' =&gt; TRUE,
];

// The AJAX callback
public function update(array &amp;$form, FormStateInterface $form_state) {
  $form_state-&gt;set('flag_1', TRUE);
  $form_state-&gt;set('flag_2', "Started!");
  $form_state-&gt;setRebuild();
}


The callback fires, and I see $form_state storage get updated with those arbitrary values, but when the form is rebuilt, I do not see them in $form_state anymore.

I looked at a few other similar form API AJAX questions, but did not have any luck getting unstuck.

Note: I do not want to have to juggle this with jQuery. I want to be able to update form data behind the scenes and rebuild the form appropriately with the relevant data.
Please try this, as @4k4 suggested you have to first build a normal form and ajaxify by using #ajax, and from the method defined inside #ajax you can return a $form and any fields inside the wrapper. 

// Relevant bit of the form...
$form['#prefix'] = '&lt;div id="my-form-wrapper"&gt;';
$form['#suffix'] = '&lt;/div&gt;';

$form['actions']['#type'] = 'actions';

$form['actions']['update'] = [
  '#type' =&gt; 'button',
  '#value' =&gt; $this-&gt;t('Start Form'),
  '#submit' =&gt; ['::setAjaxSubmit'],
  '#ajax' =&gt; [
    'wrapper' =&gt; 'my-form-wrapper',
    'callback' =&gt; [$this, 'update'],
    'method' =&gt; 'replace',
  ]
];

$form['actions']['reset'] = [
  '#type' =&gt; 'button',
  '#value' =&gt; $this-&gt;t('Reset Form'),
  '#ajax' =&gt; [
    'wrapper' =&gt; 'my-form-wrapper',
    'callback' =&gt; [$this, 'reset'],
    'method' =&gt; 'replace',
  ],
  '#disabled' =&gt; TRUE,
];

// The AJAX callback
public function update($form, FormStateInterface $form_state) {
//return $form or part inside the ajax wrapper
return $form;
}

// The submit callback
public function setAjaxSubmit($form, FormStateInterface $form_state) {
  $form_state-&gt;set('flag_1', TRUE);
  $form_state-&gt;set('flag_2', "Started!");
  $form_state-&gt;setRebuild();
}