Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / Java / JavaSE / J2EE

Editable (CRUD) Web Tables in J2EE (jQuery Data Tables and J2EE Application Integration - Part II)

4.86/5 (32 votes)
10 Apr 2012CPOL15 min read 242.7K   10.9K  
This article explains how you can implement full data management functionalites (adding, deleting, inline editing) into web tables using jQuery DataTables/Editable and J2EE applications.

Introduction

In this article, I will continue with explanations about how to implement highly functional web 2.0 tables in J2EE using the JQuery. In the previous article, "JQuery Data Tables in Java Web Applications", I have explained how you can easily convert a plain HTML table to fully functional Web 2.0 table. Here, I will explain how you can add additional data management functionalities in web tables. The following example shows a web table that enables the user to edit cells using an inline editor.

J2EE-Editable-Web-Table/editable-datatable-java-intro.png

You can see a lot of functionality in this table for data browsing (filtering by keyword, ordering by header cell, pagination, changing number of records that will be shown per page) and data management (editing cells inline, deleting rows, and adding new ones). In the first article about this topic, "JQuery Data Tables in Java Web Applications", I have explained how to integrate basic JQuery DataTables functionalities with Java web tables.

Enhancing HTML tables with search, ordering, pagination, changing the number of records shown per page, etc. is an easy task if you are using the jQuery DataTables plug-in. Using this plug-in, you can add all the above mentioned functionalities to a plain HTML table placed in the source of a web page, using a single JavaScript call:

JavaScript
$("myTable").dataTable();

In this example, "myTable" is the ID of an HTML table that will be enhanced using the DataTables plug-in. The only requirement is to have a valid HTML table in the source of the web page.

The goal of this article is to show how you can add additional functionalities using the JQuery DataTables Editable plug-in. Using this plug-in, you can add features for inline editing, deleting rows, and adding new records using the following code:

JavaScript
$("myTable").dataTable().makeEditable(); 

This call will add data management functionalities on top of the standard DataTable functionalities. These functionalities handle complete interaction with the user related to editing cells, deleting and adding rows. On each action, the plug-in sends an AJAX request to the server-side with information about what should be modified, deleted, or added. If you are using a J2EE application, you will need to implement server-side functionalities that perform ADD, DELETE, and UPDATE that will be called by the DataTables Editable plug-in. In this article, you can find detailed instructions about the implementation of these data management functionalities.

Background

This article will explain how you can convert plain tables into fully functional tables with data management functionalities. I will show you how you can implement the following:

  1. Enabling user to edit cells using a table inline editor
  2. Deleting rows
  3. Adding new records in the table

These functionalities will be added directly on the client side using jQuery. The jQuery plug-in that enables these functionalities will handle the complete interaction with the user and send AJAX requests to the server-side. The advantage of this approach is that the jQuery plug-in is server-side platform independent, i.e., it can be applied regardless of what J2EE technology you are using (servlets, JSP, JSF, Struts, etc.). The only thing that is important is that your server-side component produces a valid HTML table as the one shown in the following example:

HTML
<table id="myDataTable">
   <thead>
       <tr>
           <th>ID</th><th>Column 1</th><th>Column 2</th><th>Column 3</th>
       </tr>
   </thead>
   <tbody> 
       <tr>
           <td>1</td><td>a</td><td>b</td><td>c</td>
       </tr>
       <tr>
           <td>2</td><td>e</td><td>f</td><td>g</td>
       </tr>
   </tbody>
</table>

If you generate that kind of HTML table on the server-side and send it to the client-side, you can decorate it with the jQuery DataTable and jQuery DataTable Editable plug-ins using the following line of code:

JavaScript
$("myDataTable").dataTable().makeEditable();

This call will add filtering, ordering, and pagination to your table (this will be done by the .dataTables() call), and on top of these functionalities will be added features that enable the user to add, edit, and delete records in the table. The DataTables Editable plug-in will handle all client side interaction and send AJAX requests to the server side depending on the user action. An example of an AJAX call sent to the server-side is shown in the following figure:

