enisn / UraniumUI

Uranium is a Free & Open-Source UI Kit for MAUI.
Apache License 2.0
985 stars 110 forks source link

MultiplePickerField does not show validation errors #628

Open nickl-martin opened 1 month ago

nickl-martin commented 1 month ago

MultiplePickerField does not have any error text or icon when validations are applied.

Consider the following layout:

<input:FormView>

    <mtrl:PickerField
        Title="My Single Picker"
        ItemsSource="{Binding Items}">
        <mtrl:PickerField.Validations>
            <v:RequiredValidation/>
        </mtrl:PickerField.Validations>
    </mtrl:PickerField>

    <mtrl:MultiplePickerField
        Title="My Multi Picker"
        ItemsSource="{Binding Items}">
        <mtrl:MultiplePickerField.Validations>
            <v:RequiredValidation/>
        </mtrl:MultiplePickerField.Validations>
    </mtrl:MultiplePickerField>

    <Button
        Text="Submit"
        input:FormView.IsSubmitButton="True"/>

</input:FormView>

When the submit button is pressed without filling out either field it only shows the error for the single picker field.

enisn commented 1 month ago

Probably the items colletion is not null, it's an empty collection. You probably need to create a validation something like that:

public class CollectionNotEmptyValidation : IValidation
{
    public string Message { get; set; }

    public bool Validate(object value)
    {
        if (value is ICollection<object> collection)
        {
            return collection.Count > 0;
        }
        return false;
    }
}

And use it like this:

<material:MultiplePickerField Title="Multiple Picker">
    <material:MultiplePickerField.Validations>
        <root:CollectionNotEmptyValidation Message="At least one option must be selected." />
    </material:MultiplePickerField.Validations>
</material:MultiplePickerField>

I'll consider handling collections in RequiredValidation in the library in the next version

nickl-martin commented 1 month ago

I see. Having RequiredValidation check for empty collections would be useful, however that is only part of the problem.

I dug a little deeper and found the real issue. MultiplePickerField does not override the GetValueForValidator() virtual method defined on InputField. Because of this it uses the implementation in InputField which just returns new object() (see below). https://github.com/enisn/UraniumUI/blob/45858514387014504eb82f1ed90ceae5846a9a9e/src/UraniumUI.Material/Controls/InputField.Validation.cs#L97

This could be resolved with the following code added to MultiplePickerField.

protected override object GetValueForValidator()
{
    return SelectedItems;
}