laravel / prompts

Beautiful and user-friendly forms for your command-line PHP applications.

Home Page:https://laravel.com/docs/prompts

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

SelectPrompt $required is not allowed to be false

code-distortion opened this issue · comments

commented

Laravel Prompts Version

v0.1.12

Laravel Version

v10.29.0

PHP Version

8.2.11

Operating System & Version

Debian GNU/Linux 12 (bookworm) (php:8.2.11-fpm docker image)

Terminal Application

GNOME Terminal

Description

Hi Jess and Co. Prompts is a useful package and I appreciate the effort put in to it.

The relatively recent change f48bc94 forces SelectPrompt's $required bool|string to not be false anymore.

This broke the prompts for me because of the way I use the SelectPrompt.

In my project, I give the user a number of options to choose from. The last option is sometimes called "Back" and sometimes called "Quit", and has a key of '' (an empty string). For me an empty string is a consistent way of checking that the user wants to return from the current prompt / go back / exit / quit etc without having to worry about the wording. e.g.

$options = [
    'database' => 'Database Management',
    'deploy' => 'Deployment',
    '' => 'Quit',
];

$choice = select(
    label: "Main",
    options: $options,
    required: false, // <<<< This would allow '' (i.e. Quit) to be chosen
);

if ($choice === '') {
    break;
}

(My actual code is abstracted and the $options are passed in, so it's less hard-coded than this).

I can get around it by setting $required to '', but it seems odd to solve it that way.

The commit explicitly checks to make sure that $required is not false, so I thought I'd ask about the reason behind that? Or am I simply not using it as intended?

Steps To Reproduce

$options = [
    'database' => 'Database Management',
    'deploy' => 'Deployment',
    '' => 'Quit',
];

$choice = select(
    label: "Main",
    options: $options,
);

if ($choice === '') {
    break;
}

The Quit option can't be picked.

 ┌ Main ────────────────────────────────────────────────────────┐
 │   ○ Database Management                                      │
 │   ○ Deployment                                               │
 │ › ● Quit                                                     │
 └──────────────────────────────────────────────────────────────┘
  ⚠ Required.

Hey @code-distortion,

The commit explicitly checks to make sure that $required is not false, so I thought I'd ask about the reason behind that? Or am I simply not using it as intended?

Before the change, $required could not be configured for the select prompt because it's inherently required to select one of the configured options. The $required parameter was added to allow customisation of the error message when the select prompt is run in non-interactive mode without a default specified. Because it was always true previously, it seemed to make sense to prevent it from being set to false to ensure that the return value would always be one of the configured options regardless of whether it's run interactively or non-interactively.

It wasn't intended for users to ever get a required validation error when running the select prompt interactively because all configured options should be valid.

I'm curious how you were able to set $required to false before f48bc94?

I think the real issue is that the validation check should allow empty-strings for the select prompt. The current check is very generic for all prompts and the empty-string check is really just for prompts like text where an empty string should not be valid.

I'll work up a PR to fix this.

I can get around it by setting $required to '', but it seems odd to solve it that way.

Agreed. It's a bit of a hack that relies on a falsy check.

commented

Hi Jess. Thank you, that's great. I understand now.

Sorry for the confusion. In the first example I showed required: false, to indicate what would help solve the problem if it worked. In my actual code before the update, I omitted the required field when calling select().

Your proposed solution of allowing the empty-string option to be chosen for select inputs seems like the right idea to me too.

Great! #99 should solve this.

Thanks for your help!

commented

Yes, that's fixed it up for me. Thank you.