@manhnguyenv

Welcome to my blog!

AJAX error handling with jQuery

January 11, 2018 16:41

Visual Studio 2017 start debugging very slow

After some additional investigation I found this thread Unchecking Enable Diagnostic Tools while debugging in Tools → Options → Debugging → General did the trick!

Web Application > right click to go to the Properties > Configuration Properties > Debugging

Remove all items in the folder: C:\Users\manhnguyenv\AppData\Local\Microsoft\WebsiteCache

You will learn:

1) Model

using System.ComponentModel;
using System.ComponentModel.DataAnnotations;

namespace CURDCodeFirst.Models
{
    public class StudentViewModel
    {
        public long Id { get; set; }

        [Required(ErrorMessage = "First Name is required")]
        [DisplayName("First Name")]
        [StringLength(255)]
        public string FirstName { get; set; }

        [Required(ErrorMessage = "Last Name is required")]
        [DisplayName("Last Name")]
        [StringLength(255)]
        public string LastName { get; set; }

        public string Name { get; set; }

        [DataType(DataType.EmailAddress)]
        [EmailAddress]
        [Required(ErrorMessage = "Email is required")]
        public string Email { get; set; }

        [DisplayName("Enrollment No")]
        [Required(ErrorMessage = "Enrollment No is required")]
        public string EnrollmentNo { get; set; }

        [DisplayName("Phone Number")]
        [DataType(DataType.PhoneNumber)]
        [Phone]
        public string PhoneNumber { get; set; }

        [DisplayName("Age")]
        [Range(18, 99, ErrorMessage = "Age should be between 18 and 99")]
        public int Age { get; set; }
    }
}

2) View

Index.html

@model IEnumerable<StudentViewModel>
@using CURDCodeFirst.Models
@using CURDCodeFirst.Code

<div class="panel panel-primary">
<div class="panel-heading panel-head">Students</div>
<div class="panel-body">
<div class="btn-group">
<a id="createEditStudentModal" data-toggle="modal" href="@Url.Action("AddEditStudent")" data-target="#modal-action-student" class="btn btn-primary">
<i class="glyphicon glyphicon-plus"></i> Add Student
</a>
</div>
<div class="top-buffer"></div>
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>Name</th>
<th>Enrollment No</th>
<th>Email</th>
<th>Phone Number</th>
<th>Age</th>
<th>Action</th>
</tr>
</thead>
<tbody>
@foreach (var item in Model)
{
<tr>
<td>@item.Name</td>
<td>@item.EnrollmentNo</td>
<td>@item.Email</td>
<td>@item.PhoneNumber</td>
<td>@item.Age</td>
<td>
<a id="editUserModal" data-toggle="modal" href="@Url.Action("AddEditStudent", new {id=@item.Id })" data-target="#modal-action-student" class="btn btn-info">
<i class="glyphicon glyphicon-pencil"></i>
</a>
<a id="deleteUserModal" data-toggle="modal" href="@Url.Action("DeleteStudent", new {id=@item.Id })" data-target="#modal-action-student" class="btn btn-danger">
<i class="glyphicon glyphicon-trash"></i>
</a>
</td>
</tr>
}
</tbody>
</table>
</div>
</div>

@Html.Partial("_Modal", new BootstrapModel { Id = "modal-action-student", AreaLabeledId = "modal-action-student-label", Size = ModalSize.Medium })

@section scripts{
@Scripts.Render("~/Scripts/student-index.js")
}

_AddEditStudent.cshtml

@using CURDCodeFirst.Models
@model StudentViewModel

@using (Html.BeginForm())
{
@Html.HiddenFor(model => model.Id)

@Html.Partial("_ModalHeader", new ModalHeader { Heading = $"{(Model.Id == 0 ? "Add" : "Edit")} Student" })
<div class="modal-body form-horizontal">

@Html.ValidationSummary(true)

<div class="form-group">
@Html.LabelFor(model => model.FirstName, new { @class = "col-lg-3 col-sm-3 control-label" })
<div class="col-lg-6">
@Html.TextBoxFor(model => model.FirstName, new { @class = "form-control " })
@Html.ValidationMessageFor(model => model.FirstName)
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.LastName, new { @class = "col-lg-3 col-sm-3 control-label" })
<div class="col-lg-6">
@Html.TextBoxFor(model => model.LastName, new { @class = "form-control " })
@Html.ValidationMessageFor(model => model.LastName)
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.EnrollmentNo, new { @class = "col-lg-3 col-sm-3 control-label" })
<div class="col-lg-6">
@Html.TextBoxFor(model => model.EnrollmentNo, new { @class = "form-control " })
@Html.ValidationMessageFor(model => model.EnrollmentNo)
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Email, new { @class = "col-lg-3 col-sm-3 control-label" })
<div class="col-lg-6">
@Html.TextBoxFor(model => model.Email, new { @class = "form-control " })
@Html.ValidationMessageFor(model => model.Email)
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.PhoneNumber, new { @class = "col-lg-3 col-sm-3 control-label" })
<div class="col-lg-6">
@Html.TextBoxFor(model => model.PhoneNumber, new { @class = "form-control " })
@Html.ValidationMessageFor(model => model.PhoneNumber)
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Age, new { @class = "col-lg-3 col-sm-3 control-label" })
<div class="col-lg-6">
@Html.TextBoxFor(model => model.Age, new { @class = "form-control " })
@Html.ValidationMessageFor(model => model.Age)
</div>
</div>
</div>

@Html.Partial("_ModalFooter", new ModalFooter())

<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>
<script src="@Url.Content("~/Scripts/common.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/student-addeditstudent.js")" type="text/javascript"></script>
}

JavaScript

common.js

(function ($) {
    $.fn.serializeFormJSON = function () {
        var o = {};
        var a = this.serializeArray();
        $.each(a, function () {
            if (o[this.name]) {
                if (!o[this.name].push) {
                    o[this.name] = [o[this.name]];
                }
                o[this.name].push(this.value || '');
            } else {
                o[this.name] = this.value || '';
            }
        });
        return o;
    };
})(jQuery);

Student-Index.js

(function ($) {
    function Student() {
        var $this = this;
        function initilizeModel() {
            console.log('Init the model and show in the bootstrap modal');
            $("#modal-action-student").on('loaded.bs.modal', function (e) {
                console.log('Show bootstrap modal');
            }).on('hidden.bs.modal', function (e) {
                console.log('Hide bootstrap modal');
                $(this).removeData('bs.modal');
            });
        }
        $this.init = function () {
            initilizeModel();
        }
    }
    $(function () {
        var self = new Student();
        self.init();
    });
}(jQuery))

Student-AddEditStudent.js

$(document).ready(function () {
    var $form = $("form");
    $form.validate();
    $(document).on("submit", $form, function (e) {
        e.preventDefault();
        if ($form.validate().valid) {
            var data = $form.serializeFormJSON();
            $.ajax({
                url: "/Student/SaveStudent",
                type: "POST",
                dataType: "json",
                data: JSON.stringify(data),
                contentType: "application/json; charset=utf-8",
                /*
                 * A function to be called if the request fails. 
                 */
                error: function (jqXhr, textStatus, errorThrown) {
                    alert('An error occurred... Look at the console (F12 or Ctrl+Shift+I, Console tab) for more information!');
                    console.log('jqXHR:' + jqXhr);
                    console.log('jqXHR.responseText:' + jqXhr.responseText);
                    console.log('status:' + jqXhr.status);
                    console.log('status code:' + jqXhr.statusCode);
                    console.log('status text:' + jqXhr.statusText);
                    console.log('textStatus:' + textStatus);
                    console.log('errorThrown:' + errorThrown);
                },
                /*
                 * A function to be called if the request succeeds.
                 */
                success: function (data, textStatus, jqXhr) {
                    alert('Call AJAX successfully. Look at the console (F12 or Ctrl+Shift+I, Console tab) for more information! ');
                    console.log('jqXHR:' + jqXhr);
                    console.log('textStatus:' + textStatus);
                    console.log('data:' + data);
                }
            });
        }
    });
});

3) Controller

using CF.Data;
using CF.Repo;
using CURDCodeFirst.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Web.Mvc;
using System.Net.Http;

namespace CURDCodeFirst.Controllers
{
    public class StudentController : Controller
    {
        private readonly Repository _studentRepository;

        public StudentController()
        {
            var unitOfWork = new UnitOfWork();
            _studentRepository = unitOfWork.Repository();
        }

        [HttpGet]
        public ActionResult Index()
        {
            IEnumerable students = _studentRepository.Table.AsEnumerable().Select(s => new StudentViewModel
            {
                Id = s.Id,
                Name = $"{s.FirstName} {s.LastName}",
                Email = s.Email,
                EnrollmentNo = s.EnrollmentNumber,
                PhoneNumber = s.PhoneNumber,
                Age = s.Age
            });
            return View(students);
        }

        [HttpGet]
        public PartialViewResult AddEditStudent(long? id)
        {
            StudentViewModel model = new StudentViewModel();
            if (id.HasValue)
            {
                Student student = _studentRepository.GetById(id.Value);
                model.Id = student.Id;
                model.FirstName = student.FirstName;
                model.LastName = student.LastName;
                model.EnrollmentNo = student.EnrollmentNumber;
                model.Email = student.Email;
                model.PhoneNumber = student.PhoneNumber;
                model.Age = student.Age;
            }
            return PartialView("~/Views/Student/_AddEditStudent.cshtml", model);
        }

        [HttpPost]
        public JsonResult SaveStudent(StudentViewModel model)
        {
            try
            {
                if (ModelState.IsValid)
                {
                    long id = model.Id;
                    bool isNew = id == 0;
                    Student student = isNew ? new Student
                    {
                        AddedDate = DateTime.UtcNow
                    } : _studentRepository.GetById(id);
                    student.FirstName = model.FirstName;
                    student.LastName = model.LastName;
                    student.EnrollmentNumber = model.EnrollmentNo;
                    student.Email = model.Email;
                    student.PhoneNumber = model.PhoneNumber;
                    student.Age = model.Age;
                    student.IPAddress = Request.UserHostAddress;
                    student.ModifiedDate = DateTime.UtcNow;
                    string msg;
                    if (isNew)
                    {
                        _studentRepository.Insert(student);
                        msg = "Add success";
                    }
                    else
                    {
                        _studentRepository.Update(student);
                        msg = "Update success";
                    }
                    return Json(msg, JsonRequestBehavior.AllowGet);
                }
                return Json("ModelState is not valid", JsonRequestBehavior.AllowGet);
            }
            catch (Exception ex)
            {
                return Json(ex.Message, JsonRequestBehavior.AllowGet);
            }
        }
    }
}

Categories