AhmedLSayed9 / dropdown_button2

Flutter's core Dropdown Button widget with steady dropdown menu and many other features.
https://pub.dev/packages/dropdown_button2
MIT License
264 stars 122 forks source link

The border does not change to red on validation error #297

Open nelci592 opened 2 months ago

nelci592 commented 2 months ago

I have the following code. However, when there is a validation error, the underlineinputborder does not change its color:


      DropdownButtonFormField2<MarketingCampaignType>(
      isExpanded: true,
      validator: (value) {
        if (value == null) {
          return S.of(context).campaign_information_missing_type;
        }
        return null;
      },
      menuItemStyleData: const MenuItemStyleData(
        padding: EdgeInsets.only(left: 0),
      ),
      dropdownStyleData: const DropdownStyleData(
        padding: EdgeInsets.only(left: 0),
      ),
      buttonStyleData: const ButtonStyleData(
        padding: EdgeInsets.only(right: 0),
      ),
      autovalidateMode: autovalidateMode,
      decoration: InputDecoration(
        labelText: S.of(context).campaign_information_campaign_type_label,
        floatingLabelBehavior: FloatingLabelBehavior.auto,
        labelStyle: const TextStyle(
          color: Color(0xFF7F849D),
          fontSize: 15,
          height: 0.3,
        ),
         errorBorder: const UnderlineInputBorder(
            borderRadius: BorderRadius.all(Radius.circular(1)),
            borderSide: BorderSide(color: Colors.red, width: 1)),
        focusedBorder: const UnderlineInputBorder(
            borderRadius: BorderRadius.all(Radius.circular(1)),
            borderSide: BorderSide(color: Color(0xFF2A2C42), width: 1)),
        border: const UnderlineInputBorder(
            borderRadius: BorderRadius.all(Radius.circular(1)),
            borderSide: BorderSide(color: Color(0xFF2A2C42), width: 1)),
        enabledBorder: const UnderlineInputBorder(
            borderRadius: BorderRadius.all(Radius.circular(1)),
            borderSide: BorderSide(color: Color(0xFF2A2C42), width: 1)),
        isDense: true,
        hintStyle: const TextStyle(
          color: Color(0xFF7F849D),
          fontSize: 15,
        ),
      ),
      hint: Text(
           "totet",
              style: const TextStyle(
                color: Color(0xFF7F849D),
                fontSize: 15,
              ),
            ),
      items: campaignTypes.map((MarketingCampaignType campaignType) {
        return DropdownItem(
          value: campaignType,
          child: OnHover(
            //Wraping the DropDownMenuItem child so then when Items of drop down is hovering we see hovering effect
            builder: (isHovered) {
              final color =
                  isHovered ? const Color(0xFF252F4A) : const Color(0xFF7F849D);
              final fontWeight =
                  isHovered ? FontWeight.bold : FontWeight.normal;
              return [buildCampaignTypeText(campaignType, color, fontWeight)]
                  .toRow(mainAxisSize: MainAxisSize.max);
            },
          ),
        );
      }).toList(),
      onChanged: (value) {

      },
    )```
yashanghan22 commented 2 months ago

@nelci592 , I think your validation is returning null every time. Try removing your validation and returning a simple string instead to see if it works.

nelci592 commented 2 months ago

@yashanghan22 I have tested on this sample project, however, on error, the underline's color remains the same:

import 'package:dropdown_example/dropdown/dropdown_button2.dart';
import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      title: 'DropdownButton2 Demo',
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key});

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final List<String> items = [
    'Item1',
    'Item2',
    'Item3',
    'Item4',
    'Item5',
    'Item6',
    'Item7',
    'Item8'
  ];
  final valueListenable = ValueNotifier<String?>(null);
  AutovalidateMode _autoValidateMode = AutovalidateMode.disabled;
  final GlobalKey<FormState> _formKey = GlobalKey();

  @override
  void initState() {
    _autoValidateMode = AutovalidateMode.onUserInteraction;

    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(mainAxisAlignment: MainAxisAlignment.center, children: [
          Form(
            key: _formKey,
            child: SizedBox(
              width: 400,
              child: DropdownButtonFormField2<String>(
                autovalidateMode: _autoValidateMode,
                isExpanded: true,
                hint: const Row(
                  children: [
                    Icon(
                      Icons.list,
                      size: 16,
                      color: Colors.yellow,
                    ),
                    SizedBox(
                      width: 4,
                    ),
                    Expanded(
                      child: Text(
                        'Select Item',
                        style: TextStyle(
                          fontSize: 14,
                          fontWeight: FontWeight.bold,
                          color: Colors.yellow,
                        ),
                        overflow: TextOverflow.ellipsis,
                      ),
                    ),
                  ],
                ),
                items: items
                    .map((String item) => DropdownItem<String>(
                          value: item,
                          height: 40,
                          child: Text(
                            item,
                            style: const TextStyle(
                              fontSize: 14,
                              fontWeight: FontWeight.bold,
                              color: Colors.white,
                            ),
                            overflow: TextOverflow.ellipsis,
                          ),
                        ))
                    .toList(),
                valueListenable: valueListenable,
                validator: (value) {
                  if (value == null || value.isEmpty) {
                    return 'Please select an option';
                  }
                  return null;
                },
                onChanged: (value) {
                  valueListenable.value = value;
                },
                decoration: const InputDecoration(
                  labelText: "Text ",
                  floatingLabelBehavior: FloatingLabelBehavior.auto,
                  labelStyle: TextStyle(
                    color: Color(0xFF7F849D),
                    fontSize: 15,
                    height: 0.3,
                  ),
                  errorBorder: UnderlineInputBorder(
                      borderRadius: BorderRadius.all(Radius.circular(1)),
                      borderSide: BorderSide(color: Colors.red, width: 1)),
                  focusedBorder: UnderlineInputBorder(
                      borderRadius: BorderRadius.all(Radius.circular(1)),
                      borderSide:
                          BorderSide(color: Color(0xFF2A2C42), width: 1)),
                  border: UnderlineInputBorder(
                      borderRadius: BorderRadius.all(Radius.circular(1)),
                      borderSide:
                          BorderSide(color: Color(0xFF2A2C42), width: 1)),
                  enabledBorder: UnderlineInputBorder(
                      borderRadius: BorderRadius.all(Radius.circular(1)),
                      borderSide:
                          BorderSide(color: Color(0xFF2A2C42), width: 1)),
                  isDense: true,
                  hintStyle: TextStyle(
                    color: Color(0xFF7F849D),
                    fontSize: 15,
                  ),
                ),
                buttonStyleData: const ButtonStyleData(
                  height: 50,
                  width: 160,
                  padding: EdgeInsets.only(left: 14, right: 14),
                  elevation: 2,
                ),
                iconStyleData: const IconStyleData(
                  icon: Icon(
                    Icons.arrow_forward_ios_outlined,
                  ),
                  iconSize: 14,
                  iconEnabledColor: Colors.yellow,
                  iconDisabledColor: Colors.grey,
                ),
                dropdownStyleData: DropdownStyleData(
                  maxHeight: 200,
                  width: 200,
                  decoration: BoxDecoration(
                    borderRadius: BorderRadius.circular(14),
                    color: Colors.grey,
                  ),
                  offset: const Offset(-20, 0),
                  scrollbarTheme: ScrollbarThemeData(
                    radius: const Radius.circular(40),
                    thickness: MaterialStateProperty.all<double>(6),
                    thumbVisibility: MaterialStateProperty.all<bool>(true),
                  ),
                ),
                menuItemStyleData: const MenuItemStyleData(
                  padding: EdgeInsets.only(left: 14, right: 14),
                ),
              ),
            ),
          ),
          Padding(
            padding: const EdgeInsets.only(top: 50),
            child: TextButton(
                onPressed: () {
                  _formKey.currentState?.validate();
                },
                child: const Text("Validate")),
          )
        ]),
      ),
    );
  }
}
yashanghan22 commented 2 months ago

Can you change the color of all the underlined borders to blue, black, or grey? Do not change the error border color.

Then see if it's work or not because you are giving light red color to focused border, border, enabled border so it might be showing like same colour as error border colour.

nelci592 commented 2 months ago

I have already tested this but it does not seem to work. You can check the sample project that I attached. dropdown_example.zip

yashanghan22 commented 2 months ago

@nelci592 Let me know if it's the solution of your problem

dropdown error border issue.webm

solution: In the input decoration, there is a parameter called errorText, which is a string that can be empty (nullable). By default, its value is null (empty).

I created a variable that will show an error based on validation. For more details, please check the updated code file.

Here is the project with updated code: dropdown_example.zip

let me know if there is an issue in this code.