来源:http://trac.seagullproject.org/wiki/Plugins/DataGrid

通用的Data Grid插件

请看:source:branches/datagrid/

我们公司开发了一个Data Grid控件——我想你可能感兴趣。它很强大而且易于使用。 我们把代码移到SVN分支。

有一些关于它的文档和实例。

DataGrid类使得快速编程产生具有强大特性的列表有了可能。使用这个类应用程序中的所有DataGrid可以有一样的外观和行为,而且可容易地增加新的特性。DataGrid?是用MVC标准集成的。

Demo (实例演示)

特性

  • 按列排序
  • 按列过滤
  • 快速过滤和排序 (使用改进的 SQL 查询语句来排序和过滤,所以很快而且可靠)
  • 分页, 页面间的导航, 可以选择每页要显示的行数
  • 导出到 Excel/Word
  • 选择/取消选择所有行,并在多行上操作
  • 单行操作
  • 在添加/修改后(即刷新后)自动选定被添加/修改的行
  • 针对行/列的颜色和字体属性
  • 灵活的模板来 修改 look & style
  • 一个页面支持多个DataGrid
  • 统计列数,页数,整个列表记录数
  • 计算列平均值,页平均值,整个列表记录平均埴
  • 数据源类型: sql查询语句和程序没手工添加行
  • 列类型:
        o id: DataGrid的id, 用来惟一标识被选中的行。它可设置成不可见, 使用JavaScript选择行?
        o text: text (左对齐)
        o html: HTML (左对齐)
        o user: 程序员可自己设置列的属性(如:对刘方式,颜色等)
        o colour: 这各类型的列会用数据的颜色来着色
        o integer: 整数(右对齐)
        o real: 实数 (右对齐)
        o date: 日期字段 (右对齐)
        o hour: 时间字段 (居中对齐)
        o image: 来自文件的图片 (居中对齐)
        o thumbnail: 文件的缩略图 (居中对齐)
        o enclosure: 附件,带文件类型图标 (居中对齐)
        o mail: 用来发送e-mail的e-mail地址(左对齐)
        o action: 在这里定义基于行的数据操作 (如,编辑,删除按钮等)
  • 它不仅可以被用在动态列表也用来做报表(只需要改变 DataGrid 的模板)

Programming

  • MVC 标准
  • 3 个主要概念:
        o DataGrid主要对象: actions dispatching, 列和数据源管理
        o Column 对象(DataGrid中的每一列都被视为一个对象), 可更改列的属性,类型等。
        o DataSource 对象(基于行的): 排序,过滤和页面导航功能
  • 现成的可以使用/修改的模板: DataGrid.html 很复杂但很强大 - 你可改变 DataGrid 的look & feel。 为什么会有一个这么奇怪的函数: {getArrayValue(valueObj,column.dbName)}: 由于FLEXY 的局限(valueObjcolumn.dbName is not possible in FLEXY)

实例

简易DataGrid, 手工填充数据

<?php

      require_once SGL_LIB_DIR . '/SGL/DataGrid.php';
      require_once SGL_LIB_DIR . '/SGL/DataSource.php';
      //创建新的 dataGrid
      $dataGrid = & new SGL_DataGrid('one');
      //添加列到 dataGrid
      $col = &$dataGrid->addColumn(array(
                      'type' => 'text',
                      'name' => 'name',
                      'dbName' => 'name',
                      'filterable' => true,
                      'sortable' => true
                    ));
      $col->setTransformInColumn(array('Adamus' => 'ad'));
      $col2 = &$dataGrid->addColumn(array(
                      'type' => 'text',
                      'name' => 'surname',
                      'dbName' => 'surname',
                      'filterable' => true,
                      'sortable' => true
                    ));
      $col2->setTransformInColumn(array('Mielcarus' => 'mtest'));
      $dataGrid->addColumn(array(
                  'type' => 'text',
                  'name' => 'city',
                  'dbName' => 'city',
                  'filterable' => true,
                  'sortable' => true
                ));
      $dataGrid->addColumn(array(
                  'type' => 'integer',
                  'name' => 'age',
                  'dbName' => 'age',
                  'filterable' => true,
                  'sortable' => true,
                  'avgTotalable' => true,
                  'avgable' => true
                ));
      //创建数据源实例
      $dataSource = & new SGL_DataGridDataSource();
      //手工添加数据到数据源
      $dataSource->addRow(array
          ('name' => 'Adamus', 'surname' => 'Mielcarus', 'city' => 'Olimp', 'age' => 33));
      $dataSource->addRow(array
          ('name' => 'Grzegorzus', 'surname' => 'Dabrawus', 'city' => 'Sparta', 'age' => 21));
      $dataSource->addRow(array
          ('name' => 'Robertus', 'surname' => 'Borkowus', 'city' => 'Ateny', 'age' => 22));
      $dataSource->addRow(array
          ('name' => 'Piotrus', 'surname' => 'Skrzypus', 'city' => 'Troja', 'age' => 24));
      $dataSource->addRow(array
          ('name' => 'Tomaszus', 'surname' => 'Przybyszus', 'city' => 'Saloniki', 'age' => 25));
  
      //获取全部数据并绑定或填充到,dataGrid并显示
      $dataGrid->validate($input->inputReq);
      $dataGrid->setDataSource($dataSource);
      $dataGrid->display($output);

