sagesky36
sagesky36

Reputation: 4692

form validation with razor

I have the following in my .net mvc razor form and I'm clicking on the submit button, but it's not being validated by the validation in the js. I debugged it in Firefox and instead, goes right to the form method and no validation comes out on the form to stop the form submission.

the HTML output of the model.LoanId is simply LoanId.

How can I properly validate the form????

What am I doing wrong?

HTML

        @using (Html.BeginForm("Refresh", "Home", FormMethod.Post, new { id = "frmTemps" })) 
    <tr>
                    <td>
                    @Html.LabelFor(model => model.LoanId)
                    @Html.TextBoxFor(model => model.LoanId)
                    <td colspan="3">
                        <input type="submit" id="btnRefresh" value='Refresh' />
                    </td>
                </tr>

js

$("#frmTemps").validate({
        event: "submit",
        rules: {
            LoanID: {
                required: true
            }
        },
        messages: {
            LoanID: {
                required: ' Please enter a Loan ID. '
            }
        }
    });

I also tried it with non-model data below and got the same thing.

    @Html.Label("loanid:", "LoanID")
                    @Html.TextBox("loanID")


Here is the html I'm trying to validate:
<td>@Html.LabelFor(model => model.LoanType)
                    @Html.TextBox("SBA", "SBA")
                    @Html.ValidationMessageFor(model => model.LoanType)
                    @*@Html.TextBoxFor(model => model.LoanType)*@
                </td>
                <td>
                    <label for="ddlDept">Department:</label>
                    @(Html.Kendo().DropDownListFor(model => model.SelectedDeptText)
                            .Name("ddlDept")
                            .DataTextField("DepartmentName")
                            .DataValueField("DepartmentID")
                            .Events(e => e.Change("Refresh"))
                            .DataSource(source =>
                            {
                                source.Read(read =>
                                {
                                    read.Action("GetDepartments", "Home");
                                });
                            })
                    )
                    @Html.ValidationMessageFor(model => model.SelectedDeptText)

View Model

public class ViewModelTemplate_Guarantors
{
    public int SelectedTemplateId { get; set; }
    public IEnumerable<PDFTemplate> Templates { get; set; }

    public int SelectedGuarantorId { get; set; }
    public IEnumerable<tGuarantor> Guarantors { get; set; }

    public string LoanId { get; set; }
    public string SelectedDeptText { get; set; }
    public string LoanType { get; set; }

    public bool ShowTemps { get; set; }
    public string Error { get; set; }
    public string ErrorT { get; set; }
    public string ErrorG { get; set; }
    public bool ShowGeneratePDFBtn { get; set; }
}

_Layout.cshtml

<script src="~/Scripts/jquery-1.7.1.min.js"></script>
<script src="~/Scripts/jquery.validate.min.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>
<script src="~/Scripts/jquery.unobtrusive-ajax.min.js"></script>
<script src="~/Scripts/modernizr-2.5.3.js"></script>
<script src="@Url.Content("~/Scripts/kendo/2012.2.913/kendo.all.min.js")"></script>
<script src="@Url.Content("~/Scripts/kendo/2012.2.913/kendo.aspnetmvc.min.js")"></script>

Validation class

namespace PDFService03Validation.Validations
{
    [MetadataType(typeof(PDFService03_Validation))]
    public partial class PDFService03
    {

}

    public partial class PDFService03_Validation
    {
        public class PDFService03
        {
            [Required(ErrorMessage = "Loan ID Required")]
            [DataType(DataType.Text)]
            public string LoanID { get; set; }

            [Required(ErrorMessage = "Loan Type Required")]
            [DataType(DataType.Text)]
            public string LoanType { get; set; }

            [Required(ErrorMessage = "Department Name Required")]
            [DataType(DataType.Text)]
            public string SelectedDeptText { get; set; }
        }
    }
}

Index method

public ActionResult Index(ViewModelTemplate_Guarantors model)
{
    ViewBag.Error = "";

    model.ShowGeneratePDFBtn = false;

    return View();
}

Index.cshtml - still thinks the object is not set. When debugging, I go into my Controller, sets the variable in the model, then, comes back here. Please help... I don't know what I'm doing incorrectly here. I think I've followed everything as needed.

Sorry to bug you again, but I'm almost there....

I did as you said, but still am not getting any validation errors....

Below, is the html markup that is produced by my View. You can see the scripts I'm using at the top and you can also see the validation in the span tags. What am I missing??? I'm also going to show you the ViewModel I edited. thanks so much ahead of time...

ViewModel

namespace PDFConverterModel.ViewModels
{
    [MetadataType(typeof(ViewModelTemplate_Guarantors_Validation))]
    public partial class ViewModelTemplate_GuarantorsValidation
    {

    }

    public partial class ViewModelTemplate_Guarantors_Validation
    {
        public class ViewModelTemplate_Guarantors
        {
            [Required(ErrorMessage = "Loan ID Required")]
            [DataType(DataType.Text)]
            public string LoanID { get; set; }

            [Required(ErrorMessage = "Loan Type Required")]
            [DataType(DataType.Text)]
            public string LoanType { get; set; }

            [Required(ErrorMessage = "Department Name Required")]
            [DataType(DataType.Text)]
            public string SelectedDeptText { get; set; }
        }
    }

    public class ViewModelTemplate_Guarantors
    {
        public int SelectedTemplateId { get; set; }
        public IEnumerable<PDFTemplate> Templates { get; set; }

