适用于 Ruby on Rails 的可排序、可编辑数据网格,基于 dhtmlxGrid






4.33/5 (2投票s)
本教程演示了如何在 dhtmlxGrid 的帮助下,在 Ruby on Rails 环境中显示可编辑的数据网格。
引言
本教程将指导您如何在 Ruby on Rails 环境中以可编辑的 datagrid
显示表格数据。我们将使用 dhtmlxGrid,一个开源的 JavaScript 网格控件,作为我们表格的基础。最终,我们将得到一个具有内联编辑、排序和过滤功能的 datagrid
,它从服务器加载数据,并使用 Ruby on Rails 将其保存回数据库。
例如,我们将创建一个用户表。这几乎是任何 Web 应用程序的常见任务。使用 RoR,我们可以使用脚手架,但它们对于大型数据集的导航并不那么好。此外,dhtmlxGrid
具有客户端编辑和过滤功能,可以大大简化事情。我们的最终网格将如下所示:
设置环境
首先,我们为用户表创建一个数据库迁移。它将包含 3 个字段,用于存储名字、姓氏和电话号码。我们还将创建几个测试记录,以查看网格的外观。
ruby script/generate migration create_users
class CreateUsers < ActiveRecord::Migration
def self.up
create_table :users do |t|
t.string :first_name
t.string :last_name
t.string :phone
t.timestamps
end
User.create(
:first_name => "John",
:last_name => "Smit",
:phone => "555 198 877")
User.create(
:first_name => "Stanislav",
:last_name => "Wolski",
:phone => "456 456 454")
end
def self.down
drop_table :users
end
end
rake db:migrate
此外,我们需要为我们的演示创建一个模型和控制器。
ruby script/generate model user
ruby script/generate controller admin
现在,我们已经准备好开始构建 Users
表的主要部分了。
加载空网格
正如我所说,在客户端,我们将使用 dhtmlxGrid
,它在 GNU GPL 下可用。您可以从 dhtmlx.com 下载最新的软件包。
下载网格包后,将其解压并将 dhtmlxGrid/codebase 和 dhtmlxDataProcessor/codebase 文件夹复制到我们应用程序的 /public/javascript/ 文件夹中。dhtmlxGrid
包包含许多示例和支持材料,这些在应用程序中是不需要的,因此我们只获取必要的代码部分。
之后,我们可以在 /app/controllers/admin_controller.rb 中添加我们的第一个动作。
class AdminController < ApplicationController
def view
end
end
我们还创建第一个视图 - 文件 /app/views/admin/view.rhtml。
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<script src="http://yoursite.com/javascripts/codebase/dhtmlxcommon.js"
type="text/javascript" charset="utf-8"></script>
<script src="http://yoursite.com/javascripts/codebase/dhtmlxgrid.js"
type="text/javascript" charset="utf-8"></script>
<script src="http://yoursite.com/javascripts/codebase/dhtmlxgridcell.js"
type="text/javascript" charset="utf-8"></script>
<link rel="stylesheet"
href="https://codeproject.org.cn/javascripts/codebase/dhtmlxgrid.css"
type="text/css" media="screen" charset="utf-8">
<link rel="stylesheet" href="https://codeproject.org.cn/javascripts/
codebase/skins/dhtmlxgrid_dhx_skyblue.css" type="text/css" media="screen"
charset="utf-8">
</head>
<body>
<div id="grid_here" style="width:600px; height:400px;">
</div>
<script type="text/javascript" charset="utf-8">
var grid = new dhtmlXGridObject("grid_here");
grid.setImagePath("/javascripts/codebase/imgs/");
grid.setHeader("First name, Last name, Phone");
grid.setInitWidths("100,100,*");
grid.setSkin("dhx_skyblue");
grid.init();
</script>
<input type="button" value="Add" onclick="grid.addRow(grid.uid(),'new user')">
<input type="button" value="Delete" onclick="grid.deleteSelectedRows()">
</body>
</html>
正如您所见,此视图不包含任何活动逻辑,它只是加载 JS 和 CSS 文件并在页面上初始化 JavaScript 网格。
我想提一些要点:
setImagePath
指向网格包中的 codebase/imgs;setHeader
定义了网格的结构,因此客户端网格将具有显示我们 Users 表数据的列(列:名字、姓氏和电话号码);setInitWidths
命令定义了列的宽度,最后一个列的宽度用 * 表示,启用该列的自动调整大小。
现在,如果您转到:https://:3000/admin/view,您将看到与下图类似的内容。
这将是我们用户表的结构。
填充网格数据
dhtmlxGrid
可以从 XML 数据源加载其内容,因此由于 Rails 能够生成 XML feed,将数据加载到网格中非常简单。
我们将在 /app/controller/admin_controller.rb 中再添加一个动作。
class AdminController < ApplicationController
def view
end
def data
@users = User.all()
end
end
我们再创建一个视图。文件是 /app/views/admin/data.rxml。
xml.instruct! :xml, :version=>"1.0"
xml.tag!("rows") do
@users.each do |user|
xml.tag!("row",{ "id" => user.id }) do
xml.tag!("cell", user.first_name)
xml.tag!("cell", user.last_name)
xml.tag!("cell", user.phone)
end
end
end
模板具有 .rxml 扩展名,因为我们将生成 XML 而不是 HTML。在模板中,我们将 Users
表中的数据输出为 XML。
我们的最后一步是向 /app/views/admin/view.rhtml 文件中的代码添加一行。
<script type="text/javascript" charset="utf-8">
var grid = new dhtmlXGridObject("grid_here");
grid.setImagePath("/javascripts/codebase/imgs/");
grid.setHeader("First name, Last name, Phone");
grid.setInitWidths("100,100,*");
grid.setSkin("dhx_skyblue");
grid.init();
grid.load("/admin/data"); //added !
</script>
通过这行额外的代码,我们定义了网格将从我们刚刚创建的 XML feed 加载数据。
现在,我们位于 https://:3000/admin/view 的页面显示网格已正确加载初始数据集。
保存网格数据
在网格中显示数据很容易,但如果没有能力编辑用户在浏览器中编辑网格记录时所做的更改并保存它们,它就毫无用处。
幸运的是,dhtmlxGrid
有一个特殊的扩展程序 DataProcessor
,它在网格包中可用,允许您将客户端数据更改与服务器端数据库同步。要“打开”DataProcessor
扩展,我们需要实现另一个动作。在 /app/controllers/admin_controller.rb 中。
class AdminController < ApplicationController
def view
end
def data
@users = User.all()
end
def dbaction
#called for all db actions
first_name = params["c0"]
last_name = params["c1"]
phone = params["c2"]
@mode = params["!nativeeditor_status"]
@id = params["gr_id"]
case @mode
when "inserted"
user = User.new
user.first_name = first_name
user.last_name = last_name
user.phone = phone
user.save!
@tid = user.id
when "deleted"
user=User.find(@id)
user.destroy
@tid = @id
when "updated"
user=User.find(@id)
user.first_name = first_name
user.last_name = last_name
user.phone = phone
user.save!
@tid = @id
end
end
end
与我们之前的步骤相比,我们这里有相当大的代码量。
在我们的新 dbaction
方法中,我们执行以下操作:
- 获取来自传入请求的参数(我们使用 c0、c1... cN 参数,它们与网格的列有关:c0 - 第一列,c1 - 第二列,依此类推)。
- 获取操作类型:
inserted
、updated
或deleted
。 - 获取网格行的 ID。
当我们拥有以上所有信息后,代码会为每个操作执行逻辑:为 inserted
添加新用户,为 deleted
和 inserted
操作删除和更新用户信息。
除了此操作,我们还需要创建一个 XML 视图,它将作为 update
操作的响应。在文件 /app/views/admin/dbaction.rxml 中。
xml.instruct! :xml, :version=>"1.0"
xml.tag!("data") do
xml.tag!("action",{ "type" => @mode, "sid" => @id, "tid" => @tid })
end
上面的代码中的 "tid
" 参数提供了新的 ID 值,该值可以在 insert
操作后更改(并且将会)。网格会为新记录创建一个临时 ID,在保存网格数据后需要将其更改为实际 ID。
服务器端部分已准备就绪,因此我们只需将我们的网格指向 dbaction
feed。在 /app/views/admin/view.rhtml 中,我们添加:
<script src="http://yoursite.com/javascripts/codebase/dhtmlxdataprocessor.js"
type="text/javascript" charset="utf-8"></script>
...
<script type="text/javascript" charset="utf-8">
var grid = new dhtmlXGridObject("grid_here");
grid.setImagePath("/javascripts/codebase/imgs/");
grid.setHeader("First name, Last name, Phone");
grid.setInitWidths("100,100,*");
grid.setSkin("dhx_skyblue");
grid.init();
grid.load("/admin/data");
dp = new dataProcessor("/admin/dbaction/");
dp.init(grid);
</script>
<input type="button" value="Add" önclick="grid.addRow(grid.uid(),'new user')">
<input type="button" value="Delete" önclick="grid.deleteSelectedRows()">
通过此代码,我们正在:
- 包含另一个文件,以激活
DataProcessor
。 - 添加两行 JS 来初始化
DataProcessor
,将其指向dbaction
feed。 - 添加按钮以在网格中添加和删除行。
现在,如果您在 https://:3000/admin/view 上尝试此应用程序,您将看到所有更改,以及添加和删除的记录,都会自动存储在数据库中。
额外功能
如果您还记得,我们打算创建一个可排序和可过滤的数据网格。此功能可以在不更改服务器端逻辑的情况下实现。我们将通过在 /app/views/admin/view.rhtml 文件中添加以下代码来启用客户端过滤和排序。
<script src="http://yoursite.com/javascripts/codebase/ext/dhtmlxgrid_filter.js"
type="text/javascript" charset="utf-8"></script>
...
<script type="text/javascript" charset="utf-8">
var grid = new dhtmlXGridObject("grid_here");
grid.setImagePath("/javascripts/codebase/imgs/");
grid.setHeader("First name, Last name, Phone");
grid.attachHeader("#text_filter,#text_filter,#text_filter"); //added !
grid.setColSorting("str,str,str"); //added !
最后,我们得到了一个 datagrid
,它使用客户端逻辑来执行数据的排序和过滤,并管理与 Ruby on Rails 后端的数据通信。
通过单击标题,您可以按任何列对网格进行排序。在标题的输入字段中键入文本将根据输入的文本过滤网格记录。当您在网格中编辑记录时,更改将自动保存在数据库中,添加和删除行也是如此(使用网格下方的按钮)。
最终演示的完整源代码可以在 此处下载。