jTable.org

A JQuery plugin to create AJAX based CRUD tables.

Donate to jTable
Demos | Documentation | Discussion | Themes | Downloads | About
jTable on GitHub Github


HTML code

<div id="StudentTableContainer"></div>

Javascript code

<script type="text/javascript">

    $(document).ready(function () {

        $('#StudentTableContainer').jtable({
            title: 'Student List',
            paging: true, //Enable paging
            sorting: true, //Enable sorting
            defaultSorting: 'Name ASC',
            //openChildAsAccordion: true, //Enable this line to show child tabes as accordion style
            actions: {
                listAction: '/Demo/StudentList',
                deleteAction: '/Demo/DeleteStudent',
                updateAction: '/Demo/UpdateStudent',
                createAction: '/Demo/CreateStudent")'
            },
            fields: {
                StudentId: {
                    key: true,
                    create: false,
                    edit: false,
                    list: false
                },
                //CHILD TABLE DEFINITION FOR "PHONE NUMBERS"
                Phones: {
                    title: '',
                    width: '5%',
                    sorting: false,
                    edit: false,
                    create: false,
                    display: function (studentData) {
                        //Create an image that will be used to open child table
                        var $img = $('<img src="/Content/images/Misc/phone.png" title="Edit phone numbers" />');
                        //Open child table when user clicks the image
                        $img.click(function () {
                            $('#StudentTableContainer').jtable('openChildTable',
                                    $img.closest('tr'),
                                    {
                                        title: studentData.record.Name + ' - Phone numbers',
                                        actions: {
                                            listAction: '/Demo/PhoneList?StudentId=' + studentData.record.StudentId,
                                            deleteAction: '/Demo/DeletePhone',
                                            updateAction: '/Demo/UpdatePhone',
                                            createAction: '/Demo/CreatePhone'
                                        },
                                        fields: {
                                            StudentId: {
                                                type: 'hidden',
                                                defaultValue: studentData.record.StudentId
                                            },
                                            PhoneId: {
                                                key: true,
                                                create: false,
                                                edit: false,
                                                list: false
                                            },
                                            PhoneType: {
                                                title: 'Phone type',
                                                width: '30%',
                                                options: { '1': 'Home phone', '2': 'Office phone', '3': 'Cell phone' }
                                            },
                                            Number: {
                                                title: 'Phone Number',
                                                width: '30%'
                                            },
                                            RecordDate: {
                                                title: 'Record date',
                                                width: '20%',
                                                type: 'date',
                                                displayFormat: 'yy-mm-dd',
                                                create: false,
                                                edit: false
                                            }
                                        }
                                    }, function (data) { //opened handler
                                        data.childTable.jtable('load');
                                    });
                        });
                        //Return image to show on the person row
                        return $img;
                    }
                },
                //CHILD TABLE DEFINITION FOR "EXAMS"
                Exams: {
                    title: '',
                    width: '5%',
                    sorting: false,
                    edit: false,
                    create: false,
                    display: function (studentData) {
                        //Create an image that will be used to open child table
                        var $img = $('<img src="/Content/images/Misc/note.png" title="Edit exam results" />');
                        //Open child table when user clicks the image
                        $img.click(function () {
                            $('#StudentTableContainer').jtable('openChildTable',
                                    $img.closest('tr'), //Parent row
                                    {
                                    title: studentData.record.Name + ' - Exam Results',
                                    actions: {
                                        listAction: '/Demo/ExamList?StudentId=' + studentData.record.StudentId,
                                        deleteAction: '/Demo/DeleteExam',
                                        updateAction: '/Demo/UpdateExam',
                                        createAction: '/Demo/CreateExam'
                                    },
                                    fields: {
                                        StudentId: {
                                            type: 'hidden',
                                            defaultValue: studentData.record.StudentId
                                        },
                                        StudentExamId: {
                                            key: true,
                                            create: false,
                                            edit: false,
                                            list: false
                                        },
                                        CourseName: {
                                            title: 'Course name',
                                            width: '40%'
                                        },
                                        ExamDate: {
                                            title: 'Exam date',
                                            width: '30%',
                                            type: 'date',
                                            displayFormat: 'yy-mm-dd'
                                        },
                                        Degree: {
                                            title: 'Degree',
                                            width: '10%',
                                            options: ["AA", "BA", "BB", "CB", "CC", "DC", "DD", "FF"]
                                        }
                                    }
                                }, function (data) { //opened handler
                                    data.childTable.jtable('load');
                                });
                        });
                        //Return image to show on the person row
                        return $img;
                    }
                },
                Name: {
                    title: 'Name',
                    width: '20%'
                },
                EmailAddress: {
                    title: 'Email address',
                    list: false
                },
                Password: {
                    title: 'User Password',
                    type: 'password',
                    list: false
                },
                Gender: {
                    title: 'Gender',
                    width: '11%',
                    options: { 'M': 'Male', 'F': 'Female' }
                },
                CityId: {
                    title: 'City',
                    width: '12%',
                    options: '/Demo/GetCityOptions'
                },
                BirthDate: {
                    title: 'Birth date',
                    width: '15%',
                    type: 'date',
                    displayFormat: 'yy-mm-dd'
                },
                Education: {
                    title: 'Education',
                    list: false,
                    type: 'radiobutton',
                    options: { '1': 'Primary school', '2': 'High school', '3': 'University' }
                },
                About: {
                    title: 'About this person',
                    type: 'textarea',
                    list: false
                },
                IsActive: {
                    title: 'Status',
                    width: '12%',
                    type: 'checkbox',
                    values: { 'false': 'Passive', 'true': 'Active' },
                    defaultValue: 'true'
                },
                RecordDate: {
                    title: 'Record date',
                    width: '15%',
                    type: 'date',
                    displayFormat: 'yy-mm-dd',
                    create: false,
                    edit: false,
                    sorting: false //This column is not sortable!
                }
            }
        });

        //Load student list from server
        $('#StudentTableContainer').jtable('load');

    });

