Defining fields
Adding fields
There are 2 ways of defining fields, both are done in the setup()
method of your Table
class.
You can either return an array of fields or use addField($name, $properties)
.
Returning an array (overwrite)
If the fields()
method of your Table
class return an array it will overwrite the $fields
property of your instance:
public function setup()
{
return [
'id' => $this->newField()->set([
'title' => 'ID',
'column' => 'id',
'sortable' => true,
'searchable' => false
]),
'email' => $this->newField()->set([
'title' => 'E-mail',
'column' => 'email',
'sortable' => true,
'searchable' => true
]),
];
}
Adding fields (append)
calling addField($name, $properties)
will append fields to your instance:
public function setup()
{
$this->addField('id', [
'title' => 'ID',
'column' => 'id',
'sortable' => true,
'searchable' => false
]);
$this->addField('email', [
'title' => 'E-mail',
'column' => 'email',
'sortable' => true,
'searchable' => true
]);
}
Properties
There are plenty of options you can set as properties on your fields. Some can be defined on their own, some need others in order to work.
Here's an overview of several use cases:
Title (optional)
This property takes a string, as you might have guessed, it's used to set the column's title in your table's <thead>
.
If you'd rather set this yourself in you're table's HTML tag, you can forget about this property.
'title' => 'Some string',
Sortable (optional)
Should this column be sortable? This property defaults to false.
'sortable' => true,
Searchable (optional)
Should this column be searchable? This property defaults to false.
'searchable' => true,
Default (optional)
This option allows you to define default content for a column.
The default content will be rendered if the data isn't set (as in NULL
or if no column/select property was defined).
'default' => 'No result',
Retrieving field data
There are several ways you can set up a field's data retrieval:
- by a column name
- by a select statement
- leave it empty
Before I start explaining them I'd like to mention that there are 2 handy 'variables' you can insert in your columns or selects:
(:table)
the table's name of the column(:primary_key)
the name of the model's primary key column
If the column has a relation key defined, it will try to use the relation's data instead of the specified model's.
By Column name
Let's say we have a blog and want to display a list of posts.
If you want something as simple as just a column from your database you could define it like so (in this case we'll select the title field).
'column' => 'title'
This is technically correct, but to help you keep yourself sane while debugging I would advise you to adding (:table).
before title
. If you're not making use of relations (:table)
will be replaced with the model's table name.
Of course, if you've also loaded relations you could and you know their model's table name you could replace (:table)
with that to be sure the column you want gets selected.
In case you don't know your relation's model's table name you could define a relation
property.
Let's say we'll add a second field to our table with the post's author's name:
'column' => '(:table).name',
'relation' => 'author',
This would work fine if we're sure that the name
column is only present in the relation's table.
If the model's table also has a name
column we'll need to make sure Eloquent knows which one we're talking about.
This can be done easily by adding an as
property:
'column' => '(:table).name',
'relation' => 'author',
'as' => 'author_name'
Now we're 100% sure that the author's name won't conflict with any other relations or the model's columns.
By select statement
If you want more flexibility you have the option of doing a raw SQL
select, for example, looking back at our previous example. What if, instead of just a name
, the author has a first_name
and a last_name
.
You could make 2 separate fields for them, but searching might be easier if they're together. So let's concatenate them:
'select' => 'CONCAT((:table).first_name, \' \', (:table).last_name)',
'as' => 'author_name'
Of course a relation could be defined here as well.
By leaving it empty
Of course defining a way to retrieve data isn't always needed, for example, when you want a column in your table that just shows a few buttons or a checkbox, to offer some data interaction.
In this case we wouldn't define any of the following properties column
, relation
, select
, as
. No, would be better to either define a default
property that sends over default content (I would advise against this when you're working with large data sets) or you could define a render function.
Presenting data
You are able to present your data in 3 different ways:
- as-is (just the values you get from the database)
- by formatting the data and sending it over in the request
- by rendering the data on the client side
You can make use of the last 2 options in 2 different ways. I'll give you a quick overview before explaining them further:
Table
method definition
Table
method definitionYour Table
class will search for a render and a format method for each field you've defined. These methods would be defined in the following format:
- the method's name name has to start with 'get'
- next it will change the column's name to camel case (title would become Title, created_at would become CreatedAt)
- the method's name should end with 'Format' or 'Render'
Anonymous function
If you're the quick and dirty type of programmer there's the option to assign an anonymous function to either the format' or
renderproperty which takes the same parameters as the
Table` method definition.
Data formatting (orthogonal data)
Sometimes you wish to format a column that you send in a request, for example, you wanted to send over a created_at
field. It's value is perfect for ordering, but it's not necessarily that human-friendly. In this situation it would make perfect sense to format the data and send the original value over for sorting.
You'll have to create a method first on your Table
instance so it knows that you want to format a specific field.
We would be adding getCreatedAtFormat($data, $record)
. The first parameter $data
would be the actual value of created_at (in this case, eloquent will provide us with a Carbon
object), while the second parameter contains all of the data in the same row.
public function getCreatedAtFormat($data, $record) {
return $data->format('D m/d/Y H:i');
}
You should keep in mind that when you define a formatter and a renderer, the renderer will be ignored.
Client side field rendering
DataTables allows you to define functions that render your column's content, just as data formatting, there are 2 ways you can do this:
- By assigning the the format key an anonymous function
- By defining a getFieldNameRender method in your
Table
definition
Both get 1 parameter $field
which is the actual definition you assigned it.
Example
Let's say we have a title
column, but we'd like the data in this column to be wrapped in a <strong>
tag,
in our case we'd need to create a new public method called getTitleRender($field)
.
The only parameter you'll get is the instance of the field definition.
in the method we'll have to return a string or an object that uses __toString()
(like View
).
public function getTitleRender($field)
{
return 'return "<strong>"+row.title+"</strong>";';
}
Any string you define there gets wrapped in the following functions:
function(data, type, row, meta)
{
----- Render method content -----
}
Updated less than a minute ago