65.9K
CodeProject 正在变化。 阅读更多。
Home

JTable 作为 HTML <select> 元素

starIconstarIconstarIconstarIconstarIcon

5.00/5 (4投票s)

2016年7月19日

CPOL

5分钟阅读

viewsIcon

16397

使用 jTable 代替下拉列表。

目录

  • 引言
  • 问题
  • 解决方案
  • 为 jTable 添加弹出功能
  • 弹出设置
  • 弹出控件
  • 模型类中的更改。

引言

本文是文章 JTable Spring Hibernate Demo (https://codeproject.org.cn/Articles/1113148/JTable-Spring-Hibernate-Demo) 和文章 Changing JTable Layout (https://codeproject.org.cn/Articles/1113206/Changing-JTable-Layout) 的延续。jTable 提供了一种创建表单以添加或编辑记录的方法。jTable 控件在提供了适当的字段并设置了它们的属性后,会创建一个表单。本文讨论将下拉菜单更改为 jTable 显示。

问题

下拉菜单是常用的表单字段之一。它允许用户从预定义选项列表中选择一个选项。当选择项数量较少时,下拉菜单易于使用。如果预定义选项数量很大,用户进行选择就会很麻烦。例如:使用下拉菜单从城市列表中选择一个城市。下拉菜单不允许用户控制如何查看列表。也没有提供对选项进行排序的选项。

解决方案

可以使用 jTable 代替下拉菜单进行选择。jTable 非常交互,并提供分页和排序等功能。这将增强用户体验。用户可以舒适地浏览每一页的选项并进行选择。用户还可以对选项进行排序,并决定每页要查看的选项数量。

下图显示了 jTable 作为选择工具。

为 jTable 添加弹出功能

整个解决方案可在 jtable_form_extension.js 中找到。jTable 是一个控件。每个控件都有 _create 函数()。为了保持 jTable 功能的完整性,jTable 的 _create 函数() 被复制到变量 base 中。

var base = {
   _create : $.hik.jtable.prototype._create,
};

然后扩展 _create 函数(),并首先调用存储在变量 base 中的原始 jTable create 函数。

$.extend(true, $.hik.jtable.prototype, {
   _create : function () {
      var self = this;
      // This will call the original method in jTable.
      base._create.apply(this, arguments);

formCreated 事件在 jTable 控件中定义。为了保持原始 jTable 功能,事件函数被存储起来。稍后,将覆盖 formCreated 函数()。在覆盖的函数中,首先调用原始 jTable 函数,然后编写其余的函数逻辑。之后调用 popUpSetup() 方法。

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.

弹出设置

弹出选项需要定义如下:

StudentJTable.fields.city_name.popUpOpts = {
   keyField : 'city_id',
   displayField : 'city_name',
   idField : 'id',
   nameField : 'name',
   selectionTable : CityJTable
};
  1. keyField:主类中 id 字段的名称,即使用 jTable 作为 HTML select 的类(例如:Student.java 的 city_id)。此字段隐藏。
  2. displayField:存储要在主类中显示的值的字段的名称(例如:Student.java 的 city_name)。
  3. idField:子类中 id 字段的名称,即需要为该类创建和显示 jTable 的类(例如:City.java 的 id)。
  4. nameField:存储要在子类中显示的值的字段的名称(例如:City.java 的 name)。
  5. selectionTable:要显示的 jTable 的定义。

扩展名为 .js 的所有文件都存储在 web/js/jTable/ 中,其中包含所需模型类的 jTable 定义。CityJTable 是存储在 city.js 中的 jTable 定义。为需要将下拉列表作为弹出窗口的表单字段提供了弹出选项。需要检查每个表单字段以查看是否为弹出控件提供了弹出选项。如果是,则应调用弹出逻辑。表单字段的外观与 jTable 表单相同。创建一个以字段名称为键,整个字段为值的哈希映射。 

jTable 中的每个表单字段都有“jtable-input-field-container”类。使用该类名的 find() 函数将返回具有该类的所有字段。在每个字段内,找到并存储输入、选择或文本区域类型的表单字段。获取字段的 name 属性,并用作哈希映射的键。将相应的字段作为键的值存储。

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 提供了 jTable 表单的表单数据。getFieldContainerMap() 返回包含名称和字段的哈希映射。遍历哈希映射以检查是否为每个字段提供了弹出选项。如果是,则存储弹出选项。$input 存储整个字段,包括用于绘制字段(如 jTable)所需的 <div> 标签和类。$keyField 是用于数据库检索和更新的 id 值。例如:Model Student 包含 City 下拉列表的 city_id。但 jTable 中只显示 city_name。此 $input 字段在控件中设置为只读。弹出控件需要将弹出选项和 key 字段作为参数传递。

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

弹出控件

创建了弹出控件。每个控件都需要 _create() 函数。调用弹出控件的元素被设置为只读。这迫使用户从预定义列表中选择一个值,而不是手动输入无效值。使用 CSS 添加指示选项的箭头。定义了 Click() 事件,以便在单击字段时,该字段的 jTable 将作为弹出窗口打开。

$.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();
      });
   },

在 openFieldJTable 中,为了使其类似于从下拉列表中选择一个元素,除了列表之外的所有操作都设置为 null。因此,不允许用户添加、删除或更新任何值。如果选择了任何字段,则调用 fieldSelected() 函数来用选定的选项填充表单字段。

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 返回选定的行。fieldSelected() 方法利用 .jtable(‘selectedRows’) 来获取它们。获得选定的行后,将选定的数据存储在变量 record 中。选定的值会更新到 Student.java 的 city_name 和 city_id 字段中。这些值以 name 和 id(City 的字段)作为键存储在 jTable 字段中。使用这些键可以访问选定记录的值,并将其存储在 city_name 和 city_id 字段的 value 属性中。这样,Student 表单就会获得选定的城市,并显示在其 City 字段中。

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

源代码

代码可在以下位置找到:  https://github.com/pujagani/JTableSpringHibernateDemo

© . All rights reserved.