I'm working on creating an unlimited value field in a custom form, and getting hung up on the remove button. I've been able to create a form that will pull the saved values for the fieldset, then allow the user to click an "Add" button to get more date field values in the fieldset. The problem is the individual remove button paired with each date. BTW, the context for the form is that a user needs to be able to add an indeterminate number of dates, then remove or update dates as needed.
I've tried adding the remove buttons with name values that correspond to the date's index in the $form
and $form_state
array values, then accessing that value through $form_state['clicked_button']
, removing the date, then re-rendering the fieldset. I've also tried simply returning nothing from the ajax call in order to just remove that date from the form. I run into different issues with each approach.
If I try to re-render the entire fieldset in the callback, the remove button only removes the last date in the fieldset. I've dpm
-ed all the values that I'm looking at, and I can't figure out where that data is being rendered from.
If I try to return an empty string from the callback and only update the single removed date field, it seems to work initially. After I hit save and the page refreshes though, I'm left with what seems to be a weird re-indexing of my values. For example, if I have consecutive days 1-4 in October and try to remove the 1st, after hitting save, I'm left with 2, 2, 3.
The code I'm working with (including some comments and troubleshooting) is below:
function daily_hours_form($form, &$form_state) {
// Fieldset container where we can add unlimited values
$form['closed_mon_exceptions'] = array(
'#type' => 'fieldset',
'#tree' => TRUE,
'#prefix' => '<div id="closed_mon">',
'#suffix' => '</div>',
'#description' => t('Exceptions to our typical closed Mondays.'),
);
// Add a flag to add on additional Mondays if the user clicks "Add Open Monday"
$form_state['storage']['add_monday'] = isset($form_state['storage']['add_monday']) ? $form_state['storage']['add_monday'] : 0;
if (isset($form_state['clicked_button']) && $form_state['clicked_button']['#value'] == 'Add Open Monday') {
$form_state['storage']['add_monday']++;
}
// If the user clicked to remove a day, need to regenerate the dates with that value removed
if (isset($form_state['clicked_button']) && $form_state['clicked_button']['#value'] == 'Remove Monday') {
// get current values from form_state
$closed_mon_dates_array = $form_state['values']['closed_mon_exceptions'];
// remove the Add Open Monday button from this array
array_pop($closed_mon_dates_array);
// retrieve the index of the one we need to remove
$remove_mon = $form_state['clicked_button']['#name'];
// Try to remove that value from any array it's being used in
//unset($form['closed_mon_exceptions'][$remove_mon]);
unset($form_state['values']['closed_mon_exceptions'][$remove_mon]);
unset($form_state['complete form']['closed_mon_exceptions'][$remove_mon]);
unset($closed_mon_dates_array[$remove_mon]);
// reorder the array, so we have expected 0 through (count-1) indices
$closed_mon_dates_array = array_values($closed_mon_dates_array);
} else {
// if we're not trying to remove a monday, just get the saved values
$closed_mon_dates_array = variable_get('closed_mon_exceptions');
}
dpm($closed_mon_dates_array);
dpm($form_state);
$num_closed_mondays = count($closed_mon_dates_array);
// Add all the current closed Monday exceptions
for ($i = 0; $i < $num_closed_mondays; $i++) {
if (isset($closed_mon_dates_array[$i])) {
$current_date_val = $closed_mon_dates_array[$i];
// Remove the value for the button, if this data was pulled from
// $form_state above
if (count($current_date_val) == 4) {
array_pop($current_date_val);
}
}
dpm($current_date_val); // Just making sure it's formatted as expected...
$form['closed_mon_exceptions'][$i] = array(
'#type' => 'date',
'#default_value' => $current_date_val,
'#title' => t('Closed Monday Exception'),
'#prefix' => '<div id="monday-' . $i . '">',
'#suffix' => '</div>',
);
// Add a remove button for each one
$form['closed_mon_exceptions'][$i]['remove_day'] = array(
'#type' => 'button',
'#value' => t('Remove Monday'),
'#name' => "$i",
'#ajax' => array(
'callback' => 'monday_remove',
'wrapper' => 'closed_mon' // Update the whole fieldset
//'wrapper' => 'monday-' . $i, // Alternately, try to update just this value
),
);
}
// Check if user clicked "Add Open Monday"
if ($form_state['storage']['add_monday'] > 0) {
// Starting index for adding open Mondays
$i = count($closed_mon_dates_array);
$number_to_add = $form_state['storage']['add_monday'];
$end_index = $i + $number_to_add;
for ($index = $i; $index < $end_index; $index++) {
$form['closed_mon_exceptions'][$index] = array(
'#type' => 'date',
'#default_value' => array(),
'#title' => t('Closed Monday Exception'),
'#tree' => TRUE,
'#prefix' => '<div id="monday-' . $index . '">',
'#suffix' => '</div>',
);
$form['closed_mon_exceptions'][$index]['remove_day'] = array(
'#type' => 'button',
'#value' => t('Remove Monday'),
'#name' => "$index",
'#ajax' => array(
'callback' => 'monday_remove',
'wrapper' => 'closed_mon',
//'wrapper' => 'monday-' . $index,
),
);
}
}
$form['closed_mon_exceptions']['add_open_monday'] = array(
'#type' => 'button',
'#value' => t('Add Open Monday'),
'#ajax' => array(
'callback' => 'multi_date_ajax_callback',
'wrapper' => 'closed_mon'
),
);
return system_settings_form($form);
}
function monday_remove($form, &$form_state) {
//return ''; // Trying to update just the date + remove button field
$form_state['rebuild'] = TRUE; // Tried adding this for troubleshooting; not seeing any difference
return $form['closed_mon_exceptions'];
}
function multi_date_ajax_callback($form, &$form_state) {
return $form['closed_mon_exceptions'];
}