1

I have a view Index and a Partial View SCItems. I use data annotations for validation. It works in Index, but not in my partial SCItem. I should use jquery validation? Thanks. SCModel code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;
using System.Web.WebPages.Html;

namespace PunchClockMobile.Models
{
    public class SCModel
    {
        public List<string> scList = new List<string>();

        [Required(ErrorMessage = "SC ID cannot be empty!")]
        public string scID { get; set; }

        [StringLength(4, ErrorMessage = " Please use 4 characters ")]
        [Range(0, 24, ErrorMessage = " Please use 0-24 range ")]
        [Required(ErrorMessage = "Please enter work duration")]
        public double? Duration { get; set; }

        [Required(ErrorMessage = "Please select a date")]
        public DateTime? Date { get; set; }

        [Required(ErrorMessage = "No task selected!")]
        private List<SelectListItem> _task = new List<SelectListItem>();

        [Required(ErrorMessage = "No task selected!")]
        public string SelectedTask { get; set; }

        [Required(ErrorMessage = "No task selected!")]
        public List<SelectListItem> Task
        {
            get { return _task; }
        }

    }
}

Index code:

@model PunchClockMobile.Models.SCModel
@{
    ViewBag.Title = "SC Number";
    Layout = "~/Views/Shared/_Layout.cshtml";
}
@section Header {
    <h3 style="text-align: left; padding-left: 1px;">
        SC Number</h3>
}
<div data-role="content" class="ui-content" role="main">
    @using (Html.BeginForm())
    {  <fieldset>
          <div data-role="fieldcontain">
        <label class="select">
            SC Number:</label>
        @Html.TextBoxFor(m => m.scID, new { @data_inline = true, @Class = "scIDFormat" })
        <br />
        <br />
        @Html.ValidationMessageFor(m => m.scID)
        <button type="submit" id="scOK" name="scOK">
            OK</button>
        </div>
        <div id="scList">
        </div>
      </fieldset>
       }
    </div>

<script language="javascript" type="text/javascript">

    $(document).ready(function () {
 $("#scOK").click(function () {

            if ($("form").valid()) {
                GetSCItems();
                $("#scList").show();
            }
            return false;
        });
 function GetSCItems() {
        var action = '@Url.Action("GetSCItems", "SCNumber")';
        var scID = $("#scID").val();
        var opt = {
            type: "GET",
            data: { ID: scID },
            url: action,
            success: SCListSuccess,
            error: SCListFailed
        };
        jQuery.ajax(opt);
    }

    function SCListSuccess(data) {
        if (data != undefined) {
            $('#scList').html(data).trigger('create');
            $("#noValues").hide();
        }
        else {
            //error
        }
    }

    function SCListFailed() {
        //error
    }
   });
</script>

SCItems code:

@model PunchClockMobile.Models.SCModel
@if (@Model.scList.Count != 0)
{

        <div data-role="fieldcontain">
            @Html.TextBoxFor(m => m.scID, new { @id = "scID", Class = "hidden" })
            <strong>@Html.Label("SC DESC:")</strong>
            @Html.TextBoxFor(m => m.scList[5], new { @id = "desc", @dbID = Model.scList[5], data_inline = "true", @readonly = "true", @class = "required" })
        </div>
        <div data-role="fieldcontain">
            <strong>@Html.Label("Product:")</strong>
            @Html.TextBoxFor(m => m.scList[6], new { @id = "prod", @dbID = @Model.scList[2], data_inline = "true", @readonly = "true", Class = "results" })
        </div>
        <div data-role="fieldcontain">
            <strong>@Html.Label("Account:")</strong>
            @Html.TextBoxFor(m => m.scList[7], new { @id = "acc", @dbID = @Model.scList[3], data_inline = "true", @readonly = "true", Class = "results" })
        </div>
        <div data-role="fieldcontain">
            <strong>@Html.Label("Project:")</strong>
            @Html.TextBoxFor(m => m.scList[8], new { @id = "proj", @dbID = @Model.scList[4], data_inline = "true", @readonly = "true", Class = "results" })
        </div>
        <div data-role="fieldcontain">
            @Html.Label("Task:  *")
            @Html.DropDownListFor(x => x.SelectedTask, new SelectList(Model.Task, "Value", "Text"), "Please Select a task", new { @Class = "required" })
            @Html.ValidationMessageFor(x => x.SelectedTask)
        </div>
        <div data-role="fieldcontain">
            <strong>@Html.Label("Date: *")</strong>
            @Html.TextBoxFor(m => m.Date, new { @data_role = "datebox", @autocomplete = "off", @Class = "required", @data_options = " {'mode':'calbox','overrideDateFormat': 'YYYY/mm/dd'" })
            @Html.ValidationMessageFor(m => m.Date)
        </div>
        <div data-role="fieldcontain">
            <strong>@Html.Label("Duration: *")</strong>
            @Html.TextBoxFor(m => m.Duration, new { @maxlength = "4", @Class = "required", @autocomplete = "off" })
            @Html.ValidationMessageFor(m => m.Duration)
        </div>
        <div id="ajaxPostMessage" class="ajaxMessage">
        </div>
        <div data-role="fieldcontain" align="center">
            <div class="search-button">
                <input type="submit" id="add" value="Add record" />
            </div>
        </div>

}