</script>

Server side code

public class DemoController : Controller
{
    //...
    
    #region Student actions

    [HttpPost]
    public JsonResult StudentList(int jtStartIndex = 0, int jtPageSize = 0, string jtSorting = null)
    {
        try
        {
            //Get data from database
            var studentCount = _repository.StudentRepository.GetStudentCount();
            var students = _repository.StudentRepository.GetStudents(jtStartIndex, jtPageSize, jtSorting);

            //Return results to jTable
            return Json(new { Result = "OK", Records = students, TotalRecordCount = studentCount });
        }
        catch (Exception ex)
        {
            return Json(new { Result = "ERROR", Message = ex.Message });
        }
    }

    [HttpPost]
    public JsonResult CreateStudent(Student student)
    {
        try
        {
            if (!ModelState.IsValid)
            {
                return Json(new { Result = "ERROR", Message = "Form is not valid! Please correct it and try again." });
            }

            var addedStudent = _repository.StudentRepository.AddStudent(student);
            return Json(new { Result = "OK", Record = addedStudent });
        }
        catch (Exception ex)
        {
            return Json(new { Result = "ERROR", Message = ex.Message });
        }
    }

    [HttpPost]
    public JsonResult UpdateStudent(Student student)
    {
        try
        {
            if (!ModelState.IsValid)
            {
                return Json(new { Result = "ERROR", Message = "Form is not valid! Please correct it and try again." });
            }

            _repository.StudentRepository.UpdateStudent(student);
            return Json(new { Result = "OK" });
        }
        catch (Exception ex)
        {
            return Json(new { Result = "ERROR", Message = ex.Message });
        }
    }

    [HttpPost]
    public JsonResult DeleteStudent(int studentId)
    {
        try
        {
            Thread.Sleep(50);
            _repository.StudentRepository.DeleteStudent(studentId);
            return Json(new { Result = "OK" });
        }
        catch (Exception ex)
        {
            return Json(new { Result = "ERROR", Message = ex.Message });
        }
    }

    #endregion

    #region City actions

    [HttpPost]
    public JsonResult GetCityOptions()
    {
        try
        {
            var cities = _repository.CityRepository.GetAllCities().Select(c => new { DisplayText = c.CityName, Value = c.CityId });
            return Json(new { Result = "OK", Options = cities });
        }
        catch (Exception ex)
        {
            return Json(new { Result = "ERROR", Message = ex.Message });
        }
    }

    #endregion

    #region Phone actions

