cssformssymfonybootstrap-4choicefield

How to display choiceType values in Symfony as Colors


I want to save an integer value in database and display it as a color but I'm not finding the right way to make it.

My Form looks like this one:

public function buildForm(FormBuilderInterface $builder, array $options): void
{
    $builder->add('risk', ChoiceType::class, [
        'choices' => 
            'level.0' => 1,
            'level.1' => 2,
            'level.2' => 3,
            'level.3' => 4,
            'level.4' => 5
        ],
    ]);
}

It should look like this form at the end: enter image description here


Solution

  • First of all thanks for Veve but his Answer was very short and not completed, I got to convert the choice type to radio buttons by adding expanded => true and multiple => false. For more Info see: Symfony Select Tag

    $builder->add('risk', ChoiceType::class, [
         'choices' => [
            'level-0' => 1,
            'level-1' => 2,
            'level-2' => 3,
            'level-3' => 4,
            'level-4' => 5
         ],
            'choice_attr' => function($choice, $key, $value) {
                 return ['class' => 'risk_'.strtolower($key)];
             },
         'expanded' => true,
         'multiple' => false,
         'placeholder' => false
    ]);
    

    Then i used a table to display the values from the form.

    <table class="table risk-colors-table">
        <tr>
            <td class="risk_level-text">Text</td>
            <td class="risk-option level-0">{{ form_row(form.risk[0])}}</td>
            <td class="risk-option level-1">{{ form_row(form.risk[1])}}</td>
            <td class="risk-option level-2">{{ form_row(form.risk[2])}}</td>
            <td class="risk-option level-3">{{ form_row(form.risk[3])}}</td>
            <td class="risk-option level-4">{{ form_row(form.risk[4])}}</td>
        </tr>
    </table>
    

    And i added this css to make a nice design using the classes that i added before and to hide the radio buttons and labels:

    .risk_level-text {
       vertical-align: center!important;
    }
    
    .level-0 {
        background: #63d06c;
    }
    
    .level-1 {
        background: #a7e35c;
    }
    
    .level-2 {
        background: #fdf74d;
    }
    
    .level-3 {
        background: #f0a725;
    }
    
    .level-4 {
        background: #ee0018;
    }
    
    .risk-colors-table {
        width: 100%;
        padding-left: 2px;
    }
    
    .risk-colors-table tr {
        border:2px solid #d9d9d9;
    }
    
    .risk-option {
        float: right;
        vertical-align: center!important;
        border-radius: 25px;
        margin-bottom: 25px;
        height: 28px;
        width:19%;
    }
    
    .risk-option label {
        visibility: hidden;
        text-align: center;
        color:white;
        vertical-align:middle;
    }
    
    .risk-option.active {
        border:3px solid #3362b1;
    }
    
    .risk-colors-table td {
        margin: 10px 1px;
    }
    

    In JavaScript i had to add this function to make the radio button active when i click on the table td:

    $(function () {
        $('.risk-option').click(
            function () {
                $(this).addClass('active').siblings().removeClass('active');
                var $radioBtn = $('.risk-option.active input[type="radio"]');
    
                if ($radioBtn.is(':checked') === true) {
                    $radioBtn.filter('input[type="radio"]').prop('checked', true);
                }
            }
        );
    });
    

    I worked so much on it and i hope it could help someone. The final results is exactly how it shown in the picture in my mean question.