else
{
    <div class="ajaxMessage">
        @ViewBag.OpenID
    </div>
}
<script type="text/javascript">

    $(document).ready(function () {
        $("#Duration").bind('keypress', function (e) {
            return (e.which != 8 && e.which != 0 && (e.which < 48 || e.which > 57) && e.which != 46) ? false : true;
        });

        $("#ajaxPostMessage").hide();
        //GetTask method from SCNumber controller
        $.get('SCNumber/GetTask/' + $("#prod").attr('dbID'), function (response) {
            var task = $.parseJSON(response);
            var ddlSelectedTask = $("#SelectedTask");
            // clear all previous options 
            $("#SelectedTask > option").remove();
            // populate the task 
            for (i = 0; i < task.length; i++) {
                ddlSelectedTask.append($("<option />").val(task[i].Value).text(task[i].Text));
            }
        });

        $("#add").click(function () {
            $.validator.unobtrusive.parse($('form'));  //added
            if ($("form").valid()) {
                var IDs = new Array($("#prod").attr('dbID'), $("#acc").attr('dbID'), $("#proj").attr('dbID'), $("#SelectedTask").val(), $("#Date").val(), $("#Duration").val(), $("#desc").attr('dbID'), $("#scID").val());
                $.ajax({
                    url: '@Url.Action("HandleForm", "SCNumber")',
                    type: 'post',
                    data: { ids: IDs },
                    dataType: 'json',
                    traditional: true,
                    success: function (data) {
                        if (data.success == true) {
                            window.location.href = '@Url.Action("Index", "SCNumber")';
                        }
                        else {
                            $("#ajaxPostMessage").html(data.Error);
                            $("#ajaxPostMessage").show();
                        }
                    }
                });
            }
            return false;
        });
    });
</script>
rene
  • 41,474
  • 78
  • 114
  • 152
taia
  • 61
  • 3
  • 12

2 Answers2

1

Try looking into the following posting, you probably have the same issue:

MVC 3 Razor. Partial View validation is not working.

Hope this helps

Community
  • 1
  • 1
Display Name
  • 4,672
  • 1
  • 33
  • 43
0

In MVC3 return type of partial view is "MVCHTMLString",we can catch this string on server side and apply validation on it. In your controller

 protected string RenderPartialViewToString(string viewName, object model)
        {
            if (string.IsNullOrEmpty(viewName))
                viewName = ControllerContext.RouteData.GetRequiredString("action");

            ViewData.Model = model;

            using (StringWriter sw = new StringWriter())
            {
                ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(ControllerContext, viewName);
                ViewContext viewContext = new ViewContext(ControllerContext, viewResult.View, ViewData, TempData, sw);
                viewResult.View.Render(viewContext, sw);
                return sw.GetStringBuilder().ToString();
            }
        }

by passing the ViewName and Model to this method it will return you "MVCHTMLString" of view so can apply your validation in model. and use Ajax.BeginForm instead of Html.BeginForm for submitting partial view. so in your paratil view

      @using (Ajax.BeginForm("GetSCItems", "SCNumber", new AjaxOptions { OnSuccess = "AddSearch", UpdateTargetId = "scList" }))
     {
        <input type="submit" value="save"/>
     } 

In Controller

public ActionResult GetSCItems(SCModel model)
{
     // operation 
     return RenderPartialViewToString("SCItems",model)
}

in AjaxOption specified "UpdateTargetId" as scList where your result will append.

Shivkumar
  • 1,903
  • 5
  • 21
  • 32