Issue #2115695 by justAChris, plopesc, rpayanm, mpdonadio, larowlan: Datetimelist element only works when all the fields are filled
parent
935fd2c41b
commit
3843053735
|
@ -55,19 +55,21 @@ class Datelist extends DateElementBase {
|
|||
$date = NULL;
|
||||
if ($input !== FALSE) {
|
||||
$return = $input;
|
||||
if (isset($input['ampm'])) {
|
||||
if ($input['ampm'] == 'pm' && $input['hour'] < 12) {
|
||||
$input['hour'] += 12;
|
||||
if (empty(static::checkEmptyInputs($input, $parts))) {
|
||||
if (isset($input['ampm'])) {
|
||||
if ($input['ampm'] == 'pm' && $input['hour'] < 12) {
|
||||
$input['hour'] += 12;
|
||||
}
|
||||
elseif ($input['ampm'] == 'am' && $input['hour'] == 12) {
|
||||
$input['hour'] -= 12;
|
||||
}
|
||||
unset($input['ampm']);
|
||||
}
|
||||
elseif ($input['ampm'] == 'am' && $input['hour'] == 12) {
|
||||
$input['hour'] -= 12;
|
||||
$timezone = !empty($element['#date_timezone']) ? $element['#date_timezone'] : NULL;
|
||||
$date = DrupalDateTime::createFromArray($input, $timezone);
|
||||
if ($date instanceOf DrupalDateTime && !$date->hasErrors()) {
|
||||
static::incrementRound($date, $increment);
|
||||
}
|
||||
unset($input['ampm']);
|
||||
}
|
||||
$timezone = !empty($element['#date_timezone']) ? $element['#date_timezone'] : NULL;
|
||||
$date = DrupalDateTime::createFromArray($input, $timezone);
|
||||
if ($date instanceOf DrupalDateTime && !$date->hasErrors()) {
|
||||
static::incrementRound($date, $increment);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -250,7 +252,7 @@ class Datelist extends DateElementBase {
|
|||
$title = '';
|
||||
}
|
||||
|
||||
$default = !empty($element['#value'][$part]) ? $element['#value'][$part] : '';
|
||||
$default = isset($element['#value'][$part]) && trim($element['#value'][$part]) != '' ? $element['#value'][$part] : '';
|
||||
$value = $date instanceOf DrupalDateTime && !$date->hasErrors() ? $date->format($format) : $default;
|
||||
if (!empty($value) && $part != 'ampm') {
|
||||
$value = intval($value);
|
||||
|
@ -265,7 +267,7 @@ class Datelist extends DateElementBase {
|
|||
'#attributes' => $element['#attributes'],
|
||||
'#options' => $options,
|
||||
'#required' => $element['#required'],
|
||||
'#error_no_message' => TRUE,
|
||||
'#error_no_message' => FALSE,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -300,6 +302,7 @@ class Datelist extends DateElementBase {
|
|||
$input_exists = FALSE;
|
||||
$input = NestedArray::getValue($form_state->getValues(), $element['#parents'], $input_exists);
|
||||
if ($input_exists) {
|
||||
$all_empty = static::checkEmptyInputs($input, $element['#date_part_order']);
|
||||
|
||||
// If there's empty input and the field is not required, set it to empty.
|
||||
if (empty($input['year']) && empty($input['month']) && empty($input['day']) && !$element['#required']) {
|
||||
|
@ -309,6 +312,11 @@ class Datelist extends DateElementBase {
|
|||
elseif (empty($input['year']) && empty($input['month']) && empty($input['day']) && $element['#required']) {
|
||||
$form_state->setError($element, t('The %field date is required.'));
|
||||
}
|
||||
elseif (!empty($all_empty)) {
|
||||
foreach ($all_empty as $value){
|
||||
$form_state->setError($element[$value], t('A value must be selected for %part.', array('%part' => $value)));
|
||||
}
|
||||
}
|
||||
else {
|
||||
// If the input is valid, set it.
|
||||
$date = $input['object'];
|
||||
|
@ -317,12 +325,34 @@ class Datelist extends DateElementBase {
|
|||
}
|
||||
// If the input is invalid, set an error.
|
||||
else {
|
||||
$form_state->setError($element, t('The %field date is invalid.'));
|
||||
$form_state->setError($element, t('The %field date is invalid.', array('%field' => !empty($element['#title']) ? $element['#title'] : '')));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the input array for empty values.
|
||||
*
|
||||
* Input array keys are checked against values in the parts array. Elements
|
||||
* not in the parts array are ignored. Returns an array representing elements
|
||||
* from the input array that have no value. If no empty values are found,
|
||||
* returned array is empty.
|
||||
*
|
||||
* @param array $input
|
||||
* Array of individual inputs to check for value.
|
||||
* @param array $parts
|
||||
* Array to check input against, ignoring elements not in this array.
|
||||
*
|
||||
* @return array
|
||||
* Array of keys from the input array that have no value, may be empty.
|
||||
*/
|
||||
protected static function checkEmptyInputs($input, $parts) {
|
||||
// Filters out empty array values, any valid value would have a string length.
|
||||
$filtered_input = array_filter($input, 'strlen');
|
||||
return array_diff($parts, array_keys($filtered_input));
|
||||
}
|
||||
|
||||
/**
|
||||
* Rounds minutes and seconds to nearest requested value.
|
||||
*
|
||||
|
|
|
@ -519,6 +519,84 @@ class DateTimeFieldTest extends WebTestBase {
|
|||
$this->assertOptionSelected("edit-$field_name-0-value-day", '31', 'Correct day selected.');
|
||||
$this->assertOptionSelected("edit-$field_name-0-value-hour", '17', 'Correct hour selected.');
|
||||
$this->assertOptionSelected("edit-$field_name-0-value-minute", '15', 'Correct minute selected.');
|
||||
|
||||
// Test the widget for partial completion of fields.
|
||||
entity_get_form_display($this->field->getTargetEntityTypeId(), $this->field->getTargetBundle(), 'default')
|
||||
->setComponent($field_name, array(
|
||||
'type' => 'datetime_datelist',
|
||||
'settings' => array(
|
||||
'increment' => 1,
|
||||
'date_order' => 'YMD',
|
||||
'time_type' => '24',
|
||||
),
|
||||
))
|
||||
->save();
|
||||
\Drupal::entityManager()->clearCachedFieldDefinitions();
|
||||
|
||||
// Test the widget for validation notifications.
|
||||
foreach ($this->datelistDataProvider() as $data) {
|
||||
list($date_value, $expected) = $data;
|
||||
|
||||
// Display creation form.
|
||||
$this->drupalGet('entity_test/add');
|
||||
|
||||
// Submit a partial date and ensure and error message is provided.
|
||||
$edit = array();
|
||||
foreach ($date_value as $part => $value) {
|
||||
$edit["{$field_name}[0][value][$part]"] = $value;
|
||||
}
|
||||
|
||||
$this->drupalPostForm(NULL, $edit, t('Save'));
|
||||
$this->assertResponse(200);
|
||||
$this->assertText(t($expected));
|
||||
}
|
||||
|
||||
// Test the widget for complete input with zeros as part of selections.
|
||||
$this->drupalGet('entity_test/add');
|
||||
|
||||
$date_value = array('year' => 2012, 'month' => '12', 'day' => '31', 'hour' => '0', 'minute' => '0');
|
||||
$edit = array();
|
||||
foreach ($date_value as $part => $value) {
|
||||
$edit["{$field_name}[0][value][$part]"] = $value;
|
||||
}
|
||||
|
||||
$this->drupalPostForm(NULL, $edit, t('Save'));
|
||||
$this->assertResponse(200);
|
||||
preg_match('|entity_test/manage/(\d+)|', $this->url, $match);
|
||||
$id = $match[1];
|
||||
$this->assertText(t('entity_test @id has been created.', array('@id' => $id)));
|
||||
|
||||
// Test the widget to ensure zeros are not deselected on validation.
|
||||
$this->drupalGet('entity_test/add');
|
||||
|
||||
$date_value = array('year' => 2012, 'month' => '12', 'day' => '31', 'hour' => '', 'minute' => '0');
|
||||
$edit = array();
|
||||
foreach ($date_value as $part => $value) {
|
||||
$edit["{$field_name}[0][value][$part]"] = $value;
|
||||
}
|
||||
|
||||
$this->drupalPostForm(NULL, $edit, t('Save'));
|
||||
$this->assertResponse(200);
|
||||
$this->assertOptionSelected("edit-$field_name-0-value-minute", '0', 'Correct minute selected.');
|
||||
}
|
||||
|
||||
/**
|
||||
* The data provider for testing the validation of the datelist widget.
|
||||
*
|
||||
* @return array
|
||||
* An array of datelist input permutations to test.
|
||||
*/
|
||||
protected function datelistDataProvider() {
|
||||
return [
|
||||
// Year only selected, validation error on Month, Day, Hour, Minute.
|
||||
[['year' => 2012, 'month' => '', 'day' => '', 'hour' => '', 'minute' => ''], '4 errors have been found: Month, Day, Hour, Minute'],
|
||||
// Year and Month selected, validation error on Day, Hour, Minute.
|
||||
[['year' => 2012, 'month' => '12', 'day' => '', 'hour' => '', 'minute' => ''], '3 errors have been found: Day, Hour, Minute'],
|
||||
// Year, Month and Day selected, validation error on Hour, Minute.
|
||||
[['year' => 2012, 'month' => '12', 'day' => '31', 'hour' => '', 'minute' => ''], '2 errors have been found: Hour, Minute'],
|
||||
// Year, Month, Day and Hour selected, validation error on Minute only.
|
||||
[['year' => 2012, 'month' => '12', 'day' => '31', 'hour' => '0', 'minute' => ''], '1 error has been found: Minute'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue