2

I am using jquery dialog to show the details of my view for adding and editing issue

I was able to show the form and on the update button the first level of validation is working fine which is [Required] and [RegularExpression(...)], but its not working on the model validation level (IValidatableObject), the model is returning the errors but the form is not showing them.

here is the jQuery i am using

the controller

 [HttpPost]
        public ActionResult _Degree(TDegree degree)
        {
            if (ModelState.IsValid)
            {
                if (degree.Degree == 0)
                {
                    db.TDegrees.Add(degree);
                    db.SaveChanges();
                }
                else
                {
                    TryUpdateModel<TDegree>(degree);
                }
                return RedirectToAction("Index", "Profile");
            }
            // what should i return here to stay on the dialog form + returning the errors? i tried this way to show the errors but the errors not shown as html but string
            return Content(ShowAllErrors());
        }
        private String ShowAllErrors()
        {
            StringBuilder sb = new StringBuilder();
            TagBuilder ul = new TagBuilder("ul");
            foreach (var e in ModelState.Values.Where(t => t.Errors.Count > 0))
            {
                foreach (var d in e.Errors)
                {
                    TagBuilder li = new TagBuilder("li");
                    li.MergeAttribute("class", "field-validation-error");
                    li.SetInnerText(d.ErrorMessage);
                    sb.Append(li.ToString());
                }
            }
            ul.SetInnerText(sb.ToString());
            return ul.ToString();
        }

the model

 public partial class TDegree : IValidatableObject
    {
        // Primitive properties

        public long Degree { get; set; }
        public int Country { get; set; }
        public long Applicant { get; set; }
        [DisplayName("Degree Type")]
        public short DegreeType { get; set; }
        [Required]
        public string Major { get; set; }
        [Required]
        public string Institution { get; set; }
        [DisplayName("Completion Year")]
        public short CompletionYear { get; set; }
        [RegularExpression(@"^\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$", ErrorMessage = "Email is not valid")]
        public string Email { get; set; }
        [DataType(DataType.PhoneNumber)]
        public string Phone { get; set; }
        public bool IsEducation { get; set; }

        // Navigation properties

        public virtual TApplicant TApplicant { get; set; }
        public virtual TCountry TCountry { get; set; }
        public virtual TDegreeType TDegreeType { get; set; }

        // this method is running after the attributes validations and its returning the errors correctly but they are not shown on the form!!
        public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
        {
            if (DegreeType == 0)
                yield return new ValidationResult("Degree Type is required", new string[] { "DegreeType" });
            if (CompletionYear < 1950 || CompletionYear > DateTime.Today.Year)
                yield return new ValidationResult("Completion Year is out of range!", new string[] { "CompletionYear" });

        }
    }

the Index view

@Html.ImageLink("_Degree", "Profile", new { id = 0 }, @Url.Content("~/Content/images/add.png"), "Add", new { @class = "addLink" }, null)
<table>
    <tr>
        <th>
            Country
        </th>
        <th>
            Type
        </th>
        <th>
            Major
        </th>
        <th>
            Institution
        </th>
        <th>
            Year
        </th>
        <th>
            Email
        </th>
        <th>
            Phone
        </th>
        <th>
        </th>
    </tr>
    @foreach (var item in Model)
    {
        <tr class="row">
            <td>
                @Html.DisplayFor(modelItem => item.TCountry.Name)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.TDegreeType.Name)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Major)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Institution)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.CompletionYear)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Email)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Phone)
            </td>
            <td>
                @Html.ImageLink("_Degree", "Profile", new { id = item.Degree }, @Url.Content("~/Content/images/select.png"), "Edit", new { @class = "editLink" }, null)
            </td>
        </tr>
    }
</table>
<div id="updateDialog" title="Degree Details">
</div>
<script type="text/javascript">
    var linkObj;
    $(function () {
        $('#updateDialog').dialog({
            autoOpen: false,
            width: 590,
            resizable: false,
            modal: true,
            buttons: {
                "Update": function () {
                    $("#update-message").html('');
                    $("#updateDegreeForm").validate();
                    $("#updateDegreeForm").submit();
                },
                "Cancel": function () {
                    $(this).dialog("close");
                }
            }
        });

        $(".editLink,.addLink").click(function () {
            linkObj = $(this);

            var dialogDiv = $('#updateDialog');
            var viewUrl = linkObj.attr('href');
            $.get(viewUrl, function (data) {
                dialogDiv.html(data);
                var $form = $("#updateDegreeForm");
                $form.unbind();
                $form.data("validator", null);
                $.validator.unobtrusive.parse(document);
                $form.validate($form.data("unobtrusiveValidation").options);
                dialogDiv.dialog('open');
            });
            return false;
        });

    });


    function updateSuccess() {
        if ($("#update-message").html() == "False") {
            $("#update-message").css('display', 'block');
            // here it working fine if the model attributes fired the errors
        }
        else {
             // if the model attributes validations was correct and the model validation returned errors, this block will be executed
             // i need here to show the errors of the model, and if there was no errors i will close the dialog
        }
    }

</script>

the details view ( partial view )

<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
@using (Ajax.BeginForm("_Degree", "Profile", null,
    new AjaxOptions
    {
        UpdateTargetId = "update-message",
        InsertionMode = InsertionMode.Replace,
        HttpMethod = "POST",
        OnSuccess = "updateSuccess"
    },
new { @id = "updateDegreeForm" }))
{
    @Html.ValidationSummary()
    <div id="update-message" class="display:none;">
    </div>
    <table>
        <tr>
            <td class="editor-label">
                @Html.LabelFor(model => model.Major)
            </td>
            <td class="editor-field">
                @Html.EditorFor(model => model.Major)
            </td>
            <td class="editor-label">
                @Html.LabelFor(model => model.Institution)
            </td>
            <td class="editor-field">
                @Html.EditorFor(model => model.Institution)
            </td>
        </tr>
        <tr>
            <td class="editor-label">
                @Html.LabelFor(model => model.Country)
            </td>
            <td class="editor-field">
                @Html.DropDownList("Country")
            </td>
            <td class="editor-label">
                @Html.LabelFor(model => model.DegreeType)
            </td>
            <td class="editor-field">
                @Html.DropDownList("DegreeType")
            </td>
        </tr>
        <tr>
            <td class="editor-label">
                @Html.LabelFor(model => model.CompletionYear)
            </td>
            <td class="editor-field">
                @Html.EditorFor(model => model.CompletionYear)
            </td>
            <td class="editor-label">
                @Html.LabelFor(model => model.Email)
            </td>
            <td class="editor-field">
                @Html.EditorFor(model => model.Email)
            </td>
        </tr>
        <tr>
            <td class="editor-label">
                @Html.LabelFor(model => model.Phone)
            </td>
            <td class="editor-field">
                @Html.EditorFor(model => model.Phone)
            </td>
        </tr>
    </table>  
}

how can i let the all levels of validation to be shown in the dialog form? thanks in advance

1
  • I'm also in the save situation :( Commented Nov 17, 2012 at 11:37

1 Answer 1

1

Well after wasting almost 2 days I stumbled upon a solution to the problem. The skeleton of what I am using for partial/jquery dialog is same as you are using (which I took from a blog post). I modified my Create method as follows:

[HttpPost]
public JsonResult Create(EventObject evt)
{
    if(ModelState.IsValid)
    {
        //save the model and return success
        return new JsonResult{
                                 Data = new
                                        {
                                            Result="S",
                                            Message="successfully created event"
                                        }
                            };
    }
    else
    {
        return new JsonResult{
                                Data = new
                                        {
                                            Result="E",
                                            Message=CONVERT MODELSTATE TO STRING
                                        }
                            };
    }
}

Now on markup side I have following div:

<div id="create-event-error"></div>

my update function is as follows:

function updateSuccess(a) {
    if (a.Result=="S") {
        $("#update-message").html(a.Message).show().delay(3000).hide();
        $dlg.dialog('close');
    }
    else {
         var d=$("div#create-event-errors");
         d.html(a.Message).dialog({
           //VARIOUS DIALOG OPTIONS
         });
    }
}

In place of dialog you can show the errors anyway you like.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.