I'm sorry if this is repeated somewhere, but I really did try to look and couldn't come up with anything.
My scenario:
I have a form, and within that form I have a div/wrapper, with two elements in it: a) a text field and b) a checkboxes element
I have two different elements that change the values/options of those using the #ajax attribute
- 1) a textfield that, when changed, updates the value in a) and populates the options in b)
- 2) a button that's pressed (after the user enters some data) that adds an option to b)
1) works fine 2) semi-works; when you add (x), it doesn't show up (though the data gets stored in the DB fine). If you immediately add (y), (x) shows up in the options, but not (y). Add (z), and (y) shows up, and so on; so, it's always one back....
1) and 2) use different callback functions, but utilize the same wrapper
The form:
function waiver_create_waiver($form, &$form_state) {
$form['id'] = array(
'#type' => 'textfield',
'#title' => 'ID',
'#ajax' => array(
'callback' => '_update_user_info',
'wrapper' => 'user-info-wrapper',
),
);
$form['user_info_div'] = array(
'#prefix' => '<div id="user-info-wrapper">',
'#suffix' => '</div>',
);
$form['user_info_div']['username'] = array(
'#type' => 'textfield',
'#title' => 'User Name',
);
$id = trim($form_state['values']['id']);
$user = user_load_by_name($id);
// Create the checkboxes
$user_hardware = _get_users_hardware($user);
$hardware_options = array();
foreach($user_hardware as $h) {
$hardware_options[$h['hid']] = $h['hardware_type'] . ' (' . $h['manufacturer'] . ') ' . 'S/N: ' . $h['serial_number'] . ', Last Seen: ' . date('D, n/d/Y g:i a', $h['last_seen']);
}
$form['user_info_div']['selected_hardware_checkboxes'] = array(
'#type' => 'checkboxes',
'#title' => t('Select Registered Hardware'),
'#options' => $hardware_options,
);
//...some textfields and selects for entering hardware info, removed for brevity...
$form['register_hardware_fieldset']['register_button'] = array(
'#type' => 'button',
'#value' => 'Register New User Hardware',
'#ajax' => array(
'callback' => '_update_hardware',
'wrapper' => 'user-info-wrapper',
),
);
return $form;
}
Callback for 1) $form['id']['#ajax']
function _update_user_info($form, &$form_state) {
$id = trim($form_state['values']['id']);
$ldap_search = ldap_connector_query_ldap(trim($id)); // This is a custom LDAP query function
$form['user_info_div']['username']['#value'] = ucwords(strtolower($ldap_search['cn'][0]));
return $form['user_info_div'];
}
Callback for 2) $form['register_hardware_fieldset']['register_button']['#ajax']
function _update_hardware($form, &$form_state) {
$id = trim($form_state['values']['id']);
if($id != NULL && $id != '') {
$user = user_load_by_name($id);
// If the user isn't on the site yet, create an account for them
if(!$user) {
$new_user = array(
'name' => $id,
'pass' => user_password(),
'mail' => $id . '@email.com',
'init' => $id . '@email.com',
'status' => 1, // Active user
'roles' => array(DRUPAL_AUTHENTICATED_RID => "authenticated user"),
);
$user = user_save(NULL, $new_user);
}
// ...Find $hardware_type and $manufacturer from elements cut from above for brevity...
// Insert the hardware in to the database...
db_insert('waiver_hardware')->fields(array(
'user_id' => $user->uid,
'date_added' => REQUEST_TIME,
'hardware_type' => $hardware_type,
'manufacturer' => $manufacturer,
))
->execute();
}
return $form['user_info_div'];
}
EDIT: I've tried adding the options to the checkboxes element within the callback, as well as making the $form a reference call, but to no avail.