Contents
- Introduction
- Problem
- Solution
- Adding pop-up functionality to jTable
- Pop-up setup
- Pop-up widget
- Change in Model classes.
Introduction
This article is a continuation of the article JTable Spring Hibernate Demo (http://www.codeproject.com/Articles/1113148/JTable-Spring-Hibernate-Demo) and article Changing JTable Layout (http://www.codeproject.com/Articles/1113206/Changing-JTable-Layout). jTable provides a way to create a form to add or edit records. jTable widget creates a form provided appropriate fields are given and their properties are set. This article discusses changing of a drop-down menu to a jTable display.
Problem
A drop-down menu is one of the commonly used form fields. It allows a user to select a single option from a predefined list of options. A drop-down is easy to use when choices are few in number. If there is large no. of predefined choices then it is tedious for the user to make a selection. Example: Selecting a city from a list of cities using a drop-down. The drop-down does not allow the user to control how to view the list. There is no provision for sorting the choices as well.
Solution
Instead of using drop-down menu for selection, jTable can be used. jTable is very interactive and provides facilities like pagination and sorting. This will enhance the user experience. User can comfortably browse through the choices on every page and make a selection. User can also sort the choices and decide no. of choices he wants to view on a single page.
Image below shows jTable as selection tool.
Adding pop-up functionality to jTable
Entire solution is available in jtable_form_extension.js. jTable is a widget. Every widget has _create function(). In order to keep the jTable functionality intact, the _create function() of jTable is copied into the variable base.
var base = {
_create : $.hik.jtable.prototype._create,
};
The _create function() is then extended and original jTable create function stored in the variable base is called first.
$.extend(true, $.hik.jtable.prototype, {
_create : function () {
var self = this;
base._create.apply(this, arguments);
formCreated event is defined in jTable widget . In order to maintain the original jTable functionality the event function is stored. Later on, the formCreated function() is overridden. In the overridden function, first the original jTable function is called and then rest of the function logic is written. popUpSetup() method is called after this.
self.options.base.formCreated = self.options.formCreated;
self.options.formCreated = function (event, data) {
self.options.base.formCreated.apply(self, arguments);
popUpSetup.apply(self, arguments);
Pop-up setup
Pop-up options needs to be defined as follows:
StudentJTable.fields.city_name.popUpOpts = {
keyField : 'city_id',
displayField : 'city_name',
idField : 'id',
nameField : 'name',
selectionTable : CityJTable
};
- keyField: name of the id field in main class i.e. the class which uses jTable as HTML select (Example: city_id of Student.java). This field is hidden.
- displayField: name of the field that stores the value to be displayed in main class (Example: city_name of Student.java).
- idField: name of the id field in subclass class i.e. the class for which jTable has to be created and displayed. (Example: id of City.java).
- nameField: name of the field that stores the value to be displayed in subclass class (Example: name of City.java).
- selectionTable: definition of the jTable to be displayed.
All files with extension .js stored in web/js/jTable/ consist of jTable definition for required model classes. CityJTable is jTable definition stored in city.js. Pop-up options are provided for the form fields that want drop-down as pop-up. Every form field needs to be checked to see if pop-up options are provided for the pop-up widget. If yes, then the pop-up logic should be invoked. The look of the form field is same as the jTable form. A hashmap is created with the name of the field as the key and the entire field as the value.
Every form field in jTable has class “jtable-input-field-container”. find() function with the class name will return all fields having that class. Within each field, form field of type input, select or textarea are found and stored. The name attribute of the field is obtained and used as key for the hashmap. The respective field is store as value for the key.
function getFieldContainerMap($form) {
var map = {};
var fields = $form.find(".jtable-input-field-container");
for (var i = 0; i < fields.length; i++) {
var $field = $(fields[i]);
var $input = $field.find("input, select, textarea");
if ($input.length > 0) {
var fieldName = $input[0].name;
map[fieldName] = $field;
}
}
return map;
}
data.form gives the form data of the jTable form. getFieldContainerMap() returns the hashmap with name and fields. Hashmap is looped through to check if pop-up options are provided for every field. If yes, then the pop-up options are stored. $input stores the entire field along with <div> tags and classes needed for painting the field like jTable. $keyField is the id value for the database retrieval and updating purposes. Ex: Model Student consists of city_id for City drop-down. But only city_name is displayed in the jTable. This $input field is made read-only in the widget. Pop-up widget requires pop-up options and key field to be passed as parameters.
function popUpSetup(event, data) {
var self = this;
var $form = data.form;
var formType = data.formType;
var fieldContainerMap = getFieldContainerMap($form);
$.each(fieldContainerMap, function (fieldName, $field) {
if (self.options.fields[fieldName].popUpOpts) {
var popUpOpts = self.options.fields[fieldName].popUpOpts;
var $input = $field.find("input");
var $keyField = $form.find('input[name=' + popUpOpts.keyField + ']');
$input.popUp({
popUpOpts : popUpOpts,
$keyField : $keyField
});
}
});
}
Pop-up widget
Pop-up widget is created. _create() function is required for every widget. The element on which pop-up widget is called is made read-only. This forces the user to select a value from a predefined list instead of manually entering invalid value. Arrow indicating that options are available is added using css. Click() event is defined such that on clicking the field jTable for that field opens up as a pop-up.
$.widget("pcj.popUp", {
_create : function () {
var self = this;
self.element.prop("readOnly", true);
self.element.css({
'background-image' : 'url(../css/img/arrow_down.png)',
'background-repeat' : 'no-repeat',
'background-position' : 'right',
'background-color' : '#EEE'
});
self.element.click(function () {
self.openFieldJTable();
});
},
In openFieldJTable to make it similar to selecting an element from a drop-down list, all actions other than list are set to null. Thus, not allowing a user to add, delete or update any value. If any field is selected then function fieldSelected() is called to populate the form field with the selected option.
openFieldJTable : function () {
var self = this;
var popUpOpts = self.options.popUpOpts;
var selectionTable = popUpOpts.selectionTable;
selectionTable.selecting = true;
selectionTable.actions.createAction = null;
selectionTable.actions.updateAction = null;
selectionTable.actions.deleteAction = null;
var $div = $('<div />').appendTo('body');
selectionTable.selectionChanged = function () {
self.fieldSelected($div);
};
$div.jtable(selectionTable);
$div.jtable('load');
$div.dialog({
minWidth : 600,
title : 'Make a selection',
position : {
my : "top",
at : "top+50",
of : window
}
});
},
jTable returns selected rows. fieldSelected() method makes use of the .jtable(‘selectedRows’) to obtain the same. Once the selected row is obtained, the selected data is stored is variable record. The selected values are updated in city_name and city_id fields of Student.java. The values are stored in field jTable using name and id (Fields of City) as key. Using these keys the values of the selected record can be accessed and stored in the value attribute of city_name and city_id fields. This way Student form gets the selected city stored and displayed in its City fields.
fieldSelected : function ($div) {
var self = this;
var popUpOpts = self.options.popUpOpts;
var $selectedRows = $div.jtable('selectedRows');
if ($selectedRows.length > 0) {
$selectedRows.each(function () {
var record = $(this).data('record');
$(self.element).val(record[popUpOpts.nameField]);
self.options.$keyField.val(record[popUpOpts.idField]);
$div.remove();
});
Source Code
Code is available at: https://github.com/pujagani/JTableSpringHibernateDemo