diff --git a/modules/order/src/Element/ProfileSelect.php b/modules/order/src/Element/ProfileSelect.php
index 0f36739..de5b3e5 100644
--- a/modules/order/src/Element/ProfileSelect.php
+++ b/modules/order/src/Element/ProfileSelect.php
@@ -6,6 +6,7 @@
use Drupal\Component\Utility\Html;
use Drupal\Component\Utility\NestedArray;
use Drupal\Core\Entity\Entity\EntityFormDisplay;
+use Drupal\Core\Form\FormState;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Render\Element\RenderElement;
use Drupal\profile\Entity\ProfileInterface;
@@ -70,9 +71,6 @@ public function getInfo() {
[$class, 'validateElementSubmit'],
[$class, 'validateForm'],
],
- '#commerce_element_submit' => [
- [$class, 'submitForm'],
- ],
'#theme_wrappers' => ['container'],
];
}
@@ -123,7 +121,7 @@ public static function validateElementProperties(array $element) {
public static function processElement(array $element, FormStateInterface $form_state, array &$complete_form) {
self::validateElementProperties($element);
- $element_state = self::getElementState($element['#parents'], $form_state, ['mode' => 'view']);
+ $element_state = self::getElementState($element['#parents'], $form_state);
// If the provided profile is in a previous revision, make sure it stays
// available as an option when $element['#profile'] gets changed.
if (empty($element['#profile_latest_revision']) && empty($element_state['fixed_option'])) {
@@ -160,7 +158,7 @@ public static function processElement(array $element, FormStateInterface $form_s
// where to return the customer upon cancelling form mode.
$element_state['selected_option'] = $selected_option;
}
- elseif (!empty($element_state['selected_option'])) {
+ elseif (!empty($element_state['selected_option']) && !$form_state->get('cancel_profile')) {
$selected_option = $element_state['selected_option'];
}
else {
@@ -170,7 +168,7 @@ public static function processElement(array $element, FormStateInterface $form_s
}
}
- if ($selected_option == '_new') {
+ if ($selected_option == '_new' && !$form_state->get('cancel_profile')) {
$element['#profile'] = $profile_storage->create([
'type' => $element['#profile_type'],
'uid' => $element['#profile_uid'],
@@ -186,15 +184,16 @@ public static function processElement(array $element, FormStateInterface $form_s
$element['#profile'] = $profile_storage->load($id_parts[0]);
}
}
+ $form_state->set('cancel_profile', FALSE);
$id_prefix = implode('-', $element['#parents']);
$wrapper_id = Html::getUniqueId($id_prefix . '-ajax-wrapper');
$element = [
- '#prefix' => '
',
- '#suffix' => '
',
- // Pass the id along to other methods.
- '#wrapper_id' => $wrapper_id,
- ] + $element;
+ '#prefix' => '',
+ '#suffix' => '
',
+ // Pass the id along to other methods.
+ '#wrapper_id' => $wrapper_id,
+ ] + $element;
if ($element_state['mode'] == 'view') {
$element['profile_selection'] = [
@@ -206,9 +205,7 @@ public static function processElement(array $element, FormStateInterface $form_s
'callback' => [get_called_class(), 'ajaxRefresh'],
'wrapper' => $wrapper_id,
],
- '#limit_validation_errors' => [
- array_merge($element['#parents'], ['profile_selection']),
- ],
+ '#limit_validation_errors' => [],
'#weight' => -1,
'#access' => !empty($profile_options),
];
@@ -217,7 +214,7 @@ public static function processElement(array $element, FormStateInterface $form_s
$element['profile'] = $view_builder->view($element['#profile'], 'default');
$element['edit_button'] = [
- '#type' => 'submit',
+ '#type' => 'button',
'#value' => t('Edit'),
'#limit_validation_errors' => [],
'#ajax' => [
@@ -250,19 +247,54 @@ public static function processElement(array $element, FormStateInterface $form_s
$widget_element['address']['#available_countries'] = $element['#available_countries'];
}
}
-
+ // Create a dummy button so the triggering element is not a button that
+ // has real significance. See FormBuilder->doBuildForm logic around
+ // support for IE and setTriggeringElement.
+ $element['dummy'] = [
+ '#type' => 'button',
+ '#value' => t('Dummy'),
+ '#attributes' => ['class' => ['visually-hidden']],
+ '#limit_validation_errors' => [],
+ '#ajax' => [
+ 'callback' => [get_called_class(), 'ajaxRefresh'],
+ 'wrapper' => $wrapper_id,
+ ],
+ '#submit' => [
+ [get_called_class(), 'ajaxSubmit'],
+ ],
+ ];
+ $element['submit'] = [
+ '#type' => 'submit',
+ '#value' => t('Save'),
+ '#ajax' => [
+ 'callback' => [get_called_class(), 'ajaxRefresh'],
+ 'wrapper' => $wrapper_id,
+ ],
+ '#submit' => [
+ [get_called_class(), 'ajaxSubmit'],
+ ],
+ '#name' => implode('_', $element['#parents']) . '_submit',
+ '#element_mode' => 'view',
+ '#save_profile' => TRUE,
+ '#access' => !empty($profiles),
+ '#button_type' => 'primary',
+ ];
$element['cancel_button'] = [
'#type' => 'submit',
- '#value' => t('Return to address selection'),
+ '#value' => t('Cancel'),
'#limit_validation_errors' => [],
'#ajax' => [
'callback' => [get_called_class(), 'ajaxRefresh'],
'wrapper' => $wrapper_id,
],
- '#submit' => [[get_called_class(), 'ajaxSubmit']],
+ '#submit' => [
+ [get_called_class(), 'ajaxSubmit'],
+ ],
'#name' => implode('_', $element['#parents']) . '_cancel',
'#element_mode' => 'view',
+ '#cancel' => TRUE,
'#access' => !empty($profiles),
+ '#button_type' => 'danger',
];
}
@@ -285,31 +317,21 @@ public static function processElement(array $element, FormStateInterface $form_s
* form, as a protection against buggy behavior.
*/
public static function validateForm(array &$element, FormStateInterface $form_state) {
- $element_state = self::getElementState($element['#parents'], $form_state, ['mode' => 'view']);
- if ($element_state['mode'] == 'form') {
+ self::getElementMode($form_state);
+ $triggering_element = $form_state->getTriggeringElement();
+ $form_state->set('save_profile', FALSE);
+ $form_state->set('cancel_profile', FALSE);
+ if (!empty($triggering_element['#save_profile']) && !empty($element['form'])) {
$form_display = EntityFormDisplay::collectRenderDisplay($element['#profile'], 'default');
$form_display->extractFormValues($element['#profile'], $element['form'], $form_state);
$form_display->validateFormValues($element['#profile'], $element['form'], $form_state);
- }
- }
-
- /**
- * Submits the element form.
- *
- * @param array $element
- * The form element.
- * @param \Drupal\Core\Form\FormStateInterface $form_state
- * The current state of the form.
- */
- public static function submitForm(array &$element, FormStateInterface $form_state) {
- $element_state = self::getElementState($element['#parents'], $form_state, ['mode' => 'view']);
- if ($element_state['mode'] == 'form') {
- $form_display = EntityFormDisplay::collectRenderDisplay($element['#profile'], 'default');
- $form_display->extractFormValues($element['#profile'], $element['form'], $form_state);
- if ($element['#profile']->hasTranslationChanges()) {
+ if (!FormState::hasAnyErrors() && $element['#profile']->hasTranslationChanges()) {
$element['#profile']->save();
}
}
+ if (!empty($triggering_element['#cancel'])) {
+ $form_state->set('cancel_profile', TRUE);
+ }
}
/**
@@ -374,32 +396,58 @@ public static function ajaxRefresh(array &$form, FormStateInterface $form_state)
public static function ajaxSubmit(array &$form, FormStateInterface $form_state) {
$triggering_element = $form_state->getTriggeringElement();
$element = NestedArray::getValue($form, array_slice($triggering_element['#array_parents'], 0, -1));
- $element_state = self::getElementState($element['#parents'], $form_state, ['mode' => 'view']);
- $element_state['mode'] = $triggering_element['#element_mode'];
+ $element_state = self::getElementState($element['#parents'], $form_state);
self::setElementState($element['#parents'], $form_state, $element_state);
$form_state->setRebuild();
}
/**
+ * Submits the element form.
+ *
+ * @param array $element
+ * The form element.
+ * @param \Drupal\Core\Form\FormStateInterface $form_state
+ * The current state of the form.
+ */
+ public static function submitForm(array &$element, FormStateInterface $form_state) {}
+
+ /**
* Gets the element state.
*
* @param array $parents
* The element parents.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* The current state of the form.
- * @param array $defaults
- * The defaults.
*
* @return array
* The element state.
*/
- public static function getElementState(array $parents, FormStateInterface $form_state, array $defaults) {
+ public static function getElementState(array $parents, FormStateInterface $form_state) {
$parents = array_merge(['element_state', '#parents'], $parents);
$element_state = (array) NestedArray::getValue($form_state->getStorage(), $parents);
- return $element_state + $defaults;
+ $element_state['mode'] = self::getElementMode($form_state);
+ return $element_state;
}
/**
+ * Get the element mode.
+ *
+ * @param \Drupal\Core\Form\FormStateInterface $form_state
+ * The current state of the form.
+ *
+ * @return string
+ * The element mode.
+ */
+ public static function getElementMode(FormStateInterface $form_state) {
+ $triggering_element = $form_state->getTriggeringElement();
+ if (!empty($triggering_element['#element_mode'])) {
+ $form_state->set('element_mode', $triggering_element['#element_mode']);
+ }
+ return $form_state->get('element_mode') ?: 'view';
+ }
+
+
+ /**
* Sets the element state.
*
* @param array $parents