?>

使用SQL数据填充 DataGrid

<?php

      require_once SGL_LIB_DIR . '/SGL/DataGrid.php';
      require_once SGL_LIB_DIR . '/SGL/SQLDataSource.php';
      $dataGrid = & new SGL_DataGrid('two');
      $dataGrid->addColumn(array(
                  'type' => 'id',
                  'name' => 'id',
                  'dbName' => 'id',
                ));
      $dataGrid->addColumn(array(
                  'type' => 'text',
                  'name' => 'name',
                  'dbName' => 'name',
                  'filterable' => true,
                  'sortable' => true
                ));
      $dataGrid->addColumn(array(
                  'type' => 'text',
                  'name' => 'description',
                  'dbName' => 'description',
                  'filterable' => true,
                  'sortable' => true
                ));
      $dataGrid->addColumn(array(
                  'type' => 'real',
                  'name' => 'salary',
                  'dbName' => 'salary',
                  'filterable' => true,
                  'sortable' => true,
                  'sumable' => true,
                  'sumTotalable' => true
                ));
      $dataGrid->addColumn(array(
                  'type' => 'enclosure',
                  'name' => 'file',
                  'dbName' => 'fileattached',
                ));
      $dataGrid->addColumn(array(
                  'type' => 'image',
                  'name' => 'picture',
                  'dbName' => 'picture',
                ));
      $dataSource = & new SGL_DataGridSQLDataSource("
          SELECT id, name, description, salary, fileattached, picture
          FROM people WHERE #_FILTER#
      ", 'id');
      $dataGrid->validate($input->inputReq);
      $dataGrid->setDataSource($dataSource);
      $dataGrid->display($output);

?>

一个页面使用两个DataGrid

<?php

      require_once SGL_LIB_DIR . '/SGL/DataGrid.php';
      require_once SGL_LIB_DIR . '/SGL/SQLDataSource.php';
      $dataGrid = & new SGL_DataGrid('three');
      $dataGrid->dataGridHeader = 'Sample title';
      $dataGrid->addColumn(array(
                  'type' => 'user',
                  'name' => 'name',
                  'dbName' => 'name',
                  'filterable' => true,
                  'sortable' => true
                ));
      $dataGrid->addColumn(array(
                  'type' => 'colour',
                  'name' => 'colour column',
                  'dbName' => 'colour',
                  'filterable' => true,
                  'sortable' => true
                ));
      $dataGrid->addColumn(array(
                  'type' => 'email',
                  'name' => 'email',
                  'dbName' => 'email',
                  'filterable' => true,
                  'sortable' => true
                ));
      $dataGrid->addColumn(array(
                  'type' => 'link',
                  'name' => 'www',
                  'dbName' => 'www',
                  'filterable' => true,
                  'sortable' => true
                ));
      $dataSource = & new SGL_DataGridSQLDataSource("
          SELECT name, birthdate, colour, email, www
          FROM people WHERE #_FILTER#
          ORDER BY name
      ", 'id');
      $dataGrid->validate($input->inputReq);
      $dataGrid->setDataSource($dataSource);
      $dataGrid->display($output);
      $dataGrid2 = & new SGL_DataGrid('four');
      $dataGrid2->emptyTitle     = 'DataGrid with no data - only special title for this situation is shown';
      $dataGrid2->addColumn(array(
                  'type' => 'id',
                  'name' => 'id',
                  'dbName' => 'id'
                ));
      $col = &$dataGrid2->addColumn(array(
                  'type' => 'text',
                  'name' => 'name',
                  'dbName' => 'name',
                  'filterable' => true,
                  'sortable' => true
                ));
      $col->setFilterSelect(array('Jan', 'Andrew', 'Stephen'));
      $dataGrid2->addColumn(array(
                  'type' => 'text',
                  'name' => 'surname',
                  'dbName' => 'surname',
                  'filterable' => true,
                  'sortable' => true
                ));
      $dataGrid2->addColumn(array(
                  'type' => 'date',
                  'name' => 'birth date',
                  'dbName' => 'birthdate',
                  'filterable' => true,
                  'sortable' => true
                ));
      $dataGrid2->addColumn(array(
                  'type' => 'real',
                  'name' => 'salary',
                  'dbName' => 'salary',
                  'filterable' => true,
                  'sortable' => true,
                  'sumable' => true,
                  'sumTotalable' => true
                ));
      $dataSource2 = & new SGL_DataGridSQLDataSource("
          SELECT id, name, surname, birthdate, salary
          FROM people WHERE #_FILTER# AND 1=0
          ORDER BY id
      ", 'id');
      $dataGrid2->validate($input->inputReq);
      $dataGrid2->setDataSource($dataSource2);
      $dataGrid2->display($output);

?>

反馈信息

Hiya Krzysztof(人名)

它是关于datagrid的伟大成就,看起来比以前简洁了,我想它确实是集成了。下面是我的一些评论:

API

文件结构
  • 请把 DataGrid 和相关的放在 lib/SGL 目录里, 使用 PEAR 风格这样就可以使用命名空间:
     /lib/SGL/DataGrid.php /lib/SGL/DataGrid/Column.php /lib/SGL/DataGrid/DataSource.php ... etc
  • 为什么不用类似于数据源的API(应用程序接口)来添加一个列,比起去查询API文档以获得所有的参数信息我更喜欢直接阅读代码。
ok

<?php $dataGrid→addColumn('text', 'name', 'name', true, true); ?>

better

<?php $dataGrid→addColumn(

     array('type' => 'text', 
           'label' => 'name', 
           'fieldName' => 'name');
           // etc

?>

  • 为避免重复我想重命名 DataGrid::dataGridValidate() 为 DataGrid::validate()
  • addAction() 函数应该更新成 0.5.x 那种处理方式,我已经有一年多不使用 ?foo=bar 这样的查询字符串了。 我可不可以建议:
    <?php
    $dataGrid->addAction(
           array('label' => 'Delete', 
                 'module' => 'foo', 
                 'manager' => 'bar'),
                 'action' => 'baz'),
                 'id' => {id}),
                 'name' => {name});
                 // or something similar
    ?>

代码

  • 你使用了方法里使用了许多全局变量,seagull 里任何地方都不会这么做而且不是一个好的编程习惯,请通过参数传递,请查看 SGL_DataGridDataSource::setSort()

General

  • 我建议你看一下Seagull内置的单元测试框架,创建这么复杂的功能时,测试对代码单元来说是很有必要的。试一下吧,这样你的工作会变得容易起来 。
  • 当上述的改进完成后请把代码移到 Seagull 0.5.x

DemianTurner /27.10.2005 10:32/

变化和改进

Hi Demian,

感谢你的建议。

我们做了一些代码和API修改,像:

  • API for addAction,
  • API for addColumn, both using array('label'⇒'zzz', 'icon'⇒'a.gif') convention,
  • 把 DataGrid以及相关的类移到 lib/SGL 目录,使用 PEAR 风格命名空间
  • 删除所有的全局变量
  • 重命名 DataGrid::dataGridValidate()为DataGrid::validate(),
  • 把代码移到 Seagull 0.6.0

我们添加了新的功能, 如:

  • 对各列的总和的平均值,
  • 将过滤器和排序保存在session,所以你返回到时,你已经设置好了过滤器并像原先一样排序
  • javascript 日历。可用来在filters,data,hour类型的列里选择日期
  • javascript 计算器。可以操作filters,integer,real类型的列的值
  • dataGrid标题
  • 特殊的dataGrid标题, 在为空时dataGrid显示
  • 函数setInitialOrder(..)设置初始列排序信息
 
plugins/datagrid.txt · 最后更改: 2010/05/30 00:21 (外部编辑)
 
Except where otherwise noted, content on this wiki is licensed under the following license:GNU Free Documentation License 1.2