JTable 作为 HTML <select> 元素





5.00/5 (4投票s)
使用 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
};
- keyField:主类中 id 字段的名称,即使用 jTable 作为 HTML select 的类(例如:Student.java 的 city_id)。此字段隐藏。
- displayField:存储要在主类中显示的值的字段的名称(例如:Student.java 的 city_name)。
- idField:子类中 id 字段的名称,即需要为该类创建和显示 jTable 的类(例如:City.java 的 id)。
- nameField:存储要在子类中显示的值的字段的名称(例如:City.java 的 name)。
- 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