Unbreakable
Unbreakable

Reputation: 8112

How to dynamically display a textbox and make it required based on radiobox selected in my ASP.NET MVC 5 application

So, I am learning basics of Jquery. I have two radioboxes and one textbox, and if "first" radiobox is selected hide the textbox and if "Second" radiobox is selected I want to show a textbox and make it as "Required Field" too at the same time. I tried some solution, but I think I overcomplicated it.

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="col-md-10">
    <input class="js-radio" id="SelectedRoleType" name="SelectedRoleType" type="radio" value="JobSeeker"> Job Seeker
    <input class="js-radio" id="SelectedRoleType" name="SelectedRoleType" type="radio" value="Referrer"> Referrar
</div>      
<div class="col-md-10">
    <input class="form-control" id="Email" name="Email" type="text" value="">
</div>

Steps I followed to achieve to my solution.

  1. added one class "MyTextBoxClass" to the textbox - [Not sure if it was necessary]
  2. Added "display to none"

  3. Added one class "MyRadioClass" to the radiobox - [Not sure if it was necessary]

    <div> <input class="MyRadioClass" id="SelectedRoleType" name="SelectedRoleType" type="radio" value="JobSeeker"> Job Seeker <input class="MyRadioClass" id="SelectedRoleType" name="SelectedRoleType" type="radio" value="Referrer"> Referrar </div>

  4. Added a "CHANGE" event on that MyRadioClass
  5. On change checked the value of the radiobox,
  6. If it is second one then removed the Style attribute so that NONE is taken out and added "Required Attribute"
  7. If it is the first checkbox then add display as none

