During the checkout process, if you hit the "Back" button without filling in any required fields, Drupal throws the usual error message and does not let you go back. I'm guessing this is the proper user experience, but from a technical standpoint it might be tricky since we were using the same submit function for the "Forward" button as well as the "Back".

Comments

Damien Tournoud’s picture

That's because you cannot use a standard required field in the current checkout logic. Checking the required fields should happen manually in the pane validation handler. This way, the pane itself fails validation, but not the whole form.

I'm wondering if we could implement the 'panes (ie. sub-forms) independently validate and submit' logic in a less hackish way then our current "do everything in the main form submit handler" strategy. I'll experiment to see how much code would be necessary to make it play nice with standard form validation (especially #require-ed elements and #element_validate functions, which we cannot use at all in the current system).

rszrama’s picture

On a side note, we could use #limit_validation_errors on the back button to suppress #required errors. The drawback is we'd need a custom submit handler for the back button that doesn't attempt to save data from the various panes on the page - trying to save invalidated data would be disastrous.

So the trade off is we could use actually required fields with a simple workaround for the back button but not capture data that might have been entered on the present page. A better solution that allows that might be forthcoming, but this seems like an acceptable trade off for 1.0 to me. Thoughts?

rszrama’s picture

Status: Active » Fixed

Ok, I've implemented a solution using #limit_validation_errors for now. This gets us around the root issue without requiring every checkout pane that wants to have required fields implementing their own solution to validate the field and indicate to the end user the field is required.

If we decide to pursue this further, the proper solution would be to alter the checkout form once constructed so that all elements with #required == TRUE would be changed via a central function to set #required = FALSE, still display a required indicator, and use a validate handler for the element to check for a value. However I will add that the way it functions now will match customer expectations, which is never a bad default behavior. : )

Commit: http://github.com/rszrama/drupalcommerce/commit/aedbbb2bc14f4b3c90bc5a8d...

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.

bgilhome’s picture

Issue summary: View changes

I've found that the only case #limit_validation_errors doesn't work for is a checkout page containing a commerce_payment_pane. As a slightly hacky workaround, you can attach an onclick or some js to the Back button in this case via a hook_form_alter:

  if (strpos($form_id, 'commerce_checkout_form_') === 0 && $page_id = substr($form_id, strlen('commerce_checkout_form_'))) {
        $checkout_panes = commerce_checkout_panes(array('page' => $page_id));
        if (in_array('commerce_payment', array_keys($checkout_panes))) {
          $form['buttons']['back']['#attributes'] = array('onclick' => "history.go(-1); return false;");
        }
  }