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

JTable as HTML <select> element

5.00/5 (4 votes)
19 Jul 2016CPOL5 min read 16K  
Using jTable instead of drop-down list.

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.

Image 1

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.

Image 2

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.

JavaScript
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.

JavaScript
$.extend(true, $.hik.jtable.prototype, {
   _create : function () {
      var self = this;
      // This will call the original method in jTable.
      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.

JavaScript
self.options.base.formCreated = self.options.formCreated;
self.options.formCreated = function (event, data) {
   self.options.base.formCreated.apply(self, arguments);
   popUpSetup.apply(self, arguments); //popUp logic is called.

Pop-up setup

Pop-up options needs to be defined as follows:

JavaScript
StudentJTable.fields.city_name.popUpOpts = {
   keyField : 'city_id',
   displayField : 'city_name',
   idField : 'id',
   nameField : 'name',
   selectionTable : CityJTable
};
  1. 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.
  2. displayField: name of the field that stores the value to be displayed in main class (Example: city_name of Student.java).
  3. 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).
  4. nameField: name of the field that stores the value to be displayed in subclass class (Example: name of City.java).
  5. 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.

JavaScript
function getFieldContainerMap($form) {
   // Obtaining hashmap
   var map = {};
   // finding fields from the form using the jTable classes defined to create the field.
   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.

JavaScript
function popUpSetup(event, data) {
// Similar to layoutSetup.
   var self = this;
   var $form = data.form;
   var formType = data.formType;
   var fieldContainerMap = getFieldContainerMap($form);
   $.each(fieldContainerMap, function (fieldName, $field) {
   // Checking if popUp widget is called for any of the fields.
   // If it is, then calling the popUp widget by passing the required parameters.
      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.

JavaScript
$.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'
      });
      // On clicking the field a function is called to open the popUp.
      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.

JavaScript
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.

JavaScript
fieldSelected : function ($div) {
   var self = this;
   var popUpOpts = self.options.popUpOpts;
   var $selectedRows = $div.jtable('selectedRows');
          // The data of the selected row can be stored in the form field.
          // Example: If city Mumbai is selected then value of city_id and name are stored in city_id and city_name
          // variables of Student class.
   if ($selectedRows.length > 0) {
      $selectedRows.each(function () {
         var record = $(this).data('record');
         // Obtaining and storing the name and id field.
         $(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

License

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