jwaliszko / ExpressiveAnnotations

Annotation-based conditional validation library.
MIT License
351 stars 123 forks source link

How can I check if a list of GUID (CheckboxList) is empty? #129

Closed Znow closed 8 years ago

Znow commented 8 years ago

Hi

I've tried fiddling around with checking if a list of GUID's (CheckboxList) is empty or not.

But it seems to be triggered wrong.

ClientID is a DropdownList in the view. ClientIDs is a CheckboxList in the view.

[RequiredIf("!ListHasAny(ClientIDs))]
public Guid? ClientID { get; set; }

[RequiredIf("ClientID == null")]
public List<Guid> ClientIDs { get; set; }

public bool ListHasAny(List<Guid> list)
{
    return list.Any();
}
ea.addMethod('ListHasAny', function (list) {
    return list.length > 0;
});

View:

@Html.LabelFor(model => model.ClientID, htmlAttributes: new { @class = "control-label col-md-2 edit" })
    <div class="col-md-10">
        <div class="input-group">
            <span class="input-group-addon"><span class="glyphicon glyphicon-user"></span></span>
            @Html.DropDownListFor(model => model.ClientID, Model.Clients, "Modtager", new { @class = "form-control", @id = "dropdowntoggle" })
        </div>
        @Html.ValidationMessageFor(model => model.ClientID, "", new { @class = "text-danger" })
    </div>

@Html.LabelFor(model => model.ClientIDs, htmlAttributes: new { @class = "control-label col-md-2 edit" })
    <div class="form-group" style="max-height: 200px; overflow-y: scroll">
        <div class="col-md-10 checkbox" id="checklist">
            @Html.CheckBoxListFor(model => model.ClientIDs, Model.Clients, false, new { @class = "form-control borderless" })
        </div>
        @Html.ValidationMessageFor(model => model.ClientIDs, "", new { @class = "text-danger" })
    </div>

I need only to validate "ClientID" IF ClientIDs is empty or null, and only validate "ClientIDs" if ClientID is null.

The problem occurs if "ClientID" is "empty" or null, ie. nothing is selected in the dropdown. Then the clientvalidation does not show for the CheckboxList if none is selected there.

image

Kind regards

jwaliszko commented 8 years ago

Provided data is insufficient to troubleshoot.

There is no information whether it is client- or server-side problem. No logs like web console output or eventual exception stack. No view rendering code, neither the output HTML.

Due to that what I can advice is to check the sample project for similar example.

Znow commented 8 years ago

@jwaliszko I've updated the first post with more information.

Your sample project, does not have an example of this scenario, where I need to check for a list of something has any.

That's why I'm asking.

Znow commented 8 years ago

@jwaliszko I rethinked my scenario, and saw that I only need

[RequiredIf("ClientIDs == null")]
public Guid? ClientID { get; set; }

As it will always validate this field if the other is null, which it always will be, if its not set.

This seems to work fine. All though, the client-side validation doesn't fire again in this scenario:

  1. Select a ClientID from the dropdown
  2. Go down to ClientIDs, click the button "Show clients" (this will "undo" the first choice in ClientID dropdown)
  3. Select a client in the checkbox list
  4. Uncheck that client again
  5. Go to other field and start entering
  6. ClientID dropdown, is still marked as valid

("Modtager" is a blank value, invalid choice) image

jwaliszko commented 8 years ago

Unfortunately, without a self-contained, minimal, reproducible test case there's not much I can do about this bug report. Provide me such a sample so I can look into it.

jwaliszko commented 8 years ago

One remark though. From what I think you have a client-side issue. Your expression is based on a list of values, which at are distracted among multiple form fields. Due to that you may need to use a value parser mechanism to deserialize the distracted chunks of data to the list object manually, prior to passing the list to any method.

Exemplary usage of value parser for a list of checkboxes you can find in the sample - the starting point.