0

I am using MVC ViewModel. There are two radio buttons with yes or no in a form. If the user selects 'Yes' TextField1 will be displayed and if select 'No' TextField2 will be displayed. Both are required fields with an * ( asterick ) symbol. Even both are required fields user is allowed to fill only one TextField at a time based on radiobutton selection. The issue is when user submits one of the textfield required validation error message is displaying. Is there any workaround to fix this issue.

VVR147493
  • 251
  • 2
  • 4
  • 16
  • So are the two fields declared as `Required` in your model as a DataAnnotation? – Grizzly Sep 06 '16 at 14:06
  • Yes. Both are required fields. – VVR147493 Sep 06 '16 at 14:10
  • so are you against using javascript? If not, why not take the `Required` data annotations off of your model, and then in JS check to see if one or the other radio buttons is checked, if yes then `.attr("required")`? – Grizzly Sep 06 '16 at 14:43
  • I tried that but that is not working. – VVR147493 Sep 06 '16 at 15:08
  • Is there any option to change the validation error message of a required attribute using javascript – VVR147493 Sep 06 '16 at 15:10
  • You mean like [this](http://stackoverflow.com/questions/5272433/html5-form-required-attribute-set-custom-validation-message)? – Grizzly Sep 06 '16 at 15:13
  • Use a [foolproof](http://foolproof.codeplex.com/) `[RequiredIf]` or similar conditional validation attribute so you get both client and server side validation –  Sep 06 '16 at 22:15

1 Answers1

1

You can't have both be required if you only display one.

One of the easiest ways to get around this is one of the advantages of using View Models over passing the DTO object to the page.

I will need to make a lot of assumptions here because you haven't provided any code, but your question is straight forward enough. Even if my assumptions are incorrect, the principles can be extrapolated easily to your specific use case.

I'm going to assume that your object looks something like this:

public class DtoObject
{
    public bool IsPositiveSelection { get; set; }
    public string YesReason { get; set; }
    public string NoReason { get; set; }
}

With no knowledge of what is going on, I'll assume you have a good reason for that. Perhaps asking for an email address in one, and phone number the other.

If you haven't already, you will want to create a view model like this:

public class DtoObjectViewModel
{
    public bool YesNoRadio { get; set; }
    [Required]
    public string Reason { get; set; }
}

What I did here is instead of making two separate boxes, have a single one that will always be displayed. If you do need something like email validation on one, and phone number on the other, you can apply that with JavaScript instead of just relying on Attributes.

This will then allow you to ensure that the value is always there, regardless of which state the radio button is in.

At some point, you'll need to map your View Model back to your DTO Object:

private DtoObject MapToDto(DoObjectViewModel model)
{
    return new DtoObject
    {
        IsPositiveSelection = model.YesNoRadio,
        YesReason = model.YesNoRadio ? model.Reason : "",
        NoReason = model.YesNoRadio ? "" : model.Reason
    };
}

There are plenty of other options as well, but those would require more JavaScript, and make any answer even broader than this one already is.

krillgar
  • 12,596
  • 6
  • 50
  • 86
  • Thanks for the quick update. This seems to be the best answer instead of using javascript. But when the user submits I want to show the validation error message for appropriate fields. If I use only one field I can't show for the specific error message for the not selected one. – VVR147493 Sep 06 '16 at 14:24
  • Well with this method, you wouldn't be showing/hiding one of the boxes. You're still going to need some JavaScript, but this would probably be the least amount of work. – krillgar Sep 06 '16 at 14:26
  • Or, you could always run the secondary type checks on the server, and add an error to ModelState and return that to the page. – krillgar Sep 06 '16 at 14:27