Introduction 

In this article will be explained how you can implement data management functionalities in the web tables using the J2EE applications. In the following example is shown web table that enables user to edit cells using an inline editor.

editable-datatable-java-intro.png

You can see a lot of functionalities 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 add new ones). 

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

$("myTable").dataTable();

In this example "myTable" is an id of the HTML table that will be enhanced using a DataTable plugin. Only requirement is to have a valid HTML table in the source of the web page.

Goal of this article is to show how you can add additional functionalites using the JQuery DataTables Editable plugin. Using this plugin you can add inline editing, deleting rows, and adding new records using the following code: 

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

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

Background

In this article will be explained how you can convert plain tables into the fully functional tables with complete data management functionalites. I will show you how you can implement following functionalites:

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

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

   <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 JQuery DataTable and JQuery DataTable Editable plugins using the following line of code:  

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

This call will add filtering, ordering and pagination to your table (this will be done by the .dataTables() call), and on the top of these functionalities will be added features that enables user to add, edit, and delete records in the table.  DataTables editable plugin will handle all client side interaction and send Ajax request to the server side depending on the user action. Example of the Ajax calls sent to the server-side are shown in the following figure:

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 current page or sort order is changed), UpdateData is called when some cell is edited, DeleteData is called when some row is deleted, and AddData is called when new record is added. You can also see parameters that are sent to the server-side when UpdateData Ajax call is performed. To integrate plugin 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:

@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 dataTables editable plugin functional. In the following sections will be described in details what should be done to implement each of these features.  

Using the code 

Starting point is to create J2EE application that generates a plain HTML table. In this example will be used simple JSP page that generates list of companies in the HTML table. Then, you will need to apply dataTables plugin to this table to enable to add basic data table enhancements. This is a second article in the group that describes how you can use JQuery DataTables to enhance your J2EE applications and here will not be explained how you can add basic DataTables functionalities. Focus of this article will be on the data management functionalities only. If you have not read previous article jQuery Data Tables and J2EE applications integration I will recommend that you read this article first because there is explained how you can integrate DataTables plugin with J2EE application. In this article I will assume that the code for integration of JQuery DataTables plugin is implemented and only code required or integration of DataTables Editable plugin will be explained here.  

In this section will be explained implementation of the following features:

  1. Displaying data in the table including some changes that should be made in the DataTables integration,
  2. Editing cells using inline JEditable plugin,  
  3. Deleting table rows,  
  4. Adding new records to the table. 
In the following sections are explained how to implement these features.

Setup  

As described above prerequisite for this code is that you integrate JQuery DataTable plugin into the java application. You can find detailed instructions here jQuery Data Tables and J2EE applications integration but I will put short description in this article.

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

JQuery DataTables plugin works in two major modes:

  1. Client-side processing mode where all information in the table are placed in the <TBODY> of the table and in this case all processing is done in JavaScript code in the browser. This is faster mode but it might cause performance problem if you have lot of records in the table.
  2. Server-side processing mode where you will need to implement all functionalities on the server-side, and JQuery DataTables plugin will provide user interface and send Ajax request 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, table is generated on the server side (in some JSP page) and id of the each record should be placed as an id attribute of <TR> element. Part of JSP code that generates this table is shown in the example below:
<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 user edit or delete some row/cell, plugin will take this attribute and send it as an id.

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

<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 row will be dynamically loaded by the DataTables plugin. In this case id of the record is placed in the first column (this column is usually hidden in DataTables configuration). In the code example that can be downloaded in this article you can find a table integrated in server-side processing mode.

For more details about integrating DataTable with Java web application see jQuery Data Tables and J2EE applications integration 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 editable data table plugin is used.

In the example above is shown how data table/editable plugins are applied to the table without parameters. In this default mode each cell in the table is replaced with text box that can be used for editing. When user finishes with editing, Ajax request is sent to the server.

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

$('#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 define editor that will be used is one of the table columns. In the example above, empty object is set to the first column, null to the second (to make the second column read-only), and in third column uses select list for editing.

Regardless what configuration you used, dataTables editable plugin will send same format of the Ajax request to the server-side. In the Ajax request are sent 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 actual data, and return response. Example of the servlet code that is used in this example is:

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

Servlet reads id of the record that should be updated, column that will determine property of the object that will be updated and value that should be set. If nothing is returned, plugin will assume that record is successfully updated on the server-side. Any other message that is returned will be shown as an error message and updated cell will be reverted to the original value. 

Deleting rows 

DataTables Editable plugin enables user to select and delete rows in the table. First thing you need to do is to place plain HTML button that will be used for deleting rows somewhere in the form. Example of this button is shown in the following listing:

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

Only thing that is required is to set id of the button to the value "btnDeleteRow" (this id is used by the DataTable Editable plugin to add delete handlers to the button). DataTables Editable plugin will disable button initially and when user select any row in the table button will be enabled again. If row is unselected, button will be disabled again. If delete button is pressed while row is selected, DataTables Editable plugin will take id of the selected row and send Ajax request to the server side. Ajax request has a singe parameter id containing the id of the record that should be deleted as shown in the following figure:

editable-datatable-java-delete-xhr.png

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

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 id of the record that should be deleted and removes it from the collection. If nothing is returned DataTables editable plugin will assume that delete is successful and 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 delete action will be aborted.

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

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

In this call is set HTTP method that will be used for the Ajax delete call (e.g. "POST", "GET", "DELETE"), URL that will be called and id of the button that should be used for delete (this is useful if you do not want to put 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 few items on the client side. In the DataTables Editable plugin new rows are added using a custom dialog that you will need to define. This dialog is shown in the following figure:

editable-datatable-java-addnew.png

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

<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 one button that will be used for adding new records - this button should have id "btnAddNewRow". Form for adding new records should have id "formAddNewRow" and should have Ok and Cancel buttons with ids "btnAddNewRowOk" and "btnAddNewRowCancel". DataTables Editable plugin will find add new row button by id, attach event handler for opening 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 fields in the form - all values that are entered in the form will be posted to the server. Ajax call that will be sent to the server-side is shown in the figure below:

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 add a new record. Code of the servlet method that handles Ajax call is shown in the following listing:

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, creates and add new company record. Method must return id of the new record because plugin will set this value as a id of the added row in the table.

When Ajax call is finished DataTables Editable plugin 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 elements id, Name, Address, and Town have rel attributes 0, 1, 2, and 3 - these values will be used to map new record to the columns in the table.

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

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

In this example are changed default ids of the form for adding new record, add button, ok/cancel buttons used in add new record pop-up, URL that will be called when new row should be added, and HTTP method that should be used in the Ajax call. 

Conclusion  

In this article is described how you can create fully featured client side web table that enables 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 Java web application that will accept Ajax calls from the client side. 

I believe that you this article can help you to create effective user interface using the JQuery plugins. 

 

推荐.NET配套的通用数据层ORM框架:CYQ.Data 通用数据层框架
新浪微博粉丝精灵,刷粉丝、刷评论、刷转发、企业商家微博营销必备工具"