Click here to Skip to main content
Click here to Skip to main content

AJAX based CRUD tables using ASP.NET MVC 3 and jTable jQuery plug-in

By , 10 Feb 2013
 
Prize winner in Competition "Best overall article of November 2011"
Prize winner in Competition "Best Web Dev article of November 2011"
jTable overview
A full-featured jTable instance. Try a live demo here.

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:

The person list

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:

Creating new record

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:

Editing a record

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):

Delete confirmation dialog

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; }

    // Id of a City in Cities
    [Required]
    public int CityId { get; set; }

    [Required]
    public string Name { get; set; }

    [Required]
    public string EmailAddress { get; set; }

    [Required]
    public string Password { get; set; }

    // "M" for mail, "F" for female.
    [Required]
    public string Gender { get; set; }

    [Required]
    public DateTime BirthDate { get; set; }

    public string About { get; set; }

    // 0: Unselected, 1: Primary school,
    // 2: High school 3: University
    [Required]
    public int Education { get; set; }

    //true: Active, false: Passive
    [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:

jTable folder structure

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 () {

        //Prepare jtable plugin
        $('#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
                }
            }
        });

        //Load person list from server
        $('#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:

jTable paging

To enable paging, paging option must set to true. You can also set pageSize option (default value is 10).

$('#PersonTable').jtable({
    //...
    paging: true, //Set paging enabled
    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:

jTable sorting

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, //Enable sorting
    defaultSorting: 'Name ASC', //Sort by Name by default
    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:

jTable selecting

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.

//Prepare jtable plugin
$('#PersonTable').jtable({
    //...
    selecting: true, //Enable selecting
    multiselect: true, //Allow multiple selecting
    selectingCheckboxes: true, //Show checkboxes on first column
    //selectOnRowClick: false, //Enable this to only select using checkboxes
    actions: {
        //...
    },
    fields: {
        //...
    },
    //Register to selectionChanged event
    selectionChanged: function () {
        //Get all selected rows
        var $selectedRows = $('#PersonTable').jtable('selectedRows');

        $('#SelectedRowList').empty();
        if ($selectedRows.length > 0) {
            //Show selected rows
            $selectedRows.each(function () {
                var record = $(this).data('record');
                $('#SelectedRowList').append(
                    'PersonId: ' + record.PersonId +
                    'Name:' + record.Name
                    );
            });
        } else {
            //No rows selected
            $('#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:

Master Child table on jTable

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) { //opened handler
            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
    {
        //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 };
    }
}

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:

jTable Metro Styles Red

There are 10 color options for metro style theme.

Light theme:

jTable Lightcolor gray style

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:

Validatin Engine Integration

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:

<!-- Validation engine style file -->
<link href="@Url.Content("~/Scripts/validationEngine/validationEngine.jquery.css")" 
      rel="stylesheet" type="text/css" />

<!-- Validation engine script file and english localization -->
<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 () {

        //Prepare jtable plugin
        $('#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');
            }
        });

        //Load person list from server
        $('#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

License

This article, along with any associated source code and files, is licensed under The MIT License

About the Author

Halil ibrahim Kalkan
Software Developer Sestek
Turkey Turkey
I have started programming at 14 years old using Pascal as hobby. Then I interested in web development (HTML, JavaScript, ASP...) before university.
 
I graduated from Sakarya University Computer Engineering. At university, I learned C++, Visual Basic.NET, C#, ASP.NET and Java. I partly implemented ARP, IP and TCP protocols in Java as my final term project.
 
Now, I am working in a private company in Istanbul as a professional software developer. I have been working on windows and web based software development using C#.NET for five years.
 
http://www.halilibrahimkalkan.com

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
QuestionEditing FormmemberMember 955879511-Nov-12 6:37 
I used your tutorial for project I got the grid to display my data from an SQL Server database that I connected to using the Server Explorer. I'm using VS 2010 MVC3 for the project but when I click the save button in the edit table nothing happens. I don't know why I thought I did everything correctly since everything else works. I can send you the project if you'd like or can you tell me why my edit record table does not work, thanks.
AnswerRe: Editing FormmemberYamilBracho12-Nov-12 2:42 
Check your server side code...
BugDialog WidthmemberTrevor Goertzen6-Nov-12 13:00 
The width of the dialog box used for editing and creating records is 100% of the page width in IE7 on the jtable.org site. It is a normal width in FF. Any ideas on how to fix this?
Questionhow I can get the data once the load is calledmemberdiegocz6-Nov-12 3:27 
I want to stroe the data in a array for do stuff with the data, how can I achieve this
 
try this but dont work can get but is in the "data"
 
$('#TraspasoReboteTableContainer').jtable('load', {
            almacenId: IdOnly($('#AlmacenOrigen').val()), // parameter
            movimientoId: IdOnly($('#MovimientoId').val()),
// parameter
            completeCallback: function (data) {
               if(data.Result == "OK")
{
// do something
}
            }
 });
AnswerRe: how I can get the data once the load is calledmemberYamilBracho6-Nov-12 3:56 
No tested, maybe it could work :
 
completeCallback: function (data) {
  if(data.Result == "OK") {
       jsonData = JSON.stringify(data.form);
  } 
 
Or serialize the form using JQuery(URL Encoded) and then convert the resulting string to json... Smile | :)
GeneralRe: how I can get the data once the load is called [modified]memberdiegocz6-Nov-12 4:44 
thanK I will test. I Can do it like this with this event
 
recordsLoaded: function (event, data) {
                   var returndata = data.serverResponse;
                   if (returndata.Result == "OK") {
                       var model = data.records;
                       if (model != null) {
                           for (var i = 0; i < model.length; i++) {
                               var registro = {
                                   MovimientoDetId: model[i].MovimientoDetId,
                                   ProductoId: model[i].ProductoId,
                                   CodigoProducto: model[i].CodigoProducto,
                                   StockActual : model[i].StockActual,
                                   Cantidad: model[i].Cantidad
                               };
                               registros.push(registro);
                           }
               }
           }
 
the problem with this is that when I delete a record for some reason that not understand it loaded agagin (to my action in my controller) and call that event again
 
how I delete a record
$('#TraspasoReboteTableContainer').jtable('deleteRecord', {
           key: id,
           clientOnly: true
       });
 

i CALL the load for my jtable from a button so there is no connection between my load and delete
 
$('#TraspasoReboteTableContainer').jtable('load', {
            almacenId: IdOnly($('#AlmacenOrigen').val()),
            movimientoId: IdOnly($('#MovimientoId').val()),
            });
 
oh now is ok it load again because I have pagging = true in my jtable I erase that and is fine now
 
thank you for your help

modified 6-Nov-12 14:37pm.

QuestionFilteringmemberjelenacosa6-Nov-12 0:17 
Hi again,
I have one question. Is it possible to fill dropdown list for filtering from database same way as options in fields are filled for edit?
For example, I have 10 options for field "States" when I want to update or add row in table (these 10 are from database, not hard coded), so I want this same dropdown list as my filter.
I know I can do it, by calling database again, but is there a way to do it with JTable?
Thanks, Jelena

QuestionManipulate Select BoxmemberMember 94750025-Nov-12 23:19 
Hi,
 
I have a requirement in create/edit screen, where i have 2 select box. The values of 2nd select box is determined by the value selected in 1st select box. So, based on the value selected in 1st select box, i have to make a ajax call to determine the values for 2nd select box & also populate the values.
 
Thanks
AnswerRe: Manipulate Select BoxmemberYamilBracho6-Nov-12 3:28 
This is a code I published in the forum:
 
formCreated: function (event, data) {
   var cboLocationOffice = data.form.find('select[name="LocationOfficeId"]');
   var cboLine = data.form.find('select[name="LineId"]');
 
   // LocationOffice ComboBox Change
   cboLocationOffice.change(function(e) {
	var locationOfficeId = $(this).val();
 
	// Refresh Line Combo
	var url = '../Line/LineController.php?action=O&locationOfficeId=' + locationOfficeId;
	$.getJSON(url, { ajax: 'true' }, function(response) {
		var result = response.Result;
		var options = '';
				
		cboLine.html(options);
		if (result == 'OK') {
   		   var rows = response.Options;
		   for (var i=0; i < rows.length; i++) {
		     options += '<option value="' + rows[i].Value + '">' +
			rows[i].DisplayText + '</option>';
		    }
	 	 }
		cboLine.html(options);
		cboLine.change();
	    });
});
...

GeneralRe: Manipulate Select BoxmemberMember 94750026-Nov-12 5:50 
Thanks for the snippet. Could you please give me the complete javascript for this sample? I would like to know where to exactly place it.
 
Thanks
GeneralRe: Manipulate Select BoxmemberYamilBracho6-Nov-12 5:56 
Inside your jtable definition, maybe afte the "fields"...
   $('#ClientTableContainer').jtable({
     ...
     fields:{
        ...
     },
     formCreated:function(event, data) {
       ...
     }
   });

GeneralRe: Manipulate Select BoxmemberMember 94750026-Nov-12 6:05 
Please find below my code. Values for AreaType must be determined based on the PhoneType select. Could you please help me in placing your script at the correct place in the code below?
 
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>DataTables</title>
 
<script type="text/javascript" language="javascript" src="../../static/jtable/jquery.js"></script>
<script type="text/javascript" language="javascript" src="../../static/jtable/jquery-ui.js"></script>

<!-- Include one of jTable styles. -->
<link href="../../static/jtable/themes/standard/blue/jtable_blue.css" rel="stylesheet" type="text/css" />

<!-- Include jTable script file. -->
<script src="../../static/jtable/jquery.jtable.min.js" type="text/javascript"></script>
 

 
<script type="text/javascript">
$(document).ready(function () {
$('#PersonTableContainer').jtable({
id: 'personDiv',
title: 'Table of people',
actions: {
listAction: '/brands/personList',
createAction: '/GettingStarted/CreatePerson',
updateAction: '/rest/brands/updatePerson',
deleteAction: '/GettingStarted/DeletePerson'
},
fields: {
id: {
key: true,
create: false,
edit: false,
list: false
},
name: {
title: 'Author Name',
width: '40%'
},
age: {
title: 'Age',
width: '20%'
},
recordDate: {
title: 'Record date',
width: '30%',
create: false,
edit: false
},
// start of child phone
phone: {
title: 'phone',
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 class="phone-number-class" src="../../static/jtable/phone.png" title="Edit phone numbers" />');
//Open child table when user clicks the image
$img.click(function () {
$('#PersonTableContainer').jtable('openChildTable',
$img.closest('tr'),
{
title: studentData.record.name + ' - Phone numbers',
actions: {
listAction: '/brands/phoneList?id=' + studentData.record.id,
deleteAction: '/Demo/DeletePhone',
updateAction: '/Demo/UpdatePhone',
createAction: '/Demo/CreatePhone'
},
fields: {
id: {
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%'
},
areaType: {
title: 'Area Type',
width: '10%',
options: {
}
}
}

},
function (data) { //opened handler
data.childTable.jtable('load');
}

);
});
//Return image to show on the person row
return $img;
}
}
///// end of child phone
}
});

$('#PersonTableContainer').jtable('load');
});
</script>


</head>
<body>
 
<div id="PersonTableContainer"></div>
 
</body>
</html>
GeneralRe: Manipulate Select BoxmemberYamilBracho6-Nov-12 6:21 
Take out the 'options' definition for areaType field and next, after the areaType field definition add teh formCreated:
 
  ...
   areaType: {
    title: 'Area Type',
      width: '10%'
   }
 }
},
formCreated:function(event,data) {
   var cboPhoneType = data.form.find('select[name="PhoneType"]');
 
   cboPhoneType .change(function(e) {
      var phoneType= $(this).val();
      var cboAreaType = data.form.find('select[name="areaType"]');
      var url = 'YourservercodeToFillAreaType?action=Fill_Area&phoneType=' + phoneType; 
						  
      $.getJSON(url, { ajax: 'true'}, 
	function(response) {      
  	   var result = response.Result;
	   var options = '';   	
						
	   cboAreaType.html(options);
	   if (result == 'OK') {
	     var rows = response.Options;
	     for (var i=0; i < rows.length; i++) {
		 options += '<option value="' + rows[i].Value + '">' +
	            rows[i].DisplayText + '</option>';
	     }
	   }
	   cboAreaType.html(options);  
	});	
     });
}),
...
}

GeneralRe: Manipulate Select BoxmemberMember 94750026-Nov-12 23:35 
It works!!! Thanks a lot for your help.
GeneralRe: Manipulate Select Box [modified]memberMember 94750022-Jan-13 10:12 
Hi,
 
PFB the code my snippet. Existing Allocation Code is displayed when the form is loaded. When i try to add a new record, in the new record pop up screen i select an allocation level, ajax call is made to get the corresponding allocation codes, but allocation codes are not getting displayed as drop down list. allocationCode is considered as textbox and not drop down list. Need your support.
 
allocationLevel: {
title: 'Allocation Level',
width: '12%',
create: true,
edit: false,
options: { '0': 'Select Allocation Level' , '1': 'Area', '2': 'Market', '3': 'Country', '4': 'Station'}
},
allocationCode: {
title: 'Allocation Code',
width: '12%',
create: true,
edit: false,
}
 

var oAllocationLevel = data.form.find('select[name="allocationLevel"]');

oAllocationLevel.change(function(e) {
var allocationLevelVal = $(this).val();
var oAllocationCode = data.form.find('select[name="allocationCode"]');
var url = '/displayAllocationCode?allocLevel=' + allocationLevelVal;
$.getJSON(url, { ajax: 'true'},
function(response) {
var result = response.Result;
var options = '';

oAllocationCode.html(options);
if (result == 'OK') {
var rows = response.Options;
for (var i=0; i < rows.length; i++) {
options += '<option value="' + rows[i].Value + '">' +
rows[i].DisplayText + '</option>';
}
}
oAllocationCode.html(options);
});
});
 
Response:
{"Options":[{"Value":"AMER","DisplayText":"AMER-Americas","key":"AMER","value":"AMER","displayText":"AMER-Americas"},{"Value":"ASIA","DisplayText":"ASIA-Asia","key":"ASIA","value":"ASIA","displayText":"ASIA-Asia"},{"Value":"EURO","DisplayText":"EURO-Europe","key":"EURO","value":"EURO","displayText":"EURO-Europe"},{"Value":"FDA","DisplayText":"FDA-FDA","key":"FDA","value":"FDA","displayText":"FDA-FDA"},{"Value":"MEIN","DisplayText":"MEIN-MEIndiaAfr","key":"MEIN","value":"MEIN","displayText":"MEIN-MEIndiaAfr"}],"Result":"OK"}

modified 2-Jan-13 16:30pm.

QuestionUpper and Lower CasememberRoberto Carlos Brazil5-Nov-12 20:23 
How can set a form field only to accept only upper or lower case?
AnswerRe: Upper and Lower CasememberYamilBracho6-Nov-12 3:13 
there is not built-in option for this in jtable. However, you can use JQuery and create a custom KeyUp event to handle. For example:
 
$('#yourTextFiled').keyup(function(){
    this.value = this.value.toUpperCase();
});
 
Also, I think (but I am not a CSS expert) you can use
input {
  text-transform: uppercase;
}

GeneralRe: Upper and Lower CasememberRoberto Carlos Brazil6-Nov-12 3:20 
Worked. Thank you.
QuestionMoney FormatmemberRoberto Carlos Brazil5-Nov-12 17:11 
Similar to date format:
BirthDate: {
title: 'Birth date',
width: '18%',
type: 'date',
displayFormat: 'dd/mm/yy'
},
 
Is it possible to have a money format?
Salary: {
title: 'Salary',
width: '18%',
type: 'money',
displayFormat: 'R$ #.##0,00'
},
 
Thanks.
AnswerRe: Money FormatmemberYamilBracho6-Nov-12 3:06 
The 'displayFormat' property is only valid for date fields... :(
GeneralRe: Money FormatmemberRoberto Carlos Brazil6-Nov-12 3:15 
Is there a way to format money on list/edit/insert?
GeneralRe: Money FormatmemberYamilBracho6-Nov-12 3:25 
For Create/Edit operations you got a form, so you can "find" the field and format it using javascript.
For list operation, you have to return the formatted field from your server side code.
To be short I think it could be easy to add a format option for text field but you would need to modify the jtable code...
QuestionCompound/Composite Primary Key [modified]memberRoberto Carlos Brazil5-Nov-12 16:40 
Is it possible to define a compound/composite key field such as?
fields: {
TeacherId: {
key: true,
create: false,
edit: false,
list: false
},
ModuleId: {
key: true,
create: false,
edit: false,
list: false
},
...
This is due database design...
Thanks.

modified 5-Nov-12 23:12pm.

AnswerRe: Compound/Composite Primary KeymemberYamilBracho6-Nov-12 3:03 
The key option defines an unique index per table and it's used in update and delete operations, where that field it is automatically passed as parameter to your server side code.
GeneralRe: Compound/Composite Primary KeymemberRoberto Carlos Brazil6-Nov-12 3:13 
How can I pass a second paramter for update and delete operations?
GeneralRe: Compound/Composite Primary KeymemberYamilBracho6-Nov-12 3:22 
For update operation it's easy, because you have the needed fields in a form and they are passed to your server side code via POST.
However, with delete, things get complicated... Maybe you can create an unique key combining the other fields...
QuestionOptions in fieldmemberjelenacosa5-Nov-12 6:31 
First of all, I want to thank you for such a great job Big Grin | :-D
I'm implementing your plug-in in my JSP project, a it's great.
Only thing I want to ask you is to provide me an example of array returned for field options from server(I'm using URL, so I have string or json). Is it:
{"Result":"OK", "Records"=[{"something":"something"}, {"somethingElse":"etc"}]}
or
{Result=OK, Records=[{something=something}, {somethingElse=etc}]}
or something else?
I've seen something with values and DisplayText, but I don't know how exactly that looks.
Thank you
AnswerRe: Options in fieldmemberRoberto Carlos Brazil5-Nov-12 7:20 
This is a result example for getCityOptions:
{
"Result":"OK",
"TotalRecordCount":15,
"Options":
[
{"DisplayText":"Adana","Value":"1"},
...
{"DisplayText":"Volos","Value":"15"}
]
}
GeneralRe: Options in fieldmemberYamilBracho5-Nov-12 8:07 
For this response you only need Result and Options in the format as Roberto mentioned...
GeneralRe: Options in fieldmemberjelenacosa5-Nov-12 8:36 
OK. Thank you very much. Big Grin | :-D
QuestionHow to pass values from separate form along with the Jquery Jtable?memberAllen Emanuel Raj4-Nov-12 20:04 
I have a separate form in the php page which also has jtable. the form have drop down list boxes to select options. i have to pass the values from those dropdown along with the Jtable action List, to list rows with respect to the condition selected from the drop down.
 
If i choose Machine 1 from the dropdown list, i have to make the jtable to display only the rows which has machine as Machine 1 in the table. i have the db query to retrieve rows matching the passing machine value. But the problem is i can't able to pass the value from the dropdown along with Jtable parameters to the Actions.php page.
 
Is it possible to pass value from in jtable.

AnswerRe: How to pass values from separate form along with the Jquery Jtable?memberYamilBracho5-Nov-12 3:59 
I have two textfield in my form when the user enter two dates and then click in a button to refresh my jtable. My code is :
 
function btnSearchClick(e) {
  $('#TableContainer').jtable('load', {
    fromDate: $('#txtFrom').val(),
    toDate: $('#txtTo').val()
   });
   e.preventDefault();
}

GeneralRe: How to pass values from separate form along with the Jquery Jtable?memberAllen Emanuel Raj6-Nov-12 19:44 
Thanks for your help, My actual need is,
 
I took the value from drop down options by
                                select = document.getElementById("selectShift");
				select.onchange = function(){
					//alert(this.value); 
					//alert(this.innerHTML); 
					var options = this.getElementsByTagName("option");
					optionHTML = options[this.selectedIndex].innerHTML;  
					//alert(optionHTML); 
				};
now optionHTML have a value in it. I want to pass the value in listActions url like this
listAction: 'ShiftLogActions.php?action=list&ShiftId='+optionHTML
but i get undefined in the actions page.
when i hardcode shift value like thid
listAction: 'ShiftLogActions.php?action=list&ShiftId=Shift_92'
its working fine, is there any way to do it?
GeneralRe: How to pass values from separate form along with the Jquery Jtable?memberYamilBracho7-Nov-12 2:47 
Try
select = document.getElementById("selectShift");
select.onchange = function(){
	//alert(this.value); 
	//alert(this.innerHTML); 
	var options = this.getElementsByTagName("option");
	optionHTML = options[this.selectedIndex].innerHTML;  
	
  $('#TableContainer').jtable('load', {
    ShiftId: optionHTML
   });
	
	//alert(optionHTML); 
};
 

GeneralRe: How to pass values from separate form along with the Jquery Jtable?memberAllen Emanuel Raj7-Nov-12 16:43 
Hi YamilBracho,
 
Even then i was not able to use the ShiftId in my ListAction like this,
listAction: 'ShiftLogActions.php?action=list&ShiftId='+ShiftId,

GeneralRe: How to pass values from separate form along with the Jquery Jtable?memberYamilBracho8-Nov-12 2:38 
This happens because the creation of the list attribute occurs before your code..
Th only way to refresh your jtable according a filter is using the load method...
GeneralRe: How to pass values from separate form along with the Jquery Jtable?memberAllen Emanuel Raj9-Nov-12 20:52 
Thanks YamilBracho, it works fine. I have another issue, i can't able to use paging properly, if i gave pageSize 10, and the total record is 20, even though i click 2 page, it displaying the same 10 records from the first page.
 
How can i use paging in filters.
 
Thank you.
QuestionERROR: "this.options.fields undefined" [ in _createCellForRecordField ]memberAdeptBlue2-Nov-12 0:29 
QUESTION: How can I reset/re-initialize jTable so that I can
               call a second table WITHOUT refreshing the entire
               page?
 
I have 9 jTables that I want to call individually in response to button-
clicks.
 
The first jTable loads fine [ and will reload fine ].
 
When I try to load a second table I get the error above.
 
I examined the jTable code & can see that the problem is that jTable is not
being re-initialized for the second table.
 
If I refresh the page before calling hitting the second button it works just
fine. But, this defeats my purpose of having the MasterForm/Layout static &
the jTables change in an AJAX fashion.
 
My question is:
 
   How can I reinitialize jTable when a new table is called without refreshing
   the entire page?
 
   I was thinking of something along the lines of forcing it with a
call(?) to _create [i.e. Constructor], but i'm not sure how that would work.
 
   Is there some way to 'drop' jTable and restart it to force the
initialization?
 
   Roger
AnswerRe: ERROR: "this.options.fields undefined" [ in _createCellForRecordField ]memberYamilBracho2-Nov-12 4:52 
I have a form in my app, where the user sets two dates and in a event click of a button the jtable is reload with the new info without reloading the whole page.
 
// ----------------------------------------------------
// Shows new info in the table according dates
// ----------------------------------------------------
function btnSearchClick(e) {
	$('#TableContainer').jtable('load', {
		fromDate: $('#txtFrom').val(),
		toDate: $('#txtTo').val()
	});
	e.preventDefault();
}

GeneralRe: ERROR: "this.options.fields undefined" [ in _createCellForRecordField ]memberAdeptBlue2-Nov-12 6:35 
First ... Thank you for your quick reply.
 
I tried adding 'load' & I think a made some progress. But now another error
pops up:
 
0x800a138f - Microsoft JScript runtime error: Unable to get value of the property 'form': object is null or undefined.
 
This is in: formCreated: function (event, data) of 2nd table
 
            //Initialize validation logic when a form is created
            formCreated: function (event, data)
            {
                  data.form.validationEngine();
            },
 
I wasn't sure what to do with the e.preventDefault(); as my code is a bit different
from yours. I understand what e.preventDefault(); generally does, but I don't think this is my problem here.
 
I have another table where I pass variable to the table successfully and the table does not reload without either 'load' or e.preventDefault();.
 
I believe my original problem is different that the solution you outline. I am NOT trying to update the current table. I am attempting to load a new table in a AJAX manner.
 
Table 1 is displayed [ and works successfully ]
On button-click, I am attempting to load a new table into the same space.
 
Table 2 is the one throwing the error> "this.options.fields undefined"
 
I do believe it is because jTable has not been 're-initialized' with the appropriate data for table 2.
 
If I reload the page[ F5 ] [ and jTable, of course ] and click on the 2nd button, it loads OK.
 
Strangely, if I now click button 1, the first table is again displayed. [ I think this may because of a cache ? ]
 
Possibly seeing some code will make this plain:
 
      <span><button onclick ="displayUsers()">Users</button></span>   // Button 1
      <span><button onclick ="displayGames()" >Games</button></span>   // Button 2  
 

// ****************** usersTable ***********************************
 
[ Table 1 ]
 
function displayUsers() {
      $('#AdminTableContainer').jtable(
      {
            title: 'Users',
 

 
// ****************** gamesTable ***********************************
 
[ Table 2 ]
 
function displayGames() {
      $('#AdminTableContainer').jtable(
      {
            title: 'Game List',
 

Any ideas on how I can re-initialize jTable.js when I click button 2 and before table 2 is submitted to jTable.js.
 
Thank you for your help
 
Roger
GeneralRe: ERROR: "this.options.fields undefined" [ in _createCellForRecordField ]memberYamilBracho2-Nov-12 6:46 
Ok.. Roger, now I can see what you want to do...
Maybe you can use JQuery getScript() to load and execute the particular code for each table... Unsure | :~
GeneralRe: ERROR: "this.options.fields undefined" [ in _createCellForRecordField ]memberAdeptBlue2-Nov-12 13:29 
Thanks again !!
 
'Close, but no cigar' as they say.
 
This solution has a timing issue. The first time I click on Button 1, it sets up the .js file,
but says it cannot find the function it just loaded.
 
Here is the code so you can follow:
 
      <span><buttononclick ="DisplayUsers()">Users</button></span>      // Button 1
      <span><button onclick ="DisplayGames()" >Games</button></span>   // Button 2
  
 
function DisplayUsers()         // Code 1
{
      $.getScript('/Areas/Admin/Scripts/displayUsers.js');
 
      displayUsers();
};
 
function DisplayGames()         // Code 2
{
      $.getScript('/Areas/Admin/Scripts/displayGames.js');
 
      displayGames();
};
 
The second time I click [ on the same button ], the code runs sorrectly.
 
Then: the first time I click on Button 2 is returns 'DisplayGames is not defined
[ same as Button 1 ]. The second time I click on Button 2, it returns the original error: 'this.options.fields[fieldName] is undefined'.
 
So ... back to square 1.
 
I think I still need to find a way to re-initialize jTable [ _create: ].
 
By-the-way, I also tried to use $.getScript() to reload jTable without success, but the error was different:
      "0x800a138f - Microsoft JScript runtime error: Unable to get value of the   property 'listClass': object is null or undefined".
 
The error location is:
 
            /* Create a cell for given field.
            *************************************************************************/
            _createCellForRecordField: function (record, fieldName) {
                  return $('<td class="' + this.options.fields[fieldName].listClass + '"></td>')                              //
                        .append((this._getDisplayTextForRecordField(record, fieldName) || ''));
            },
 
Again, the problem keeps revolving around initialization of '.fields'. And, if we solve the specific problem of initilizing '.fields', I suspect another of the initializeFields in:
 
            /* Intializes some private variables.
            *************************************************************************/
            _initializeFields: function () {
                  this._lastPostData = {};
                  this._$tableRows = [];
                  this._columnList = [];
                  this._fieldList = [];
                  this._cache = [];
            },
 
would pop up as a problem.
 
I hope this all makes sense.
 
Thanks
 
Roger
GeneralRe: ERROR: "this.options.fields undefined" [ in _createCellForRecordField ]memberYamilBracho5-Nov-12 5:08 
Roger, are you including jtable.js in your current script or in the "loaded" script. Try putting it in the "static" script...
And check your fieldnames in your jtable definition. It looks like some field name is misspelled...
GeneralRe: ERROR: "this.options.fields undefined" [ in _createCellForRecordField ]memberAdeptBlue6-Nov-12 6:18 
Hi again ...
 
Sorry I took so long to get back, but I've been trying all sorts of things.
 
I'm loading jTable statically. I had experimented with dynamic load, but that didn't help so I went back to static.
 
What you think is miss-spelling is exactly the problem:
 
At that point, I am trying to load Button2/Code2. The data for Code2 IS LOADED.
That is, if I break and use intellisence I see the data for Code2.
 
But jTable is attempting to find the 'listClass' for Button1/Code1 fields. Thus,
it blows up since there is no index into the array for that field value.
 
It appears, at this point, that everything is loading/operating correctly EXCEPT
updating/reloading the array of field names.
 
That is why I keep looking for a way to update/reload this array.
 
I have tried to 'trace' the process to look for a point at which I could update the field array, but I just keep getting myself tied in knot [ as the Brits say 'got my knickers twisted' ]. This is because I quite new to Javascript/jQuery. But
I still feel that if I could find that place to modify [ hack ?? ] jTable that would
solve my problem.
 
I admit I am trying to do something that wasn't anticipate in jTable, but I feel that if jTable can [seem to] load everything else OK, it should update this field array.
 
Hope I'm not asking too much.
 
Thanks again for your help
 
Roger
GeneralRe: ERROR: "this.options.fields undefined" [ in _createCellForRecordField ]memberYamilBracho6-Nov-12 6:30 
Yes, it is likely we need to modify some code in jtable Frown | :(
I am running out of ideas... D'Oh! | :doh:
I just checked the docs some minutes ago and found a "destroy" method..
Try this method before load the jtable definition using Jquery.getScript()...
GeneralRe: ERROR: "this.options.fields undefined" [ in _createCellForRecordField ]memberAdeptBlue6-Nov-12 7:55 
I had not seen 'destroy' but I was essentially preforming the same with:
 
function showTable(ndx)
{
            // Remove any existing 'span' with id='jsDisplay'
            $('#jsDisplay').remove();
 
            // Select the parent and append SPAN
            $("#AdminTableContainer").append("<span id = 'jsDisplay'></span>");
 
            var display = document.getElementById("jsDisplay");
            display.innerHTML = js[ndx];
 
            // Remove any existing 'span' with id='cssDisplay'
            $('#cssDisplay').remove();
 
            // Select the parent and append SPAN
            $(".MainContentWide").append("<span id = 'cssDisplay'></span>");
 
            var display = document.getElementById("cssDisplay");
            display.innerHTML = ss[ndx];
 
            eval(script1[ndx]);
};
 
// *******************   Partials
var ss =
[
   '<link href="/Areas/Admin/Content/displayUsers.css" rel="stylesheet"/>',
   '<link href="/Areas/Admin/Content/displayGames.css" rel="stylesheet"/>',
 
var js =
[
   '<script src="/Areas/Admin/Scripts/displayUsers.js"></script>',
   '<script src="/Areas/Admin/Scripts/displayGames.js"></script>',
 
var script1 =
[
   'displayUsers()',
   'displayGames()',
 
// *******************   Partials
 

 
'destroy' only applies to the child in a master/child table. The above applies to the entire table.
 
NOTE: I also destroy/recreate the appropriate .css file to match up with the table being opened. This is to cure a problem if ALL .css file are loaded at the start. [ the many fields with the same name were totally confusing the app at run time].
 
I see in GOOGLE there might be a problem by assigning the table [.js] to the innerHTML [its not a problem for .css]. It seems the code (.js) will not run automatically when it is assigned to the innerHTML.
 
The recommendation was to use eval(). But I'm not sure I'm doing it right. Any thoughts?
 
Roger
GeneralRe: ERROR: "this.options.fields undefined" [ in _createCellForRecordField ]memberYamilBracho6-Nov-12 8:22 
Roger, Do you have HTML code in the js to be loaded or just only plain javascript ?
I mean something like :
<script type="text/javascript">
    alert("Hello");
    $(function() {
       alert("Hello from jQuery ready");
    });
<script

GeneralRe: ERROR: "this.options.fields undefined" [ in _createCellForRecordField ] [modified]memberAdeptBlue6-Nov-12 11:30 
UPDATE -- 11/07/12:   Making Progress
 
I created a PUBLIC function 'create' that calls the _create: function but I'm having trouble figuring exactly where to put it. Right now, I place it before the 1st constructor _create:
 
            // RJD2
            /* re-Initialize
            *************************************************************************/
            create: function () {
                  this._create();
            },
 
Each Button Click will call this function:
 

function showTable(ndx)
{
      // re-Initialize jTable
      $('#AdminTableContainer').jtable('create')
                           o
                           o
                           o
      );
 
When I click button1 the first time, it DOES NOT go thru my create function, but the from comes up OK
 
When I click button2, it DOES go to my create function, but my create function goes to the _create: function in the section "* DYNAMIC COLUMNS extension for jTable "
[ approx. line 3300 ] instead of the _create: at line [approx] 125 !!!
 
Any idea why ???
 
This ends up at the same problem: field list isn't properly initialized. But, the code1 form comes up with "No Data".
 
Here is the interesting part: If I click button2 again -- IT WORKS !!
Form2 comes up properly with data!!
 
Tracing this, this case also went thru "* DYNAMIC COLUMNS extension for jTable " section but without any error.
 
If I now click button1, the same thing occurs:
      First: Error
      Then: Success
 
Any Thoughts
 
Roger
 
PS You can probably ignore the following
 
I'm loading ONLY the jTable:
 

// ****************** usersTable ***********************************
 
function displayUsers() {
      $('#AdminTableContainer').jtable(
      {
            title: 'Users List',
                        o
                        o
                        0
 
   );
 
      //Load 'Users' list from server
      $('#AdminTableContainer').jtable('load');      // Get all records
 
};

-- modified 7-Nov-12 15:25pm.
QuestionCalculate age from record date?memberRoberto Carlos Brazil31-Oct-12 11:37 
Based on Table of People http://www.jtable.org/GettingStarted[^] how could calculate days passed since Record Date and save this number to Age?
AnswerRe: Calculate age from record date?memberYamilBracho2-Nov-12 4:58 
Do that in your server side code...

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web04 | 2.6.130617.1 | Last Updated 10 Feb 2013
Article Copyright 2011 by Halil ibrahim Kalkan
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid