jbrinley / wp-forms

An API for creating and processing forms in WordPress
101 stars 10 forks source link

Question - Radio elements and post-validation state #10

Open emeraldjava opened 10 years ago

emeraldjava commented 10 years ago

Hey,

I've a simple form with three radio elements. My issue is that if validation fails on any of the elements in the form, the state of the radio elements is lost. This does not happen for the text elements. I'm wondering is there something i'm expected as the form developer to handle this case or should the framework be expected to handle this.

My code

        $gender_drop_down = WP_Form_Element::create('radios')->set_name('bhaa_gender')
            ->set_label('Gender')->set_classes(array('radio-inline'))
            ->add_option('M','M')
            ->add_option('W','W');

and a screen shot of the form

image

Note - The gender field was selected before this form was submitted. I just want to avoid have to re-check the three radio buttons each time.

brainthinks commented 10 years ago

I ran into this same problem and I was able to patch the repo to get it working. To state the problem more generally, when a form is submitted and validation fails, the selected radio options are not displayed when the form is re-rendered.

The problem (in my opinion) lies in the default radios view - /classes/views/WP_Form_View_Radios.php

The radios element is re-rendered using the WP_Form_View_Radios->radios() method. In this method, there is no logic that will mark a specific radio button as checked. Here is how I fixed the problem in my environment:

Change this:

$output .= $this->radio( $key, $label, $attributes );

To this:

if ($element->get_value() == $key) {
  $output .= $this->radio( $key, $label, $attributes + array('checked' => 'checked') );
}
else {
  $output .= $this->radio( $key, $label, $attributes );
}

And it should work as you expect. This will retrieve the value that the user set in the radios and set that individual radio as checked.

Note that I suspect that this default radios view will also not render any value or default value up front (meaning when the form is originally rendered rather than when it is re-rendered upon validation failure), though I did not test this. In that case, I think the fix would be:

if ($element->get_value() == $key) {
  $output .= $this->radio( $key, $label, $attributes + array('checked' => 'checked') );
}
elseif (empty($element->get_value()) && $element->get_default_value() == $key) {
  $output .= $this->radio( $key, $label, $attributes + array('checked' => 'checked') );
}
else {
  $output .= $this->radio( $key, $label, $attributes );
}