Change form submit #access as a result of ajax callback I have a form that requests some information first, then pre-populates other fields before a final submit.  I'm trying to change the #access value for the buttons on the form.  Both of the code snippets below come from the same form builder function.

Considering:

$form['actions'] = [
  'id_lookup' =&gt; [
    '#type' =&gt; 'submit',
    '#title' =&gt; 'Submit',
    '#value' =&gt; 'Lookup ID',
    '#ajax' =&gt; [
      'callback' =&gt; 'my_module_populate_id_info',
      'wrapper' =&gt; 'id_info',
      'method' =&gt; 'replace',
      'effect' =&gt; 'fade',
    ],
  ],
  'submit' =&gt; [
    '#type' =&gt; 'submit',
    '#title' =&gt; 'Submit',
    '#value' =&gt; 'Register for Event',
    '#access' =&gt; FALSE,
  ],
  '#weight' =&gt; 100
];


The above code provides two buttons, one which triggers the ajax callback (see below) and the other which will submit the final form.

The below code adds additional fields (they're all disabled) with information pre-populated.  Everything works as expected, I just want to change #access on id_lookup to false and on submit to true, it's not working.  I originally tried to just change the value, but I couldn't get that to work either.

if (!empty($form_state['values']['id'])) {
  $user_info = my_module_signup_get_id_info($form_state['values']['id']);
  $ldap_user = FALSE;
  $existing_user = FALSE;
  if (isset($user_info['ldap_user'])) {
    $ldap_user = TRUE;
    $first_name = $user_info['ldap_user']['givenname'][0];
    $last_name = $user_info['ldap_user']['sn'][0];
    $job_title = $user_info['ldap_user']['title'][0];
    $organization = $user_info['ldap_user']['department'][0];
    $email = $user_info['ldap_user']['mail'][0];

    $form['id_info']['first_name'] = [
      '#type' =&gt; 'textfield',
      '#title' =&gt; 'First Name',
      '#required' =&gt; TRUE,
      '#prefix' =&gt; '&lt;div class="row"&gt;&lt;div class="col-lg-6"&gt;',
      '#suffix' =&gt; '&lt;/div&gt;&lt;/div&gt;',
      '#disabled' =&gt; TRUE,
      '#default_value' =&gt; $user_info['ldap_user']['givenname'][0],
  ];
  // ... some other fields
  // Try to change the #access on the actions
  $form['actions']['id_lookup']['#access'] = FALSE;
  $form['actions']['submit']['#access'] = TRUE;
} else {
  $form['id_info']['no_user'] = [
    '#type' =&gt; 'markup',
    '#markup' =&gt; '&lt;p&gt;No user was found for that ID&lt;/p&gt;',
  ];
}


}

Everything works as expected except the access on those buttons - what am I doing wrong?
You really shouldn't alter the form in your ajax callback.  What you want to do is set a variable in the form_state in the ajax callback, and your form code should look for that variable to decide how to set #access

So in your ajax callback, lets say whatever conditions are met, and you want to disable access when it reloads...

So set a variable like, $form_state['access_to_field_revoked'] = TRUE

Then your form code:

$form['actions'] = [
  'id_lookup' =&gt; [
    '#type' =&gt; 'submit',
    '#title' =&gt; 'Submit',
    '#value' =&gt; 'Lookup ID',
    '#access' =&gt; empty($form_state['access_to_field_revoked']) ? TRUE : FALSE,
    '#ajax' =&gt; [
      'callback' =&gt; 'my_module_populate_id_info',
      'wrapper' =&gt; 'id_info',
      'method' =&gt; 'replace',
      'effect' =&gt; 'fade',
    ],
  ],
  'submit' =&gt; [
    '#type' =&gt; 'submit',
    '#title' =&gt; 'Submit',
    '#value' =&gt; 'Register for Event',
    '#access' =&gt; !empty($form_state['access_to_field_revoked']) ? TRUE : FALSE,
  ],
  '#weight' =&gt; 100
];


You will probably need another variable like $form_state['generate_additional_fields'] = TRUE;
and put your FAPI for those fields in the form callback, and not the ajax callback...
so in your form callback:

if(!empty($form_state['generate_additional_fields']) {
// add your additional form fields now
}


Almost never a reason to alter the $form variable in the ajax callback. It is always best to set a variable in the form_state and then look for that variable in the form callback to actually set the FAPI up.  

UPDATE:
Misread the post, so your code was in the form handler, not the ajax handler, and that will work. 

One way that the #access property would not get updated is if the 'actions' buttons are outside of the wrapper div that ajax replaces. If they are, they would be showing via the '#access' value from initial form load.  One solution would be to make sure that the wrapper that the ajax callback refreshes includes the action buttons, so that they are re-rendered.

In the FAPI inside your conditional, there is a suffix, with an extra /div . This maybe the closing div for your wrapper, and if that was placed after the form actions, perhaps they would get refreshed by the ajax callback, and it would work