0

I have implemented a mvc kendo window control in my MVC page and the form validation doenst seem to work. I can the model state as false in the controller but the view doesnt seem showing the messages. Please note here that WorkLogType,WorkLog Subject and Details are required field. I have set the required attribute in the view model. I have also set the validation tag in the view for the respective controls. What is the problem ?

Here is my code

View

@using (Ajax.BeginForm("ActivityWorkLog_Create", "Activity", new AjaxOptions
{
    HttpMethod = "POST",
    OnSuccess = "OnSuccess",
    OnFailure = "OnFailure"
}))
{

<div class="k-popup-edit-form k-window-content k-content" data-role="window">
    <div class="k-edit-form-container">
        @Html.HiddenFor(x => x.RequestID, new { data_bind = "value: requestId" })
        @Html.HiddenFor(x => x.ActivityID, new { data_bind = "value: activityId" })
        @Html.HiddenFor(x => x.CountryCode, new { data_bind = "value: countryCode" })

         <div class="form-group">
            <div class="editor-label">
                @Html.LabelFor(model => model.WorkLogAppliesToName)
            </div>
            <div class="editor-field">
                @(Html.Kendo().ComboBoxFor(model => model.WorkLogAppliesToName)
        .Name("WorkLogAppliesToID")
        .Filter("contains")
        .HtmlAttributes(new { style = "width:300px", @readonly = "readonly" })
        .Placeholder("Select...")
        .DataTextField("WorkLogAppliesToName")
        .DataValueField("WorkLogAppliesToID")

        .DataSource(dataSource => dataSource
            .Read(read => read.Action("GetWorkLogAppliesTo", "WorkLog", new { id = 0 }).Type(HttpVerbs.Post)
            )

        )
                )
                @Html.ValidationMessageFor(model => model.WorkLogAppliesToName, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            <div class="editor-label">
                @Html.LabelFor(model => model.ActivitySLA)
            </div>
            <div class="editor-field">
                @*@Html.EditorFor(model => model.ActivitySLA)*@
                @Html.TextBoxFor(model => model.ActivitySLA, new { id = "ActivityDesc", @readonly = "readonly", Class = "textBoxFor" })

            </div>
        </div>

        <div class="form-group">
            <div class="editor-label">
                @Html.LabelFor(model => model.ActivityID)
            </div>
            <div class="editor-field">
                @(Html.Kendo().ComboBoxFor(model => model.ActivityID)
    .Name("Activity")
    .Filter("contains")
    .HtmlAttributes(new { style = "width:300px", @readonly = "readonly" })
    .Placeholder("Select...")
    .DataTextField("Description")
    .DataValueField("ActivityID")

    .DataSource(dataSource => dataSource
        .Read(read => read.Action("GetActivity", "WorkLog").Data("additionalActivityInfo").Type(HttpVerbs.Post)
        )//.ServerFiltering(true)
    )//.CascadeFrom("ServiceID").Filter("contains")

                )
                @Html.ValidationMessageFor(model => model.ServiceID, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            <div class="editor-label">
                @Html.LabelFor(model => model.WorkLogType)
            </div>
            <div class="editor-field">
                @(Html.Kendo().ComboBoxFor(model => model.WorkLogType)
    .Name("WorkLogTypeCode")
    .Filter("contains")
    .HtmlAttributes(new { style = "width:300px" })
    .Placeholder("Select...")
    .DataTextField("WorkLogType")
    .DataValueField("WorkLogTypeCode")

    .DataSource(dataSource => dataSource
    .Read(read => read.Action("GetWorkLogType", "WorkLog").Data("additionalWLTInfo").Type(HttpVerbs.Post))
    )

                )
                @Html.ValidationMessageFor(model => model.WorkLogType, "Please select a worklog type", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            <div class="editor-label">
                @Html.LabelFor(model => model.WorkLogSubject)
            </div>
            <div class="editor-field">
                @Html.EditorFor(model => model.WorkLogSubject)
                @Html.ValidationMessageFor(model => model.WorkLogSubject, "", new { @class = "text-danger" })
            </div>
        </div>
        <div class="form-group">
            <div class="editor-label">
                @Html.LabelFor(model => model.WorkLogDetails)
            </div>
            <div class="editor-field">
                @Html.TextAreaFor(model => model.WorkLogDetails, new { htmlAttributes = new { @class = "form-control", cols = "50" } })
                @Html.ValidationMessageFor(model => model.WorkLogDetails, "", new { @class = "text-danger" })
            </div>
        </div>

            <div class="worklogStatusButtonAlign">
                <button id="btnWorkLogSave" type="submit" class="k-button k-button-icontext k-primary k-grid-update">Save</button>
                <button id="btnClose" type="button" class="k-button k-button-icontext k-grid-cancel">Cancel</button>

            </div>

            <div id="statusMessage"> </div>

        </div>
</div>
}

ViewModel

 public class ActivityWorkLogViewModel
    {
        [ScaffoldColumn(false)]
        [Display(Name = "WorkLogID", ResourceType = typeof(Resources.Resource))]
        public int WorkLogID { get; set; }
        [Required]
        [Display(Name = "WorkLogTypeCode", ResourceType = typeof(Resources.Resource))]
        public string WorkLogTypeCode { get; set; }
        [Display(Name = "WorkLogType", ResourceType = typeof(Resources.Resource))]

        [Required(ErrorMessage = "WorkLogType is required")]
        public string WorkLogType { get; set; }
        [Required]
        [Display(Name = "WorkLogAppliesToID", ResourceType = typeof(Resources.Resource))]
        public int WorkLogAppliesToID { get; set; }
        [Display(Name = "WorkLogAppliesToName", ResourceType = typeof(Resources.Resource))]
        public string WorkLogAppliesToName { get; set; }
        [Required]
        [Display(Name = "RequestID", ResourceType = typeof(Resources.Resource))]
        public int RequestID { get; set; }
        [Display(Name = "ServiceID", ResourceType = typeof(Resources.Resource))]
        public Nullable<int> ServiceID { get; set; }
        [Display(Name = "ActivityID", ResourceType = typeof(Resources.Resource))]
        public Nullable<int> ActivityID { get; set; }
        [Required(ErrorMessage = "Subject is required")]
        [Display(Name = "WorkLogSubject", ResourceType = typeof(Resources.Resource))]
        public string WorkLogSubject { get; set; }
        [Required(ErrorMessage = "Details is required")]
        [Display(Name = "WorkLogDetails", ResourceType = typeof(Resources.Resource))]
        public string WorkLogDetails { get; set; }
        [Display(Name = "EmailTo", ResourceType = typeof(Resources.Resource))]
        public string EmailTo { get; set; }
        [Display(Name = "IsActive", ResourceType = typeof(Resources.Resource))]
        public bool IsActive { get; set; }
        [Display(Name = "CountryCode", ResourceType = typeof(Resources.Resource))]
        public string CountryCode { get; set; }
        [Display(Name = "ActivitySLA", ResourceType = typeof(Resources.Resource))]
        public string ActivitySLA { get; set; }
    }

Controller

[HttpPost]
        public ActionResult ActivityWorkLog_Create(ActivityWorkLogViewModel workLogViewModel)
        {
            if (!ModelState.IsValid)
            {
                return View("EditorTemplates/_WorkLogEdit", Mapper.Map<ActivityWorkLogViewModel>(workLogViewModel));
            }
            WorkLogRepository workLogRepository = new WorkLogRepository();
            workLogRepository.CreateWorkLog(Mapper.Map<WorkLog>(workLogViewModel));
            return PartialView("EditorTemplates/_WorkLogEdit", Mapper.Map<ActivityWorkLogViewModel>(workLogViewModel));
        }

Bundle.config

 bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
                     "~/Scripts/jquery-{version}.js",
                     "~/Scripts/jquery-ui-1.12.1.min.js",
                     "~/Scripts/jquery.validate.min.js",
                     "~/Scripts/jquery.validate.unobtrusive.min.js"
                     ));
Tom
  • 8,175
  • 41
  • 136
  • 267

1 Answers1

0

Add these lines in your view:

<script>
    $(document).ready(function() {
        var form = $('form') // Give Id prop to your from
            .removeData("validator")
            .removeData("unobtrusiveValidation");

        $.validator.unobtrusive.parse(form);
    });
<script>

Also make sure you add jquery.validate.js and jquery.validate.unobtrusive.js into your View cshtml for validation to work properly.

Lews Therin
  • 3,707
  • 2
  • 27
  • 53
User3250
  • 2,961
  • 5
  • 29
  • 61
  • Hi tried the following @using (Ajax.BeginForm("ActivityWorkLog_Create", "Activity", new AjaxOptions { HttpMethod = "POST", OnSuccess = "OnSuccess", OnFailure = "OnFailure" },new { id = "ActivityWorkLogForm" })) { – Tom May 19 '17 at 10:16
  • function OnSuccess(response) { $("#statusMessage").text("Status updated"); alert("Success"); var form = $("#ActivityWorkLogForm") .removeData("validator") .removeData("unobtrusiveValidation"); $.validator.unobtrusive.parse(form); } – Tom May 19 '17 at 10:16
  • I cant see my alert in the success getting called. Are you sure the success gets called when the model.state returns false – Tom May 19 '17 at 10:17
  • No, I mean how you load your VIEW not your submit function in the view. You use controller action to return View? – User3250 May 19 '17 at 10:37
  • Yes I use the controller action to return to the view – Tom May 19 '17 at 10:39
  • Updated my answer. Please read [this](http://stackoverflow.com/a/11535101/4868839) for how jQuery Unobtrusive Validation works. – User3250 May 19 '17 at 10:49
  • I have updated the post with the bundle.config. I can see the jss files have been loaded on form load but I am getting the error Microsoft JScript runtime error: Unable to get value of the property 'unobtrusive': object is null or undefined – Tom May 19 '17 at 11:31
  • I remove those two and added this "~/Scripts/jquery.unobtrusive-ajax.min.js" and error is gone – Tom May 19 '17 at 11:34
  • So currently the failure measure triggers when required fields are not added – Tom May 19 '17 at 11:35
  • Ok, so your validation messages are showing up right? – User3250 May 19 '17 at 11:38
  • Sorry my bad. I checked the developer tools . I am still getting the error message – Tom May 19 '17 at 11:41
  • All i can see is my failure message firing. function OnWorklogStatusFailure(response) { alert("Failure"); } – Tom May 19 '17 at 11:42
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/144650/discussion-between-user3250-and-tom). – User3250 May 19 '17 at 11:42