$('.MyRadioClass').on('change', function () {
    if($('input[name=SelectedRoleType]:checked').val() == "Referrer")
    {
        $('.MyTextBoxClass').removeAttr("style");
        $('.MyTextBoxClass #Email').attr('required','required');
    }
    else {
        $('.MyTextBoxClass').css('display', 'none');
    }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="col-md-10 MyRadioClass">
    <input class="js-radio" id="SelectedRoleType" name="SelectedRoleType" type="radio" value="JobSeeker"> Job Seeker
    <input class="js-radio" id="SelectedRoleType" name="SelectedRoleType" type="radio" value="Referrer"> Referrar
</div>
        
<div class="col-md-10 MyTextBoxClass" style="display:none;">
    <input class="form-control" id="Email" name="Email" type="text" value="">
</div>

Question 1. When I submit the form the "Required" attribute is not getting appended. I am able to submit the form without putting any value in the textbox.

Question 2. Is there a more sleek way of doing what I wanted to achieve?

My Actual Code:

<h2>@ViewBag.Title.</h2>

@using (Html.BeginForm("Register", "Account", FormMethod.Post, new { @class = "form-horizontal", role = "form" }))
{
    <div class="form-group MyRadioClass">
        <div class="col-md-10">
            @Html.RadioButtonFor(m => m.SelectedRoleType, "JobSeeker", new { @class="js-radio"}) Job Seeker
            @Html.RadioButtonFor(m => m.SelectedRoleType,"Referrer", new { @class="js-radio"}) Referrar
        </div>
    </div>
    <div class="form-group MyTextBoxClass" style = "display:none" ">
        @Html.LabelFor(m => m.Email, new { @class = "col-md-2" })
        <div class="col-md-10">
            @Html.TextBoxFor(m => m.Email, new { @class = "form-control" })
        </div>
    </div>

    <div class="form-group">
        <div class="col-md-offset-2 col-md-10">
            <input type = "submit" class="btn btn-default" value="Register" />
        </div>
    </div>

}
<button class="btn btn-info">
    <i class="fa fa-lg fa-fw fa-facebook"></i>
    facebook
</button>


@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}

<script>
    $('.MyRadioClass').on('change', function () {
        if($('input[name=SelectedRoleType]:checked').val() == "Referrer")
        {
            $('.MyTextBoxClass').show();
            $('.MyTextBoxClass input').attr('required', true);

        }
        else {
            $('.MyTextBoxClass').hide();
        }
    });

</script>

Upvotes: 3

Views: 2061

Answers (5)

user3559349
user3559349

Reputation:

Your issue is that your using the jquery.validate.js and jquery.validate.unobtrusive.js libraries for client side validation. These are not compatible with HTML-5 validation (which the required attribute is), and the jquery.validate.js modifies your <form> tag to add the novalidate attribute so your required attribute is ignored.

In order to get both client and server side validation you need to apply a conditional validation attribute. There are plenty of example of these on SO, or you could use foolproof [RequiredIf] attribute. In addition, if you want to learn to write your own I recommend reading The Complete Guide To Validation In ASP.NET MVC 3 - Part 2.

Using the foolproof attribute, your model property will be

[RequiredIf("SelectedRoleType", "Referrer", ErrorMessage = "...")]
public string Email { get; set; }

If you select the 2nd radio button (for 'Referrer') and leave the Email control empty, you submit action will be cancelled and the error message will be displayed in the view.

Then to show/hide the elements associated with the email property, your script should be

$('.MyRadioClass .js-radio').on('change', function () {
    if($('input[name=SelectedRoleType]:checked').val() == "Referrer") {
        $('.MyTextBoxClass').show();
    }
    else {
        $('.MyTextBoxClass').hide();
    }
});

Upvotes: 1

guest271314
guest271314

Reputation: 1

Note, there are duplicate ids within HTML at Question at id="SelectedRoleType". id of element in document should be unique. Substitute setting "SelectedRoleType" at class attribute at HTML.

You can use .toggle() to set display of element to block or none using .index() of currently clicked <input type="radio"> element

$(function() {
  $(".js-radio").on("click", function() {
    $("#Email").toggle(!!$(this).index())
  })
})
#Email {
  display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="col-md-10">
  <input class="js-radio SelectedRoleType" name="SelectedRoleType" type="radio" value="JobSeeker"> Job Seeker
  <input class="js-radio SelectedRoleType" name="SelectedRoleType" type="radio" value="Referrer"> Referrar
</div>
<div class="col-md-10">
  <input class="form-control" id="Email" name="Email" type="text" value="" required>
</div>

Upvotes: 0

Vikas
Vikas

Reputation: 749

You're doing it wrong way. You should have a clear understanding of jQuery selectors.

$('.MyTextBoxClass').css('required'); wouldn't work as you're selecting an HTML element, not the input field.

Secondly, .css() is not what you're looking for. Do something like this to make it work:

$(".MyTextBoxClass input").attr("required", true);

And, to show and hide your text input, I recommend using jQuery's show() and hide() methods.

So your code would look like this:

$('.MyRadioClass').on('change', function () {
    if($('input[name=SelectedRoleType]:checked').val() == "Referrer")
    {
        $('.MyTextBoxClass').show();
        $('.MyTextBoxClass input').attr('required', true);
    }
    else {
        $('.MyTextBoxClass').hide();
        $('.MyTextBoxClass input').removeAttr('required');
    }
});

If it still doesn't work, let me know.

EDIT: Remove validate tag from your form tag and use jQuery's submit event to solve the issue. Here's a link you may want to read Stop form refreshing page on submit

e.g.,

$(document).ready(function(){
    $('yourForm').removeAttr("novalidate");
});

$('yourForm').on('submit', function(event){
    event.preventDefault();
    //DO STUFF
});

Upvotes: 2

Scott L
Scott L

Reputation: 549

You could definitely clean this up a little. Some ideas:

  1. Using the input names as selectors (performance hit, but negligible in this use case)
  2. No need to remove the required attribute when hiding the text input
  3. Use a ternary instead of a if/else to save a line (up to you if this is less readable)
  4. Chain the show() and attr() calls together

So based on the above, we'd be left with something like this:

$('[name="SelectedRoleType"]').on('change', function(e) {
  e.target.value === "Referrer"
    ? $('[name="Email"]').show().attr('required', true)
    : $('[name="Email"]').hide()
});

Working jsfiddle: https://jsfiddle.net/ke4p37cy/

Upvotes: 0

Bilal Hussain
Bilal Hussain

Reputation: 1011

$('.MyRadioClass').on('change', function () {
    if($('input[name=SelectedRoleType]:checked').val() == "Referrer")
    {
        $('.MyTextBoxClass').removeAttr("style");
        $('.MyTextBoxClass #Email').attr('required','required');
    }
    else {
        $('.MyTextBoxClass').css('display', 'none');
        
    }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form action="/" type="POST">
<div class="col-md-10 MyRadioClass">
    <input class="js-radio" id="SelectedRoleType" name="SelectedRoleType" type="radio" value="JobSeeker"> Job Seeker
    <input class="js-radio" id="SelectedRoleType" name="SelectedRoleType" type="radio" value="Referrer"> Referrar
</div>
        
<div class="col-md-10 MyTextBoxClass" style="display:none;">
    <input class="form-control" id="Email" name="Email" type="text" value="">
    
    
</div>
<input type="submit" value="test submit">
</form>

Here's your tested working code. Let me know if this worked!

Upvotes: 1

Related Questions