        public int SelectedGuarantorId { get; set; }
        public IEnumerable<tGuarantor> Guarantors { get; set; }

        public string LoanId { get; set; }
        public string SelectedDeptText { get; set; }
        public string LoanType { get; set; }

        public bool ShowTemps { get; set; }
        public string Error { get; set; }
        public string ErrorT { get; set; }
        public string ErrorG { get; set; }
        public bool ShowGeneratePDFBtn { get; set; }
    }
}

Page output:

<!DOCTYPE html>
<html>
<head>
    <title>BHG :: PDF Generator</title>
    <link href="/Content/Site.css" rel="stylesheet" type="text/css" />
    <link href="/Content/kendo/2012.2.913/kendo.common.min.css" rel="stylesheet" type="text/css" />
    <link href="/Content/kendo/2012.2.913/kendo.dataviz.min.css" rel="stylesheet" type="text/css" />
    <link href="/Content/kendo/2012.2.913/kendo.blueopal.min.css" rel="stylesheet" type="text/css" />
    <script src="/Scripts/jquery-1.7.1.min.js"></script>
    <script src="/Scripts/jquery.validate.min.js"></script>
    <script src="/Scripts/jquery.validate.unobtrusive.min.js"></script>
    <script src="/Scripts/jquery.unobtrusive-ajax.min.js"></script>
    <script src="/Scripts/modernizr-2.5.3.js"></script>
    <script src="/Scripts/kendo/2012.2.913/kendo.all.min.js"></script>
    <script src="/Scripts/kendo/2012.2.913/kendo.aspnetmvc.min.js"></script>
</head>

<body>
    <div class="page">
        <header>
            <div id="title">
                <h1>BHG :: PDF Generator</h1>
            </div>
        </header>
        <section id="main">


<h2></h2>

<div>

    <table style="width: 1000px">
        <tr>
            <td colspan="5">
                <img alt="BHG Logo" src="/Images/logo.gif" />
            </td>
        </tr>

<form action="/Home/Refresh" id="frmTemps" method="post">            <tr>
                <td>


                <label for="LoanId">LoanId</label>
                <input id="LoanId" name="LoanId" type="text" value="" />
                <span class="field-validation-valid" data-valmsg-for="LoanId" data-valmsg-replace="true"></span>
                <td colspan="3">
                    <input type="submit" id="btnRefresh" value='Refresh' />
                </td>
            </tr>
            <tr>
                <td><label for="LoanType">LoanType</label>
                    <input id="SBA" name="SBA" type="text" value="SBA" />
                    <span class="field-validation-valid" data-valmsg-for="LoanType" data-valmsg-replace="true"></span>

                </td>
                <td>
                    <label for="ddlDept">Department:</label>
                    <input id="ddlDept" name="ddlDept" type="text" /><script>
    jQuery(function(){jQuery("#ddlDept").kendoDropDownList({"change":Refresh,"dataSource":{"transport":{"read":{"url":"/Home/GetDepartments"}},"schema":{"errors":"Errors"}},"dataTextField":"DepartmentName","dataValueField":"DepartmentID"});});
</script>
                    <span class="field-validation-valid" data-valmsg-for="SelectedDeptText" data-valmsg-replace="true"></span>
                </td>
            </tr>
</form>
    </table>

</div>

<script type="text/javascript">

    $('btnRefresh').on('click', '#btnRefresh', function () {
        Refresh();
    });

    function Refresh() {

        var LoanID = $("#LoanID").val();

        if (LoanID != "") {
            document.forms["frmTemps"].submit();
        }
    }
</script>

        </section>
        <footer>
        </footer>
    </div>
</body>
</html>

Upvotes: 4

Views: 38996

Answers (2)

Anirudh Agarwal
Anirudh Agarwal

Reputation: 697

  1. jquery-1.7.1.min.j
  2. kendo.web.min.js
  3. kendo.aspnetmvc.min.js
  4. kendo.validator.min.js
  5. kendo.dataviz.min.js

These 5 files are necessary for the validation to work. I have seen you have added few of these add all these and try. I also faced this problem but this have solved the problem.

also check you web config for this:

<appSettings>
    <add key="ClientValidationEnabled" value="true" />
    <add key="UnobtrusiveJavaScriptEnabled" value="true" />
  </appSettings>

This is also required. Let me no f it works.

Upvotes: 2

Leniel Maccaferri
Leniel Maccaferri

Reputation: 102438

Oh... I see why this is happening. You're forgetting this:

@Html.ValidationMessageFor(model => model.LoanId)

If you don't put the ValidationMessageFor, the unobtrusive validation won't know that this model property needs to be validated before the form submission.

So you must have this:

@Html.LabelFor(model => model.LoanId)
@Html.TextBoxFor(model => model.LoanId)
@Html.ValidationMessageFor(model => model.LoanId)

Don't forget to put some data annotation in your LoanId property first...

For more on this, look here: Validation with the Data Annotation Validators (C#)

EDIT

After you provided more code to the question I could see why the validation errors are not showing.

This happens because you're actually passing your custom ViewModel ViewModelTemplate_Guarantors to the view. As you can see, your view model has no data annotations. The data annotations you provided in the metadata class PDFService03_Validation will only take effect if you pass an object of type PDFService03 to the view. So to solve the problem you'll have to duplicate your data annotations in your ViewModelTemplate_Guarantors view model object. This is code repetition and is terrible ugly but is how it works.

Upvotes: 5

Related Questions