    [HttpPost]
    public JsonResult PhoneList(int studentId)
    {
        try
        {
            Thread.Sleep(200);
            var phones = _repository.PhoneRepository.GetPhonesOfStudent(studentId);
            return Json(new { Result = "OK", Records = phones });
        }
        catch (Exception ex)
        {
            return Json(new { Result = "ERROR", Message = ex.Message });
        }
    }

    [HttpPost]
    public JsonResult DeletePhone(int phoneId)
    {
        try
        {
            Thread.Sleep(50);
            _repository.PhoneRepository.DeletePhone(phoneId);
            return Json(new { Result = "OK" });
        }
        catch (Exception ex)
        {
            return Json(new { Result = "ERROR", Message = ex.Message });
        }
    }

    [HttpPost]
    public JsonResult UpdatePhone(Phone phone)
    {
        try
        {
            if (!ModelState.IsValid)
            {
                return Json(new { Result = "ERROR", Message = "Form is not valid! Please correct it and try again." });
            }

            _repository.PhoneRepository.UpdatePhone(phone);
            return Json(new { Result = "OK" });
        }
        catch (Exception ex)
        {
            return Json(new { Result = "ERROR", Message = ex.Message });
        }
    }

    [HttpPost]
    public JsonResult CreatePhone(Phone phone)
    {
        try
        {
            if (!ModelState.IsValid)
            {
                return Json(new { Result = "ERROR", Message = "Form is not valid! Please correct it and try again." });
            }

            var addedPhone = _repository.PhoneRepository.AddPhone(phone);
            return Json(new { Result = "OK", Record = addedPhone });
        }
        catch (Exception ex)
        {
            return Json(new { Result = "ERROR", Message = ex.Message });
        }
    }

    #endregion

    #region Exam actions

    [HttpPost]
    public JsonResult ExamList(int studentId)
    {
        try
        {
            Thread.Sleep(200);
            var exams = _repository.ExamRepository.GetExamsOfStudent(studentId).OrderBy(e => e.ExamDate).ToList();
            return Json(new { Result = "OK", Records = exams });
        }
        catch (Exception ex)
        {
            return Json(new { Result = "ERROR", Message = ex.Message });
        }
    }

    [HttpPost]
    public JsonResult DeleteExam(int studentExamId)
    {
        try
        {
            Thread.Sleep(50);
            _repository.ExamRepository.DeleteExam(studentExamId);
            return Json(new { Result = "OK" });
        }
        catch (Exception ex)
        {
            return Json(new { Result = "ERROR", Message = ex.Message });
        }
    }

    [HttpPost]
    public JsonResult UpdateExam(StudentExam exam)
    {
        try
        {
            if (!ModelState.IsValid)
            {
                return Json(new { Result = "ERROR", Message = "Form is not valid! Please correct it and try again." });
            }

            _repository.ExamRepository.UpdateExam(exam);
            return Json(new { Result = "OK" });
        }
        catch (Exception ex)
        {
            return Json(new { Result = "ERROR", Message = ex.Message });
        }
    }

    [HttpPost]
    public JsonResult CreateExam(StudentExam exam)
    {
        try
        {
            if (!ModelState.IsValid)
            {
                return Json(new { Result = "ERROR", Message = "Form is not valid! Please correct it and try again." });
            }

            var addedExam = _repository.ExamRepository.AddExam(exam);
            return Json(new { Result = "OK", Record = addedExam });
        }
        catch (Exception ex)
        {
            return Json(new { Result = "ERROR", Message = ex.Message });
        }
    }

    #endregion
}

See "Using jTable with ASP.NET MVC" tutorial for detailed usage.
Download all samples from download page.

public partial class PagingAndSorting : System.Web.UI.Page
{
    //...

    #region Student methods

    [WebMethod(EnableSession = true)]
    public static object StudentList(int jtStartIndex, int jtPageSize, string jtSorting)
    {
        try
        {
            //Get data from database
            int studentCount = _repository.StudentRepository.GetStudentCount();
            List<Student> students = _repository.StudentRepository.GetStudents(jtStartIndex, jtPageSize, jtSorting);

            //Return result to jTable
            return new { Result = "OK", Records = students, TotalRecordCount = studentCount };
        }
        catch (Exception ex)
        {
            return new { Result = "ERROR", Message = ex.Message };
        }
    }