J2EE-Editable-Web-Table/jquery-java-editable-xhr.png

In the figure, you can see that CompanyAjaxDataSource is called when information should be reloaded into the table (e.g., when the current page or sort order is changed). UpdateData is called when a cell is edited, DeleteData is called when a row is deleted, and AddData is called when a new record is added. You can also see the parameters that are sent to the server-side when the UpdateData AJAX call is performed. To integrate the plug-in with the server-side code, you will need to create three servlets that will handle add, delete, and update AJAX calls. Examples of the servlets that can handle these AJAX requests are shown in the following listing:

Java
@WebServlet("/AddData")
public class AddData extends HttpServlet {
    protected void doPost(HttpServletRequest request, 
      HttpServletResponse response) throws ServletException, IOException {    }
}

@WebServlet("/DeleteData")
public class DeleteData extends HttpServlet {
    protected void doPost(HttpServletRequest request, 
      HttpServletResponse response) throws ServletException, IOException {    }
}

@WebServlet("/UpdateData")
public class UpdateData extends HttpServlet {
    protected void doPost(HttpServletRequest request, 
      HttpServletResponse response) throws ServletException, IOException {    }
}

You will need to implement these classes/methods in order to make the DataTables Editable plug-in functional. The following sections will describe in detail what should be done to implement each of these features.

Using the Code

The starting point is to create a J2EE application that generates a plain HTML table. This example will use a simple JSP page that generates a list of companies in an HTML table. Then, you will need to apply the DataTables plug-in to this table to enable adding basic data table enhancements. This is the second article in the group that describes how you can use jQuery DataTables to enhance your J2EE applications, and it will not explain how you can add the basic DataTables functionalities. The focus of this article will be on the data management functionalities only. If you have not read the previous article, jQuery Data Tables and J2EE applications integration, I will recommend that you read that article first because it explains how you can integrate the DataTables plug-in with a J2EE application. This article will assume that the code for the integration of the jQuery DataTables plug-in is implemented, and only the code required for integration of the DataTables Editable plug-in will be explained here.

This section explains the implementation of the following features:

  1. Displaying data in a table including some changes that should be made in the DataTables integration
  2. Editing cells using the inline jEditable plug-in
  3. Deleting table rows
  4. Adding new records to the table

The following sections explain how to implement these features.

Setup

As described above, the prerequisite for this code is that you integrate the jQuery DataTable plug-in into the Java application. You can find detailed instructions here: JQuery Data Tables in Java Web Applications, but I will include a short description in this article.

Also, in this article, I will describe the major difference between the standard DataTables integration and integration with DataTables in CRUD mode. If you want to update and delete rows, you need to have some information that tells the plug-in what is the ID of a row. This ID will be sent to the server-side so it can be determined what record should be updated/deleted.

The jQuery DataTables plug-in works in two major modes:

  1. Client-side processing mode, where all information in the table is placed in the <TBODY> of the table, and in this case, all processing is done in the JavaScript code in the browser. This is a faster mode but it might cause performance problems if you have a lot of records in the table.
  2. Server-side processing mode, where you will need to implement all the functionalities on the server-side, and the jQuery DataTables plug-in will provide the user interface and send AJAX requests to the server. Use this mode if you want to send just a minimal set of data to the browser.

In the client-side processing mode, the table is generated on the server side (in some JSP page) and the ID of each record should be placed as the ID attribute of the <TR> element. Part of the JSP code that generates this table is shown in the example below:

HTML
<table id="companies">
   <thead>
       <tr>
       <th>Company name</th>
       <th>Address</th>
       <th>Town</th>
       </tr>
   </thead>
   <tbody>
      <% for(Company c: DataRepository.GetCompanies()){ %>
    <tr id="<%=c.getId()%>">
        <td><%=c.getName()%></td>
        <td><%=c.getAddress()%></td>
        <td><%=c.getTown()%></td>
    </tr>
      <% } %>
    </tbody>
