flsouto / htmltable
无需痛苦即可构建HTML表格的库
Requires
- php: ^7.2
README
他们通过命令行直接在服务器上编写html表格。向他们致敬。对于我们其他人来说,HtmlTable是工作的巨大帮助。
安装
composer require flsouto/htmltable
基本用法
创建和渲染带有属性、列和数据的表格。
$tbl = new Table(['width'=>800]);
$tbl->col('id');
$tbl->col('name');
$tbl->data([
['id'=>1,'name'=>'Alucard'],
['id'=>2,'name'=>'Richter']
]);
echo $tbl;
列对齐
$tbl->col('id')->align('left|center|right');
$tbl->col('name')->align('left|center|right');
定义列宽度
$tbl->col('id')->align('center')->width('1px');
$tbl->col('name')->align('left')->width('500px');
默认情况下,列标题将是键的名称,用空格替换“_”。要自定义标题
$tbl->col('name')
->heading('Nome do Personagem')
默认情况下,所有列都是可排序的。要禁用排序
$tbl->col('actions')
->sortable(false)
为列的null值定义一个默认值
$tbl->col('dt_updated')->heading('Atualizado')->blank('-- Never ---')
自定义列数据的模板
$tbl->col('link')->td('<a href="?id={id}">Ver {name}</a>');
要自定义td本身,请使用TD标签包裹
$tbl->col('name')->td('<td data-id="{id}">{content}</td>');
传递ARRAY来仅自定义td的属性
$tbl->col('name')->td([
'data-id' => '{id}',
'class' => 'whatever'
]);
自定义模板+属性
$tbl->col('name')->td('<b>{content}</b>')->td([
'data-id' => '{id}',
'class' => 'whatever'
]);
align()和width()函数内部设置一些属性。使用{attrs}在模板中重新使用它们
$tbl->col('name')
->align('left')
->width('500px')
->td('<td {attrs} class=blah><b>{content}</b></td>');
注意:align()在td(单元格)和th(表头)上使用相同的样式,使用样式API
$tbl->col('name')
->td([
'class' => 'blah',
'style' => ['background-color'=>'blue', 'color'=> 'white']
]);
td的所有功能也适用于th
$tbl->col('name')
->td(['class'=>'blah'])
->th(['style'=>['background'=>'black']]);
高级功能
回调以自定义渲染时的TD
$tbl->data([
['id'=>1,'name'=>'Alucard','status'=>'dead'],
['id'=>2,'name'=>'Richter','status'=>'alive']
]);
$tbl->col('actions')->td(function(Td $td){
if($td->data->get('status') == 'dead'){
$td->template('<button>Ressurect {name}</button>');
} else {
$td->template('<button>Kill {name}</button>');
}
});
echo $tbl;
对于TH也是如此,只是它没有数据
$tbl->col('actions')->th(function(Th $th){
$th->attrs->set('class','actions-heading');
$th->attrs->style(['background'=>'yellow']);
});
要自定义TR,即表格的行
$tbl->tr->callback(function(Tr $tr){
if($tr->data->get('status') == 'dead'){
$tr->attrs->set('class', 'dead');
} else {
$tr->attrs->set('class', 'alive');
}
});
如果逻辑非常简单,如上所示,只需定义一个模板即可
$tbl->tr->template('<tr class="{status}" data-id="{id}">{content}</tr>');
在TR上设置属性也是有效的。下面的例子生成了与上一个例子相同的结果
$tbl->tr->attrs->merge([
'class' => '{status}',
'data-id' => '{id}'
]);
注意:在callback
中返回字符串会覆盖整个元素的生成。这也适用于Th、Td和Tr
$el->callback(function(){
return "<custom markup>";
})
有时需要根据数据修改行(tr)中的所有单元格(td)
$tbl->each(function(Column $col){
$col->td(function(Td $td){
if($td->data->get('status')=='dead'){
$td(['style'=>['background'=>'red']]);
} else {
$td(['style'=>['background'=>'green']]);
}
});
});
上面的例子使用了一种“语法糖”来设置td的样式属性。注意以下所有形式都是等效的
$td(['style'=>'backgorund:red']);
$td->attrs->set('style', 'background:red');
$td->attrs->set('style', ['background'=>'red']);
$td->attrs->style('background:red');
$td->attrs->style(['background'=>'red']);
注意,结果是可以累积的
$td->attrs->style('background:red;color:white');
$td->attrs->style('color:green'); // redefine a cor da fonte
$td(['style'=>['border'=>'1px solid black']);
这些资源在所有其他扩展Element(如Tr和Th)的元素中都是可用的。类Table
不扩展Element,但它提供了具有相同功能的属性$tbl->attrs
。
覆盖请求数据
默认情况下,table对象从$_REQUEST变量中获取数据。通过构造函数的第二个参数传递以覆盖它
$tbl = new Table(['id'=>'whatever'], $my_request_data);
自定义排序
table对象公开了$tbl->sorting
属性,允许
- 定义默认排序
- 获取正在请求的排序
- 生成安全的SQL以插入ORDER BY子句
- 生成一个URL以排序某个列,同时考虑之前的状态(ASC/DESC)
要定义默认排序
$tbl->sorting->defaults('id','DESC');
要获取正在请求的排序
$tbl->sorting->current()->col
$tbl->sorting->current()->ord
current()返回的对象可以与字符串连接
$sql = "SELECT ... ORDER BY ".$tbl->sorting->current()
如果需要为SQL列使用别名
$sql = "SELECT ... ORDER BY ".$tbl->sorting->current()->sql('a')
注意:不需要担心SQL注入,因为current()方法通过验证列名是否已通过$tbl->col
定义在表中来验证名称。ASC/DESC字符串也被验证。
Table的Th对象已经使用Sorting来为列生成排序链接。但如果需要手动生成URL,请使用url方法
$tbl->sorting->url('column')
特殊列
除了标准类型(字符串)$tbl->col()
之外,还有针对每种相关数据类型的列,以及构建基本控件(如按钮)的列。使用正确的列类型非常重要,因为它会影响数据的排序和格式化
数字
$tbl->cnum('price')
->thousands('.')
->precision(2)
->point(',')
->td('R$ {content}')
日期
$tbl->cdate('dt_added')->datef('d/m/Y H:i:s')
按钮
$tbl->cbtn('Label')
->url('action?id={id}', $new_tab=true)
->element([
'class' => 'action-btn',
'data-id' => '{id}',
'style' => 'etc...'
])
可输入列
复选框
复选框列在每一行插入一个复选框。这对于选择某列的值非常有用
$tbl->ccheck('selection[id]');
在这个例子中,HtmlTable将为选择表中的id生成复选框
<input type="checkbox" name="selection[{id}]" />
所以这与使用以下模板创建一个普通列几乎相同
$tbl->col('id')->td('<input type="checkbox" name="selection[{id}]" />')
复选框的优势在于它会自动在表的$request中搜索是否有复选框被选中,并为相应的复选框插入"checked"属性。
要检查复选框是否被选中
if(isset($request['selection'])){
$selected_ids = array_keys($request['selection']);
}
使用以下技术让一些复选框默认选中
...
if(!$form_submited){
$request['selection'][1] = true;
$request['selection'][1] = true;
$request['selection'][3] = true;
}
$tbl = new Table(['width'=>800], $request);
$tbl->ccheck('id:selection');
...
可输入字段的替代语法
存在定义可输入字段的替代语法
$tbl->ccheck('data[id][active]');
当您已经拥有数据中的布尔列并且希望使用该值来标记复选框时,这种替代方法非常有用。在这种情况下,表单发送的数据将如下所示
foreach($request['data'] as $id => $row){
if(!empty($row['active']){
// etc...
}
}
这种语法在您的表中有多处可输入字段时也很有用
$tbl->ccheck('data[id][update]');
$tbl->col('data[id][name]');
$tbl->col('data[id][description]');
处理变得更加优雅
foreach($request['data'] as $id => $row){
if(!empty($row['update']){
$db->update('table', $data, ['id'=>$id]);
}
}
可输入字段与表单
HtmlTable不会自动创建<form></form>
标签。因此,要提交表中的输入数据,需要在表单内渲染它
<form method="METHOD" action="ACTION">
{{table}}
<button>Submit</button>
</form>
定义自己的列
$tbl->col()
函数接受一个预定义的列对象。因此,只需实现自己的列类,实例化它,并注入对象即可
class MyColumn extends Column{
function render(Data $data){
return "cool stuff";
}
}
$tbl->col(new MyColumn)->align('etc..');
内部变量术语表
正如您在本文件中所看到的,HtmlTable已经预定义了一些变量,可以在模板中引用。以下是所有这些变量的术语表
- {attrs} - 标签的属性,包括style(CSS)
- {attrs.style} - 仅style(CSS)属性
- {content} - 标签的内部内容(通常是列的格式化值)
- {table.index} - 正在被渲染的行的索引
- {button.label} - 按钮的标签
- {button.element} - 按钮的input元素(In类)
- {checkbox.element} - 复选框的input元素(In类)