    [WebMethod(EnableSession = true)]
    public static object CreateStudent(Student record)
    {
        try
        {
            var addedStudent = _repository.StudentRepository.AddStudent(record);
            return new { Result = "OK", Record = addedStudent };
        }
        catch (Exception ex)
        {
            return new { Result = "ERROR", Message = ex.Message };
        }
    }

    [WebMethod(EnableSession = true)]
    public static object UpdateStudent(Student record)
    {
        try
        {
            _repository.StudentRepository.UpdateStudent(record);
            return new { Result = "OK" };
        }
        catch (Exception ex)
        {
            return new { Result = "ERROR", Message = ex.Message };
        }
    }

    [WebMethod(EnableSession = true)]
    public static object DeleteStudent(int StudentId)
    {
        try
        {
            _repository.StudentRepository.DeleteStudent(StudentId);
            return new { Result = "OK" };
        }
        catch (Exception ex)
        {
            return new { Result = "ERROR", Message = ex.Message };
        }
    }

	#endregion

    #region City methods

    [WebMethod(EnableSession = true)]
    public static object GetCityOptions()
    {
        try
        {
            var cities = _repository.CityRepository.GetAllCities().Select(c => new { DisplayText = c.CityName, Value = c.CityId });
            return new { Result = "OK", Options = cities };
        }
        catch (Exception ex)
        {
            return new { Result = "ERROR", Message = ex.Message };
        }
    }
	
	#endregion
	
    #region Phone methods

    [WebMethod(EnableSession = true)]
    public static object PhoneList(int StudentId)
    {
        try
        {
            var phones = _repository.PhoneRepository.GetPhonesOfStudent(StudentId);
            return new { Result = "OK", Records = phones };
        }
        catch (Exception ex)
        {
            return new { Result = "ERROR", Message = ex.Message };
        }
    }

    [WebMethod(EnableSession = true)]
    public static object DeletePhone(int PhoneId)
    {
        try
        {
            _repository.PhoneRepository.DeletePhone(PhoneId);
            return new { Result = "OK" };
        }
        catch (Exception ex)
        {
            return new { Result = "ERROR", Message = ex.Message };
        }
    }

    [WebMethod(EnableSession = true)]
    public static object UpdatePhone(Phone record)
    {
        try
        {
            _repository.PhoneRepository.UpdatePhone(record);
            return new { Result = "OK" };
        }
        catch (Exception ex)
        {
            return new { Result = "ERROR", Message = ex.Message };
        }
    }

    [WebMethod(EnableSession = true)]
    public static object CreatePhone(Phone record)
    {
        try
        {
            var addedPhone = _repository.PhoneRepository.AddPhone(record);
            return new { Result = "OK", Record = addedPhone };
        }
        catch (Exception ex)
        {
            return new { Result = "ERROR", Message = ex.Message };
        }
    }

    #endregion

    #region Exam actions

    [WebMethod(EnableSession = true)]
    public static object ExamList(int StudentId)
    {
        try
        {
            var exams = _repository.ExamRepository.GetExamsOfStudent(StudentId).OrderBy(e => e.ExamDate).ToList();
            return new { Result = "OK", Records = exams };
        }
        catch (Exception ex)
        {
            return new { Result = "ERROR", Message = ex.Message };
        }
    }

    [WebMethod(EnableSession = true)]
    public static object DeleteExam(int StudentExamId)
    {
        try
        {
            _repository.ExamRepository.DeleteExam(StudentExamId);
            return new { Result = "OK" };
        }
        catch (Exception ex)
        {
            return new { Result = "ERROR", Message = ex.Message };
        }
    }

    [WebMethod(EnableSession = true)]
    public static object UpdateExam(StudentExam record)
    {
        try
        {
            _repository.ExamRepository.UpdateExam(record);
            return new { Result = "OK" };
        }
        catch (Exception ex)
        {
            return new { Result = "ERROR", Message = ex.Message };
        }
    }

    [WebMethod(EnableSession = true)]
    public static object CreateExam(StudentExam record)
    {
        try
        {
            var addedExam = _repository.ExamRepository.AddExam(record);
            return new { Result = "OK", Record = addedExam };
        }
        catch (Exception ex)
        {
            return new { Result = "ERROR", Message = ex.Message };
        }
    }

    #endregion
}

See "Using jTable with ASP.NET Web Forms" tutorial for detailed usage.
Download all samples from download page.