</table>

Each time the user edits or deletes some row/cell, the plug-in will take this attribute and send it as an ID.

In the server-side processing mode, only a plain table template is returned as HTML, and it is dynamically populated via an AJAX call when the page is loaded. An example of the plain table template is shown in the following listing:

HTML
<table id="companies">
    <thead>
        <tr>
            <th>ID</th>
            <th>Company name</th>
            <th>Address</th>
            <th>Town</th>
        </tr>
    </thead>
    <tbody>
    </tbody>
</table>

In this case, nothing is generated in the body of the table and the row will be dynamically loaded by the DataTables plug-in. In this case, the ID of the record is placed in the first column (this column is usually hidden in the DataTables configuration). In the code example that can be downloaded in this article, you can find a table integrated in the server-side processing mode.

For more details about integrating DataTables with a Java web application, see the JQuery Data Tables in Java Web Applications article.

Editing Cells

Cell content is edited using the jEditable inline editor, and validation is implemented using the jQuery validation plug-in. Therefore, these scripts should be included in the head section of the HTML page where the editable data table plug-in is used.

The example above shows how data table/editable plug-ins are applied to the table without parameters. In the default mode, each cell in the table is replaced with a text box that can be used for editing. When the user finishes editing, an AJAX request is sent to the server.

Editors applied on the columns can be customized. The following example shows how you can change the URL of the server-side page that will be called when a cell is updated and how you can use different editors in different columns.

JavaScript
$('#myDataTable').dataTable().makeEditable({
    "sUpdateURL": "/Company/UpdateCompanyData"
    "aoColumns": [
    {
        //Empty object is used for the default editable settings
    },
    null,//null for read-only columns
    {
        indicator: 'Saving...',
        tooltip: 'Click to select town',
        loadtext: 'loading...',
        type: 'select',
        onblur: 'submit',
        data: "{'London':'London','Liverpool':'Liverpool','Portsmouth':
              'Portsmouth','Edinburgh':'Edinburgh', 'Blackburn':'Blackburn',
              'Kent':'Kent','Essex':'Essex','Oxon':'Oxon','Lothian':'Lothian',
              'West Sussex':'West Sussex','Lanarkshire':'Lanarkshire',
              'Birmingham':'Birmingham','East Sussex':'East Sussex','Surrey':'Surrey'}"
    }
  ]
});

Each of the elements of the aoColumns array defines an editor that will be used in one of the table columns. In the example above, an empty object is set to the first column, null to the second (to make the second column read-only), and the third column uses a select list for editing.

Regardless of what configuration you use, the DataTables Editable plug-in will send the same format of AJAX request to the server-side. The AJAX request sends the following information:

  1. id of the row taken from the ID attribute of the <tr> tag that surrounds the cell that has been edited. Use this value to find a record that should be updated.
  2. value that is entered in the cell. This value should be written in the company record.
  3. columnName - name of the column (e.g., text found in the column heading). You can use this information to determine which property should be updated.
  4. rowId from the table. If 10 rows are shown per page, this will be a value between 0 and 9.
  5. columnPosition - position of the column value from 0 to the number of columns you see in the table - 1. Hidden columns are not counted. This value can be used instead of the column name to identify the property that should be updated. Use this value if names of the columns can be dynamically changed.
  6. columnId - ID of the column from 0 to the total number of columns - 1. Hidden columns are counted. This value can be used instead of the column name to identify the property that should be updated. You should use columnId instead of columnPosition if you have hidden columns in the table (either initially hidden or dynamically hidden).

You will also need a servlet that will accept the request described above, receive information sent from the plug-in, update the actual data, and return a response. Servlet code that is used in this example is shown here:

Java
protected void doPost(HttpServletRequest request, 
          HttpServletResponse response) 
          throws ServletException, IOException {
    int id = Integer.parseInt(request.getParameter("id"));
    //int columnId = Integer.parseInt(request.getParameter("columnId"));
    int columnPosition = Integer.parseInt(request.getParameter("columnPosition"));
    //int rowId = Integer.parseInt(request.getParameter("rowId"));
    String value = request.getParameter("value");
    //String columnName = request.getParameter("columnName");
    
    for(Company company: DataRepository.GetCompanies())
    {
        if(company.getId()==id)
        {
            switch (columnPosition)
            {
                case 0:
                    company.setName(value);
                    break;
                case 1:
                    company.setAddress(value);
                    break;
                case 2:
                    company.setTown(value);
                    break;
                default:
                    break;
            }
            response.getWriter().print(value);
            return;
        }
    }
    response.getWriter().print("Error - company cannot be found");
}

The servlet reads the ID of the record that should be updated, a column that will determine the property of the object that will be updated, and a value that should be set. If nothing is returned, the plug-in will assume that the record was successfully updated on the server-side. Any other message that is returned will be shown as an error message and the updated cell will be reverted to the original value.

Deleting Rows

The DataTables Editable plug-in enables users to select and delete rows in a table. The first thing you need to do is to place a plain HTML button that will be used for deleting rows somewhere in the form. An example of this button is shown in the following listing:

HTML
<button id="btnDeleteRow">Delete selected company</button>

The only thing that is required is to set the ID of the button to the value btnDeleteRow (this ID is used by the DataTables Editable plug-in to add delete handlers to the button). The DataTables Editable plug-in will disable the button initially and when the user selects a row in the table, the button will be enabled again. If a row is unselected, the button will be disabled. If the delete button is pressed while a row is selected, the DataTables Editable plug-in will take the ID of the selected row and send an AJAX request to the server side. The AJAX request has a single parameter, the ID of the record that should be deleted, as shown in the following figure:

J2EE-Editable-Web-Table/editable-datatable-java-delete-xhr.png

The servlet that handles this delete request is shown in the following listing:

Java
protected void doGet(HttpServletRequest request, 
          HttpServletResponse response) 
          throws ServletException, IOException {

    int id = Integer.parseInt(request.getParameter("id"));
    for(Company c: DataRepository.GetCompanies())
    {
        if(c.getId()==id)
        {
            DataRepository.GetCompanies().remove(c);
            return;
        }
    }
    response.getWriter().print("Company cannot be found");
}

This servlet takes the ID of the record that should be deleted and removes it from the collection. If nothing is returned, the DataTables Editable plug-in will assume that the delete was successful and the selected row will be removed from the table. Any text that is returned by the servlet will be recognized as an error message, shown to the user, and the delete action will be aborted.

The DataTables Editable initialization call that is used in the example above does not need to have any parameters. However, if you want, you can customize the behavior of the delete functionality as shown in the following example:

JavaScript
$('#myDataTable').dataTable().makeEditable({
                    sDeleteHttpMethod: "GET",
                    sDeleteURL: "/Company/DeleteCompany",
                    sDeleteRowButtonId: "btnDeleteCompany",
                });

This call sets the HTTP method that will be used for the AJAX delete call (e.g., "POST", "GET", "DELETE"), the URL that will be called, and the ID of the button that should be used for delete (this is useful if you do not want to put a default ID for the delete button or if you have two delete buttons for two tables on the same page, as in the example on the live demo site).

Adding Records

To enable adding new records, you will need to add a few items on the client side. In the DataTables Editable plug-in, new rows are added using a custom dialog that you will need to define. This dialog is shown in the following figure:

J2EE-Editable-Web-Table/editable-datatable-java-addnew.png

The form for adding new records will always be custom because it will depend on the fields you want to enter while you are adding, the type of elements you want to use for entering data (text boxes, select lists, check boxes, etc.), the required fields, and design. Therefore I have left it to you to define what form should be used for adding new records. However, it is not a complex task because the only things you would need to add are plain HTML buttons for adding new records, and a plain empty form that will be used as the template for adding new records. An example of plain HTML elements that are added in this example is shown in the following listing:

