Search code examples
phplaravelsymfonysymfony-console

How to display console prompt for "choice()" in columns?


In a Laravel command, I am looking for a way to display the 52 options in multiple columns rather than one long list that requires scrolling.

Is this possible?

This is the code I have so far:

do {
    $i++;
    $col_name[$i] = $this->ask('Column name?');
    if ($col_name[$i] != null) {
        $col_type[$i] = $this->choice('Column type?', [
            "0" => 'bigIncrements',
            "1" => 'bigInteger',
            "2" => 'binary',
            "3" => 'boolean',
            "4" => 'char',
            "5" => 'date',
            "6" => 'dateTime',
            "7" => 'dateTimeTz',
            "8" => 'decimal',
            ...
            "51" => 'uuid',
            "52" => 'year'
       ], 'string');
    }
} while ($col_name[$i] != null);

Solution

  • Laravel uses internally Symfony Console component, and specifically the SymfonyStyle and QuestionHelper classes.

    Since these currently only support printing a list for "choice" type of inputs, you can't make it print a table.

    What you could do, is mix it up a bit and use one representation for the options, and a different helper to acquire user input.

    Namelly, print a table with all your options, and then give the user an autocomplete input to pick one of those.

    E.g:

    $options = [
               'bigIncrements',
               'bigInteger',
               'binary',
               'boolean',
               'char',
               'date',
               'dateTime',
               'dateTimeTz',
               'decimal',
               // ...
               'uuid',
               'year'
    ];
    
    $rows    = array_chunk($options, 6);
    $headers = ['Opt 1', 'Opt 2', 'Opt 3', 'Opt 4', 'Opt 5', 'Opt 6'];
    
    $this->table($headers, $rows);
    
    $columnType = $name = $this->anticipate('Column Type?', $options);
    
    

    The fake header with "Opt X" I'm just using because Laravel helper methods give you less options than using the Symfony components directly, but I guess they would do in a pinch.