htmlburger / carbon-fields

WordPress Custom Fields Library ✨
https://carbonfields.net/
Other
1.38k stars 244 forks source link

Usability problems with missing required fields #759

Open mark-dlc opened 5 years ago

mark-dlc commented 5 years ago

Version

Expected Behavior

When the 'save' action is disabled due to missing values for required fields, the user should also be informed that the reason he cannot continue is because of missing required fields. For example by highlighting the required fields for which a value is not provided, or by providing a message stating which fields are missing.

Actual Behavior

When the user tries to save a post / theme options, while values for required fields are missing, the save or publish button is disabled. It is not made clear to (novice) users why the save button is disabled. Especially for pages with a large collection of fields, or when fields are 'hidden' in a tabbed container, users will need more information about why they are unable to save their changes (i.e. by stating which required fields they are missing).

Container definition

Container::make( 'theme_options', __( 'Theme Options' ) ) ->add_fields( array( Field::make( 'text', 'crb_text', 'Text Field' ) ->set_required( true ) ) );

Steps to Reproduce the Problem

  1. User the container definition above to create theme options
  2. As a wordpress (admin) user, visit the theme options sections.
  3. You will find that the save button is disabled with no explanation. Especially in a situation with many fields, or fields hidden in tabs, users may not understand why the button is disabled.

This applies to theme options, as well as post meta fields.

Comments

Usability is important, and users should be allowed to recover from errors (such as missing a required field).

gaambo commented 5 years ago

I also had this bug when using blocks in gutenberg. Carbon Fields dispatches the postlock and releases ist correctly, but does not show any indication why or which block/field is missing. Only when you focus a required field and move away again it get's an error state and shows the message that it's required. I thought about how to solve it in gutenberg: showing a notice seems to be to much (just think fo 4 blocks with 3 fields each - that'd be 12 notices) - the pre-publish checks also don't seem to be the right place. maybe marking the block with a red outline/border?

mark-dlc commented 4 years ago

I wrote a server side workaround. It's far from ideal but it may be use-full depending on your use case.

use Carbon_Fields\Container;
use Carbon_Fields\Field;
use Carbon_Fields\Carbon_Fields;
use Carbon_Fields\Helper\Helper;

/*
     * This function returns a list of all required fields that are missing for a post
     * Returns empty array if all required fields have a value.
     */
    static function getAllMissingRequiredFields($post_id){
        $repository = Carbon_Fields::resolve( 'container_repository' );

        $containers = $repository->get_containers('post_meta');
        $fields = array();
        foreach ( $containers as $container ) {
            if ($container->is_valid_attach_for_object($post_id)) {
                $fields = array_merge($fields, $container->get_fields());
            }
        }
        $values = array();
        foreach ( $fields as $field ) {
            if ( ! $field->is_required() ) {
                continue;
            }

            $value =  Helper::get_value( $post_id, 'post_meta', '', $field->get_base_name() );

            if (empty($value)) {
                $values[] = $field->get_base_name();
            }
        }

        return $values;
    }

You could use it from a post update hook, or carbon meta container saved hook like:

$missingRequiredFields = static::getAllMissingRequiredFields($post_id);
            if (count($missingRequiredFields) > 0) {
                $post_update = array('ID' => $post_id, 'post_status' => 'draft');
                wp_update_post($post_update);
                wp_die("Missing required fields: " . implode(" ", $missingRequiredFields) . ");
            }

Obviously, you would need to always enable the 'update' / 'publish' post button on the client side with some custom javascript. Again, a client side checker as per the original issue would be a real must to properly address this problem.