HTML
<button id="btnAddNewRow">Add new company...</button>
<form id="formAddNewRow" action="#" title="Add new company">
        <input type="hidden" id="id" name="id" value="-1" rel="0" />
        <label for="name">Name</label><input type="text" 
               name="name" id="name" class="required" rel="1" />
        <br />
        <label for="name">Address</label>
          <input type="text" name="address" id="address" rel="2" />
        <br />
        <label for="name">Postcode</label>
          <input type="text" name="postcode" id="postcode"/>
        <br />
        <label for="name">Town</label>
          <input type="text" name="town" id="town" rel="3"/>
                <br />
        <label for="name">Country</label>
        <select name="country" id="country">
                <option value="1">Serbia</option>
                <option value="2">France</option>
                <option value="3">Italy</option>
        </select>  
        <br />
    <button id="btnAddNewRowOk">Add</button>
    <button id="btnAddNewRowCancel">Cancel</button>
</form>

Similar to the delete functionality, there should be placed a button that will be used for adding new records - this button should have the ID "btnAddNewRow". The form for adding new records should have the ID "formAddNewRow" and should have OK and Cancel buttons with IDs "btnAddNewRowOk" and "btnAddNewRowCancel". The DataTables Editable plug-in will find the add new row button by ID, attach the event handler for opening the form in the dialog, and attach event handlers for submitting and canceling adding new records to the OK and Cancel buttons. You can place any input field in the form - all values that are entered in the form will be posted to the server. The AJAX call that will be sent to the server-side is shown in the figure below:

J2EE-Editable-Web-Table/editable-datatable-java-addnew-xhr.png

You can see that all values of the input fields are sent to the server-side. On the server side, you need to have a servlet that handles this AJAX call and adds a new record. The code for the servlet method that handles the AJAX call is shown in the following listing:

Java
protected void doPost(HttpServletRequest request, 
          HttpServletResponse response) 
          throws ServletException, IOException {
    String name = request.getParameter("name");
    String address = request.getParameter("address");
    String town = request.getParameter("town");
    int country = Integer.parseInt(request.getParameter("country"));
    
    Company c = new Company(name, address, town, country);
    DataRepository.GetCompanies().add(c);
    
    response.getWriter().print(c.getId());
}

This code takes parameters sent in the AJAX call, and creates and adds a new company record. The method must return the ID of the new record because the plug-in will set this value as the ID of the added row in the table.

When the AJAX call is finished, the DataTables Editable plug-in adds a new row to the table. Values that are added in the table columns are mapped using the rel attributes in the form elements. You can see that the elements id, Name, Address, and Town have rel attributes 0, 1, 2, and 3 - these values will be used to map the new record to the columns in the table.

Similar to the previous cases, adding a behavior can be configured via parameters passed to the makeEditable() function. An example is shown in the following listing:

JavaScript
$('#myDataTable').dataTable().makeEditable({
                    sAddNewRowFormId: "formAddNewCompany",
                    sAddNewRowButtonId: "btnAddNewCompany",
                    sAddNewRowOkButtonId: "btnAddNewCompanyOk",
                    sAddNewRowCancelButtonId: "btnAddNewCompanyCancel",
                    sAddURL: "/Company/AddNewCompany",
                    sAddHttpMethod: "POST",
                });

In this example, we change the default IDs of the form for adding a new record, the Add button, OK/Cancel buttons used in the add new record pop-up, URL that will be called when a new row should be added, and the HTTP method that should be used in the AJAX call.

Conclusion

This article described how you can create a fully featured client side web table that enables the client to perform all important data management actions (creating new records, deleting records, editing cells inline, etc.). You can integrate this client-side code with a Java web application that will accept AJAX calls from the client side.

I believe that this article can help you create effective user interfaces using jQuery plug-ins.

History

  • 10th Apr 2012: Initial version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)