Contents
Introduction to the problem
When we are developing a 'data manipulation page', we almost always do the same thing: A 'table/grid' that is used to 'show records'
of a table in a database, a 'create new record' page/dialog to add a new record to the database, an 'edit record' page/dialog to edit a record,
and finally a way of 'deleting a record' in the database.
Also, using AJAX, we can create more fast and interactive pages. Especially, jQuery and jQueryUI are invaluable
libraries to perform manipulation in an HTML page and perform AJAX requests to the server.
Users no longer need to leave the 'list of records' page to create/edit or delete a record. Also, the page never refreshes itself to reflect a change in records. When the user
deletes a record in the table, we can delete the corresponding row from the table without refreshing the whole page. When the user edits a record and saves it, we can change
the corresponding values in the table, and so on... Also, we can do some animations while deleting, creating, or updating records.
All of the subjects I mentioned above are known techniques and we have all implemented them. But the problem is that, we are developing/coding almost
the same page for every type of record. Surely, we can copy/paste/modify it! But is it a solution or another mess? All we know is, copy/paste
is not desirable for all kinds of programming, it is an evil!
What is jTable
jTable [1] is a jQuery plug-in that addresses the problem mentioned above. It takes a list and properties of fields of a record and does all the job! It has several features:
- Automatically creates an HTML table and loads records from the server using AJAX.
- Automatically creates a 'create new record' jQueryUI dialog form. When the user creates a record, it sends data to the server using AJAX and adds the same record to the table in the page.
- Automatically creates an 'edit record' jQueryUI dialog form. When the user edits a record, it updates the server using AJAX and updates all the cells on the table in the page.
- Allow the user to 'delete a record' by jQueryUI dialog based confirmation. When the user deletes a record, it deletes the record
from the server using AJAX and deletes the record from the table in the page.
- Supports server side AJAX based paging and sorting.
- Allows user to select rows from table.
- Allows user to resize/show/hide columns.
- Supports unlimited level of master/child tables.
- Shows animations for create/delete/edit operations on the table.
- Exposes some events to enable validation with forms.
- It can be localized easily.
- Table, forms and other elements are styled in well defined LESS CSS files.
- It comes with many pre-defined color themes.
- It is browser/platform independent and works on all common browsers.
- It is not dependent on any server-side technology such as ASP.NET MVC, and can be used with others.
- It has direct support for ASP.NET Web Forms Page Methods.
Live demo
You can try out a demonstration here: http://www.jtable.org.
A sample page with ASP.NET MVC 3 and jTable
Here I will show how to develop a data manipulation page with ASP.NET MVC 3 and jTable. This sample project is included in the download file.
Assume that we are manipulating a Person list that has a lot of information: name, city, email, password, gender, birth date, an 'about' text, and education.
Using the page
First, I will show the capabilities of jTable. Here is the list of people:
This table is automatically created by jTable. (Don't worry about the style of the table. The HTML code of the table is not styled and is a clean HTML table. You can edit the CSS files
easily.) Also, it shows only the desired fields. Edit/Delete images (buttons) are completely optional, and they are also automatically added to each row. Title is also optional
and the add new record link is changeable by the user with another element in the page. While the records are being loaded, a 'loading...' animation is shown.
When the user clicks the add new record link, a jQueryUI dialog based form is opened:
This form is also completely automatically created based on the fields of the record! When you fill the form and save,
jTable serializes the form and performs an AJAX call to the server. If the server responds 'OK', it adds the record to the table with an animation. If the server returns error while adding the record, jTable automatically shows an error dialog message and does
not add the record to the table.
If you click the edit image (button) in a row, jTable automatically creates an editing jQuery dialog form:
jTable automatically creates and fills the form with the selected record's values. When the user saves the form, just like creating
a new record, the record is saved to the server. If the AJAX call is a success, the record values are updated in the table and an 'edited' animation is shown.
When the user clicks the delete image (button), jTable shows a confirmation dialog (This is also customizable):
If the user clicks the delete button, the record is deleted from the server using an AJAX call.
If the operation succeeds, it is also removed from the table automatically with a deleting animation.
Now we will see how to implement the page above in ASP.NET MVC 3.
Model
We have two classes here: Person
(represents a record in the People database table) and City
(represents a record in the Cities database table). A person lives in a city.
So the Person
class has a CityId
that is the ID of a city row in the Cities table.
The Person
class is shown below:
public class Person
{
public int PersonId { get; set; }
[Required]
public int CityId { get; set; }
[Required]
public string Name { get; set; }
[Required]
public string EmailAddress { get; set; }
[Required]
public string Password { get; set; }
[Required]
public string Gender { get; set; }
[Required]
public DateTime BirthDate { get; set; }
public string About { get; set; }
[Required]
public int Education { get; set; }
[Required]
public bool IsActive { get; set; }
[Required]
public DateTime RecordDate { get; set; }
public Person()
{
RecordDate = DateTime.Now;
Password = "123";
About = "";
}
}
The [Required]
attributes are not related to jTable as you probably know. They are used by ASP.NET MVC and Entity framework for validation.
City
is a simple class. It is designed to show the combobox feature of jTable (as you've seen above).
public class City
{
public int CityId { get; set; }
[Required]
public string CityName { get; set; }
}
Controller
jTable uses the POST method as default while making AJAX calls to the server and expects a JSON object.
URLs (Controller/Action names in ASP.NET MVC) can be arbitrary and they are set while creating a jTable instance (we will see this soon).
Getting the list
You must supply an action to jTable to get a list of records:
[HttpPost]
public JsonResult PersonList()
{
try
{
List<Person> persons = _personRepository.GetAllPersons();
return Json(new { Result = "OK", Records = persons });
}
catch (Exception ex)
{
return Json(new { Result = "ERROR", Message = ex.Message });
}
}
All methods must return a JSON object. Result
property must be "OK" if operation is successful.
If an error occurs, Message
property will contain an error message to show to the user. If Result
is "OK", the Records
property will contain an array of records
to show in the table.
You could pass some parameters to the action that can be used to get records based on some filters. Also, you can paginate or sort the table. We will see this later.
Creating
Creating a record is optional (we will see soon). If you allow user to create a record, you must supply an action to jTable to create a new record:
[HttpPost]
public JsonResult CreatePerson(Person person)
{
try
{
if (!ModelState.IsValid)
{
return Json(new { Result = "ERROR",
Message = "Form is not valid! " +
"Please correct it and try again." });
}
var addedPerson = _personRepository.AddPerson(person);
return Json(new { Result = "OK", Record = addedPerson });
}
catch (Exception ex)
{
return Json(new { Result = "ERROR", Message = ex.Message });
}
}
CreatePerson
method must return the newly created object as the Record
property. This is needed since newly inserted record will has a key (PersonId in this sample) and automatically generated values (such as RecordDate here).
Updating
Editing a record is optional (we will see soon). If you allow user to edit a record, you must supply an action to jTable to update a record:
[HttpPost]
public JsonResult UpdatePerson(Person person)
{
try
{
if (!ModelState.IsValid)
{
return Json(new { Result = "ERROR",
Message = "Form is not valid! " +
"Please correct it and try again." });
}
_personRepository.UpdatePerson(person);
return Json(new { Result = "OK" });
}
catch (Exception ex)
{
return Json(new { Result = "ERROR", Message = ex.Message });
}
}
Deleting
Deleting a record is optional (we will see soon). If you allow user to delete a record, You must supply an action to jTable to delete a record:
[HttpPost]
public JsonResult DeletePerson(int personId)
{
try
{
_personRepository.DeletePerson(personId);
return Json(new { Result = "OK" });
}
catch (Exception ex)
{
return Json(new { Result = "ERROR", Message = ex.Message });
}
}
Getting options
jTable can automatically download and fill comboboxes from a URL. For instance, the City combobox in the Person create/edit form above uses this feature. In such cases, you must supply an action to get the option list:
[HttpPost]
public JsonResult GetCityOptions()
{
try
{
var cities = _personRepository.GetCities().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 });
}
}
The returning JSON object must have the Options
property. It is an array of objects and every object has two properties: DisplayText
and Value
.
View
Until here, there was nothing about jTable and javascript.
C# codes above was specific to the ASP.NET MVC implementation.
View side is completely about jTable.
You can obtain jTable either from nuget package or from it's web site.
When you download jTable, you will have a folder structure as shown below:
jquery.jtable.js file is the main and only JavaScript file which you must include in your page.
First, we add the metro style blue color theme file to the HEAD
section of the HTML document (Razor view in ASP.NET MVC3):
<link href="http://www.codeproject.com/Scripts/jtable/themes/metro/blue/jtable.css"
rel="stylesheet" type="text/css" />
You can use other ready themes or can write your own style files. Then we must add the jquery.jtable.js script file to the page:
<script type="text/javascript" src="http://www.codeproject.com/Scripts/jtable/jquery.jtable.js">
</script>
Note that jTable is dependent on jQuery and jQueryUI (included UI effects). So, you must add those scripts to your page before jTable. If you don't have these libraries, go to http://jqueryui.com/download to download jQueryUI (it includes jQuery).
Finally, we can create the jTable instance like this:
<div id="PersonTable" style="width: 580px; margin: auto;"></div>
<script type="text/javascript">
$(document).ready(function () {
$('#PersonTable').jtable({
title: 'The Person List',
actions: {
listAction: '/Home/PersonList',
deleteAction: '/Home/DeletePerson',
updateAction: '/Home/UpdatePerson',
createAction: '/Home/CreatePerson'
},
fields: {
PersonId: {
key: true,
create: false,
edit: false,
list: false
},
Name: {
title: 'Name',
width: '15%'
},
EmailAddress: {
title: 'Emal address',
list: false
},
Password: {
title: 'User Password',
type: 'password',
list: false
},
Gender: {
title: 'Gender',
width: '12%',
options: { 'M': 'Male', 'F': 'Female' }
},
CityId: {
title: 'Living city',
width: '15%',
options: '/Home/GetCityOptions'
},
BirthDate: {
title: 'Birth date',
width: '18%',
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: '10%',
type: 'checkbox',
values: { 'false': 'Passive', 'true': 'Active' },
defaultValue: 'true'
},
RecordDate: {
title: 'Record date',
width: '18%',
type: 'date',
displayFormat: 'dd.mm.yy',
create: false,
edit: false
}
}
});
$('#PersonTable').jtable('load');
});
</script>
Yes, it's a long definition but that's all! jTable does not need anything else to create tables, forms, and animations. All options are explained in API Reference documantation but I want to explain some basics now.
As you can see, jTable just needs a div
container as the only HTML tag. It gets options:
title
: Title of the table. actions
: URLs of actions that are used to create/delete/update/list records. fields
: All fields of the record. A field entry has properties
those define shape and behaviour the field.
Finally, the load
method of jTable is used to get records from the server. You can always call this method to load/refresh table data from the server.
Paging
jTable allows you server side paging with AJAX. See a demo here. It looks like the sample below:
To enable paging, paging
option must set to true
. You can also set pageSize
option (default value is 10).
$('#PersonTable').jtable({
paging: true,
actions: {
},
fields: {
}
});
If paging is enabled, jTable sends two query string parameters to the server on listAction AJAX call:
jtStartIndex
: Start index of records for current page. jtPageSize
: Count of maximum expected records.
Also, one additional information is expected from server:
TotalRecordCount
: Total count of records (not only this page).
An ASP.NET MVC action that is used for paging is shown below:
[HttpPost]
public JsonResult PersonList(int jtStartIndex, int jtPageSize)
{
try
{
int personCount = _personRepository.GetPersonCount();
List<Person> persons = _personRepository.GetPersons(jtStartIndex, jtPageSize);
return Json(new { Result = "OK", Records = persons, TotalRecordCount = personCount });
}
catch (Exception ex)
{
return Json(new { Result = "ERROR", Message = ex.Message });
}
}
Sorting
jTable allows you server side sorting with AJAX. See a demo here. It looks like the sample below:
To enable sorting, sorting
option must set to true
. You can also set defaultSorting
option. It can be a field name of a column of the table. For instance, if you want table sorted by Name by default, defaultSorting
can be 'Name ASC' or 'Name DESC'.
$('#PersonTable').jtable({
sorting: true,
defaultSorting: 'Name ASC',
actions: {
},
fields: {
}
});
If sorting is enabled, jTable sends a query string parameter to the server on listAction AJAX call:
jtSorting
: A string represents requested sorting. It is built from sorting field name plus sorting direction. For instance, It can be 'Name ASC', 'BirtDate DESC', 'Age ASC'... etc.
An ASP.NET MVC action that is used for sorting is shown below (paging is also enabled for the code below):
[HttpPost]
public JsonResult PersonList(int jtStartIndex = 0, int jtPageSize = 0, string jtSorting = null)
{
try
{
int personCount = _personRepository.GetPersonCount();
List<person> persons = _personRepository.GetPersons(jtStartIndex, jtPageSize, jtSorting);
return Json(new { Result = "OK", Records = persons, TotalRecordCount = personCount });
}
catch (Exception ex)
{
return Json(new { Result = "ERROR", Message = ex.Message });
}
}
Note that while sorting can be used with paging (as in this sample), it is completely independed from paging.
Selecting
jTable allows you client side selecting rows. See a demo here. It looks like the sample below:
To enable selecting, selecting
option must set to true
. You can set multiselect
option to true
to allow user to select multiple rows at once. You can set selectingCheckboxes
option to true
to show checkboxes as the sample above. Finally, you can set selectOnRowClick
to false
to prevent row selecting on clicking anywhere on the row (it's true as default).
To get list of selected rows, you can call selectedRows
method of jTable anytime (see sample usage). Also, you can get notified when selection changed by selectionChanged
event.
$('#PersonTable').jtable({
selecting: true,
multiselect: true,
selectingCheckboxes: true,
actions: {
},
fields: {
},
selectionChanged: function () {
var $selectedRows = $('#PersonTable').jtable('selectedRows');
$('#SelectedRowList').empty();
if ($selectedRows.length > 0) {
$selectedRows.each(function () {
var record = $(this).data('record');
$('#SelectedRowList').append(
'PersonId: ' + record.PersonId +
'Name:' + record.Name
);
});
} else {
$('#SelectedRowList').append('No row selected! Select rows to see here...');
}
}
});
In the sample above, we are registering to selectionChanged event. In the event handler, we are getting selected rows by selectedRows method. It returns a jQuery selection, so we can call any jQuery method on it. We can get the record by record data property. Then we can get fields of record as record.Name, record.PersonId... etc.
Master/Child tables
jTable supports unlimited level of child tables for a table. Child tables can also have their children and so on... A child table is releated in a row in master table. Look at the screen below:
Click here to see a live demo. When you click phone icon at left of a row, a new table slides down below the clicked row and you can manipulate phones of the selected person. You can do everything just as a regular jTable. When you click close button, child table slides up and closed.
To implement a child table, first we must understand custom (computed) column support of jTable. Green phone icon on the figure above is created in a custom column. To create a custom column, we use display option of jtable field definition as like below:
Phones: {
title: '',
width: '3%',
sorting: false,
edit: false,
create: false,
display: function (personData) {
var $img = $('<img src="http://www.codeproject.com/Content/images/Misc/phone.png" title="Edit phone numbers" />');
return $img;
}
}
Phones is a field definition as Name or Gender columns. But Person record has not a field named Phones. So, we define a function that will create value of this field to show on the table. display function is used for that. It is called by jTable for each row. It must return a text, HTML code or jQuery object. In the sample above, I created an image (green phone icon) as a jQuery object and returned it. Then jTable showed this image in the row. personData argument (you can change name of the argument of course) has record property that can be used to get record values for current row. So, if you want to use Name of the person, you can get it using personData.record.Name.
So far so good. But, how to open child table when user clicks this image. jTable defines two methods: openChildTable and closeChildTable to control child tables. So, web can open a child table when user clicks the phone icon (in the display method above):
$img.click(function() {
$('#PersonTable').jtable('openChildTable',
$img.closest('tr'),
{
title: personData.record.Name + ' - Phone numbers',
actions: {
listAction: '/PagingPerson/PhoneList?PersonId=' +
personData.record.PersonId,
deleteAction: '/PagingPerson/DeletePhone',
updateAction: '/PagingPerson/UpdatePhone',
createAction: '/PagingPerson/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: 'dd.mm.yy',
create: false,
edit: false
}
}
}, function(data) {
data.childTable.jtable('load');
});
});
openChildTable has three parameters. First one is used to indicate the row which is used as master row of child table. Here, I got container tr element of the image, so it gives the current row. Second parameter is a regular jTable initialization options. You can pass any option that can be passed to any jTable instance. So, you can define a custom column and open a second level child. Third and the last parameter is a callback method that is called by jTable after child table successfully created and opened. Here, I loaded records after child table is opened.
Look at the listAction. It's something like that: '/PagingPerson/PhoneList?PersonId=' + personData.record.PersonId. Thus, we are getting phone numbers those are related to current person (personData comes from display method, see codes above). Also, we need PersonId in the server side while creating a new phone number for a person. It's done with a hidden field (See StudentId definition). Given default value is used for new records.
When you create a child table, jTable automatically closes it when user clicks close icon of the table. You can change/override these functionalities.
ASP.NET Web Forms support
jTable has direct support for ASP.NET Web Forms Page Methods. While jTable is already platform independed, I have built an extension to jTable to support Page Methods in most proper way. For instance, see the code below. This page method is used to get student list as paged and sorted. It's pretty much similar to it's MVC version.
[WebMethod(EnableSession = true)]
public static object StudentList(int jtStartIndex, int jtPageSize, string jtSorting)
{
try
{
int studentCount = Repository.StudentRepository.GetStudentCount();
List<student> students = Repository.StudentRepository.GetStudents(jtStartIndex, jtPageSize, jtSorting);
return new { Result = "OK", Records = students, TotalRecordCount = studentCount };
}
catch (Exception ex)
{
return new { Result = "ERROR", Message = ex.Message };
}
}
For more information on ASP.NET Web Forms support, see the tutorial in jTable.org. Also, the download file in this article includes samples in ASP.NET Web Forms.
Details
This section of the article removed since a detailed and up-to-date API Reference documantaion is available on http://jtable.org/ApiReference.
Themes
All styles of jTable are defined it's own LESS/CSS files. Here, you see two different themes. Every theme has many color options.
Metro style theme:
There are 10 color options for metro style theme.
Light theme:
There are 5 color options for light color theme.
You can set any style by including its CSS file in your HTML document. For instance, to set light color red theme:
<link href="http://www.codeproject.com/Scripts/jtable/themes/lightcolor/red/jtable.css"
rel="stylesheet" type="text/css" />
If you want to use your own styles, you can start with themes/basic/jtable_basic.less file. If you did like a jTable theme but not happy with colors, you can copy one color and change it.
Combining with validation
Validation is a common task while working with forms. jTable exposes some events
to inject validation logic to jTable auto-created forms. You can use your own validation logic or a jQuery validation plug-in.
Validation engine [2] is a powerful validation plug-in for jQuery. I definitely recommend it. Here I will show how to inject validation
engine to a jTable instance. First, see the validation engine in action:
As you can see, when I try to save the form, the validation engine shows some error messages and prevent the submission of the form.
To be able to use the validation engine, first we must add style and JavaScript files to our HTML page:
<!--
<link href="@Url.Content("~/Scripts/validationEngine/validationEngine.jquery.css")"
rel="stylesheet" type="text/css" />
<!--
<script type="text/javascript"
src="@Url.Content("~/Scripts/validationEngine/jquery.validationEngine.js")">
</script>
<script type="text/javascript"
src="@Url.Content("~/Scripts/validationEngine/jquery.validationEngine-en.js")">
</script>
Then we register to the events of jTable to inject validation engine to jTable forms:
<script type="text/javascript">
$(document).ready(function () {
$('#PersonTable').jtable({
title: '...',
actions: {
...
},
fields: {
...
},
formCreated: function (event, data) {
data.form.find('input[name="Name"]').addClass(
'validate[required]');
data.form.find('input[name="EmailAddress"]').addClass(
'validate[required,custom[email]]');
data.form.find('input[name="Password"]').addClass(
'validate[required]');
data.form.find('input[name="BirthDate"]').addClass(
'validate[required,custom[date]]');
data.form.find('input[name="Education"]').addClass(
'validate[required]');
data.form.validationEngine();
},
formSubmitting: function (event, data) {
return data.form.validationEngine('validate');
},
formClosed: function (event, data) {
data.form.validationEngine('hide');
data.form.validationEngine('detach');
}
});
$('#PersonTable').jtable('load');
});
</script>
The validation engine works with CSS classes for validation. validate[required]
indicates that this
input element can not be empty. Take a look at the validation engine's web site [2] for details.
In the formCreated
event, I add the required classes to input elements and call the validationEngine()
plug-in method on the form.
In the formSubmitting
event, I call the Validate
method of the validation engine. It returns false
if the form is not valid. So I use the same value as the return value of the formSubmitting
event. jTable does not submit
the form if this event returns false. Finally, in the formClosed
event, I detach the validation engine from the form.
This was the first method for validation. Since jTable allows you to inject classes to your input fields using
the inputClass
property in field definitions, we could define a field with the validate[required]
class as default:
Name: {
title: 'Name',
width: '15%',
inputClass: 'validate[required]'
},
Thus, jTable automatically adds the validate[required]
class to the input element of this field. So we don't need to add classes to inputs
in the formCreated
event.
See the "Using with 'validation engine' plugin - 2" demo page in the download file or the demo web site [1].
Future works
jTable is developed under GitHub (https://github.com/hikalkan/jtable). I'm working on jTable to improve it. Also, anyone who wants to contribute to jTable can fork it and send pull request. Here, you can find what features will be included to jTable in next versions: http://jtable.org/Home/RoadMap
More
I have created an official website for jTable. There are documentations and samples on http://www.jtable.org.
I've also written an article on real time, aynchronous, server-to-client updates using jTable and SignalR: http://www.codeproject.com/KB/aspnet/RealTimeAsynchWebPages.aspx
History
- 10.02.2013: jTable 2.2.0
- Features: Toolbar, 'Change page size' and 'go to page' controls.
- Multiple sorting of columns by holding CTRL key.
- Hungarian and Italian localizations.
- Fixed some issues.
- 30.01.2013: jTable 2.1.1
- Multiple dependsOn support.
- Enhanced option caching.
- Portuguese - Portugal and Chinese localizations.
- Fixed some issues.
- 28.01.2013: jTable 2.1.0
- Added cascade dropdowns and creating dynamically option list support.
- Added field options: dependsOn and optionsSorting
- Polish, Lithuanian and Portuguese - Brazilian localizations.
- Fixed some issues.
- 24.01.2013: jTable 2.0.1
- Fixed some issues.
- Spanish and Vietnamese localizations.
- 14.01.2013: jTable 2.0.0
- All codebase revised and refactored.
- All CSS re-written using less css.
- Added metro style theme with 10 color options.
- Added a basic theme that can be start point who want to create themes to jTable.
- Added methods: getRowByKey, selectRows.
- Added field option: ajaxSettings.
- Added feature: editing primary key's value.
- Added feature: Allow updating a record with server response after updateAction
- Added ready-to-use localization scripts.
- Fixed some issues reported on GitHub.
- Set default values for key field as "edit: false" and "create: false"
- Fixed some other minor bugs.
- Removed standard theme.
- Tested with latest jQuery libraries (jQuery v1.8.3 and jQuery UI v1.9.2).
- 11.05.2012: jTable 1.7.2
- A bugfix on using column selecting with row selecting.
- 10.05.2012: jTable 1.7.1
- Added one theme and five color options.
- Bugfix on select/resize columns when page is scrolled.
- 28.04.2012: jTable 1.7
- Added feature: Allowing user to show/hide columns.
- Added general option: columnSelectable.
- Added field option: visibility.
- Added method: changeColumnVisibility.
- 17.04.2012: jTable v1.6
- Added features: Column resizing and remembering user preferences using cookies.
- 08.01.2012: jTable v1.5.1
- Added methods: addRecord, deleteRecord and updateRecord.
- Added more date formats.
- 18.12.2011: jTable 1.4.2
- IE8 delete button bugfix.
- animationsEnabled option.
- 15.12.2011: jTable 1.4.1
- Direct support for ASP.NET Web Forms Page Methods.
- Added hidden field type to be used on forms.
- 29.11.2011: jTable v1.4.
- Added feature: Master/child table support (unlimited depth).
- Added methods: closeChildRow, closeChildTable, getChildRow, isChildRowOpen, openChildRow, openChildTable, showCreateForm.
- Added events: rowInserted, rowUpdated, closeRequested.
- Added options: showCloseButton, openChildAsAccordion.
- Added field option functions: input, display.
- Added green theme.
- Bugfix: Multiple jTable in single page.
- 20.11.2011: jTable v1.3.
- Added methods: reload, deleteRows.
- Added events: loadingRecords, rowsRemoved.
- Added options: dialogShowEffect, dialogHideEffect.
- Added feature: Multiple selecting on table by using shift key.
- Changed option: deleteConfirmation can also be a function anymore.
- Code base completely refactored according to jQueryUI extensible widget pattern.
- 14.11.2011: jTable v1.2.
- Added server side sorting support.
- Added client side selecting support.
- Some minor bugfixes.
- 08.11.2011: jTable v1.0.
- Added server side paging support.
- Added recordAdded, recordDeleted, recordsLoaded and recordUpdated events.
- 01.11.2011: jTable v0.9a. First release.
References
[1] jTable official website: http://www.jtable.org
[2] Validation engine plug-in: http://www.position-relative.net/creation/formValidator