logo
v2.6.5

Table

Display tabular data beautifully in a simple way.

This component like all other BladewindUI components is simple to use with a few options to customise the component to suit your app needs. A BladewindUI table consists of two parts. The table header and the table body.

Name Department Email
Alfred Rowe Consulting alfred@therowe.com
Abigail Edwin Quality Assurance abigail@edwin.com
Michael K. Ocansey Development kabutey@gmail.com
John C. Doe Virtual Reality johncdoe@faked.com

        
             <x-bladewind::table>
                <x-slot name="header">
                    <th>Name</th>
                    <th>Department</th>
                    <th>Email</th>
                </x-slot>
                <tr>
                    <td>Alfred Rowe</td>
                    <td>Outsourcing</td>
                    <td>alfred@therowe.com</td>
                </tr>
                <tr>
                    <td>Michael K. Ocansey</td>
                    <td>Tech</td>
                    <td>kabutey@gmail.com</td>
                </tr>
            </x-bladewind::table>
        
    

By default the table component does not display a border around the table. You can enable this by setting. has_border="true"

Name Department Email
Alfred Rowe Consulting alfred@therowe.com
Abigail Edwin Quality Assurance abigail@edwin.com
Michael K. Ocansey Development kabutey@gmail.com
John C. Doe Virtual Reality johncdoe@faked.com

        
             <x-bladewind::table
                has_border="true">
                ...
            </x-bladewind::table>
        
    

No Gaps

By default the BladewindUI table rows are displayed with wide gaps to place more emphasis on each row and it’s content. Each row also has a default hover effect that highlights the left and right borders of the row. These can both be turned off.

To remove the wide gaps between the table rows you need to set the divider attribute to thin, like this, divider="thin".

Name Department Email
Alfred Rowe Consulting alfred@therowe.com
Abigail Edwin Quality Assurance abigail@edwin.com
Michael K. Ocansey Development kabutey@gmail.com
John C. Doe Virtual Reality johncdoe@faked.com
        
             <x-bladewind::table
                divider="thin">
                <x-slot name="header">
                    <th>Name</th>
                    ...
                </x-slot>
                ...
            </x-bladewind::table>
        
    

No Divider

It is also possible to completely turn off the divider lines.

To remove the divider completely, set the divided attribute to false, like this, divided="false".

Name Department Email
Alfred Rowe Consulting alfred@therowe.com
Abigail Edwin Quality Assurance abigail@edwin.com
Michael K. Ocansey Development kabutey@gmail.com
John C. Doe Virtual Reality johncdoe@faked.com
        
             <x-bladewind::table
                divided="false">
                <x-slot name="header">
                    <th>Name</th>
                    ...
                </x-slot>
                ...
            </x-bladewind::table>
        
    

No Hover Effect

To remove the beautiful green side border effect when users hover on each row, set the hover attribute to false, like this, hover_effect="false".

Name Department Email
Alfred Rowe Consulting alfred@therowe.com
Abigail Edwin Quality Assurance abigail@edwin.com
Michael K. Ocansey Development kabutey@gmail.com
John C. Doe Virtual Reality johncdoe@faked.com
        
                <x-bladewind::table
                    hover_effect="false"
                    divider="thin">

                <x-slot name="header">
                    <th>Name</th>
                    ...
                </x-slot>
                ...
            </x-bladewind::table>
        
    

Compact

If the table feels too airy and spaced, there is a compact="true" attribute to tighten things up.

Name Department Email
Alfred Rowe Consulting alfred@therowe.com
Abigail Edwin Quality Assurance abigail@edwin.com
Michael K. Ocansey Development kabutey@gmail.com
John C. Doe Virtual Reality johncdoe@faked.com

        
                <x-bladewind::table
                    compact="true"
                    divider="thin">

                <x-slot name="header">
                    <th>Name</th>
                    ...
                </x-slot>
                ...
            </x-bladewind::table>
        
    

Striped Table

Design experts argue that it is sometimes easier for users to visually scan tabular data if the table has striped rows. We are not challenging the experts. We’ve however made it possible for you to make your BladewindUI tables have striped rows. Set striped="true" on the table component to get a striped table.

Name Department Email
Alfred Rowe Consulting alfred@therowe.com
Abigail Edwin Quality Assurance abigail@edwin.com
Michael K. Ocansey Development kabutey@gmail.com
John C. Doe Virtual Reality johncdoe@faked.com
Jane Ama Doe Virtual Reality jane.doe@faked.com
        
            <x-bladewind::table
                striped="true"
                divider="thin">

                <x-slot name="header">
                    <th>Name</th>
                    ...
                </x-slot>
                ...
            </x-bladewind::table>
        
    

Celled Table

If you want your tables looking like an excel spreadsheet with each cell having all round borders, set celled="true".

Name Department Earnings Tax Amt. Due
Alfred Rowe Consulting 1,200 120 1,080
Abigail Edwin Quality Assurance 1,500 135 1,365
Michael K. Ocansey Development 1,390 125 1,265
John C. Doe Virtual Reality 1,100 98 98
        
            <x-bladewind::table celled="true">

                <x-slot name="header">
                    <th>Name</th>
                    ...
                </x-slot>
                ...
            </x-bladewind::table>
        
    

Cells for Totals

Accountants have this interesting habit of double underlining their totals. If that’s something that interests you, apply the class double-underline to the td that holds the total value you want double underlined.

Item Quantity Price (GHS)
Office furniture 2 4,300.00
HP Laser Jet Printer 1 3,000.00
7,300.00
        
            <x-bladewind::table striped="true" divider="thin">

                <x-slot name="header">
                    <th>Name</th>
                    ...
                </x-slot>
                ...
                <tr>
                    <td colspan="2" class="text-right"></td>
                    <td class="double-underline text-right">
                        7,300.00
                    </td>
                </tr>
            </x-bladewind::table>
        
    

Table With Drop Shadow

You can add a subtle shadow effect to your BladewindUI tables by setting has_shadow="true"

Item Quantity Price (GHS)
Office furniture 2 4,300.00
HP Laser Jet Printer 1 3,000.00
7,300.00

        
            <x-bladewind::table
                has_shadow="true"
                striped="true"
                divider="thin">

                <x-slot name="header">
                    <th>Name</th>
                    ...
                </x-slot>
                ...
            </x-bladewind::table>
        
    

Selectable Rows

There are cases you may want to show users which rows they have selected. You can achieve that by setting selectable="true" on the table. Now, any time a user clicks on a row it will be selected. Clicking on multiple rows will select them all. Clicking on a row that is already selected will unselect it. The cursor changes to cursor-pointer when a table is defined as selectable. Cool shortcuts like Ctrl+Click or Shift+Click do not work here.

Item Quantity Unit Price (GHS)
Office furniture 2 4,300.00
HP Laser Jet Printer 1 3,000.00
Macbook Pro M3 (13'') 4 24,300.00
iPhone 15 Pro Max 12 19,000.00
Laptop Sleeve (Black) 5 800.00

        
            <x-bladewind::table selectable="true" divider="thin">
                <x-slot name="header">
                    <th>Item</th>
                    <th>Quantity</th>
                    <th>Unit Price (GHS)</th>
                </x-slot>
                <tr>
                    <td>Office furniture</td>
                    <td class="text-center">2</td>
                    <td class="text-right">4,300.00</td>
                </tr>
                ...
            </x-bladewind::table>
        
    

Checkable

We can take the selectable tables one step further by introducing checkboxes for every row. This is achieved by setting checkable="true" on the table. Each row should now have a checkbox injected as the first column. If a table heading exists, a checkbox is also injected as the first column in the table heading. This becomes the master checkbox for checking or unchecking all other checkboxes at once. The state changes to a partial selected checkbox if some of the checkboxes are checked.

Item Quantity Unit Price (GHS)
Office furniture 2 4,300.00
HP Laser Jet Printer 1 3,000.00
Macbook Pro M3 (13'') 4 24,300.00
iPhone 15 Pro Max 12 19,000.00
Laptop Sleeve (Black) 5 800.00

        
            <x-bladewind::table selectable="true" checkable="true" divider="thin">
                <x-slot name="header">
                    <th>Item</th>
                    <th>Quantity</th>
                    <th>Unit Price (GHS)</th>
                </x-slot>
                <tr>
                    <td>Office furniture</td>
                    <td class="text-center">2</td>
                    <td class="text-right">4,300.00</td>
                </tr>
                ...
            </x-bladewind::table>
        
    

Having selectable table rows definitely means you will want to do something with the selected values. You will need to append unique IDs (data-id="your-uuid-value") to your table rows in order for Bladewind to recognize and return them.

You will also need to provide a name for the table. This will be the name of the input field that holds the comma separated list of table row IDs that are selected.


        
            <x-bladewind::table selectable="true" checkable="true" divider="thin"
                name="office_supplies">
                <x-slot name="header">
                    <th>Item</th>
                    <th>Quantity</th>
                    <th>Unit Price (GHS)</th>
                </x-slot>
                <tr data-id="1">
                    <td>Office furniture</td>
                    <td class="text-center">2</td>
                    <td class="text-right">4,300.00</td>
                </tr>
                <tr data-id="2">
                    <td>HP Laser Jet Printer</td>
                    <td class="text-center">2</td>
                    <td class="text-right">4,300.00</td>
                </tr>
                ...
            </x-bladewind::table>
        
    

We now have a hidden input injected on the page right after the table. <input type="hidden" name="office_supplies" class="office_supplies" />. We can now access the value of this input field using JavaScript or via a form submission if your table is placed within a form. In the example below we delete all table rows that are selected. Select more than one row.


Item Quantity Unit Price (GHS)
Office furniture 2 4,300.00
HP Laser Jet Printer 1 3,000.00
Macbook Pro M3 (13'') 4 24,300.00
iPhone 15 Pro Max 12 19,000.00
Laptop Sleeve (Black) 5 800.00
        
    <x-bladewind::card reduce_padding="true">
        <!-- the delete button -->
        <div class="office-supplies-actions p-3 bg-gray-100/50 rounded-lg hidden">
            <x-bladewind::button size="tiny"
                type="secondary" outline="true"
                icon="trash" color="red"
                onclick="deleteRows()">
                Delete
            </x-bladewind::button>
        </div>

        <x-bladewind::table selectable="true" divider="thin"
            checkable="true"
            name="office_supplies">
            <x-slot:header>
                <th>Item</th>
                <th class="!text-center">Quantity</th>
                <th class="!text-right">Unit Price (GHS)</th>
            </x-slot:header>
            <tr data-id="12">
                <td>Office furniture</td>
                <td class="text-center">2</td>
                <td class="text-right">4,300.00</td>
            </tr>
            ...
        </x-bladewind::table>
    </x-bladewind::card>
        
    

The above code will draw the table and let Bladewind do its checkboxing magic. You will however, need to write the code for working with the values of the selected table rows. The deleteRows() Javascript function below is what handles deleting of the rows selected by the user from the example above. deleteRow() is not a BladewindUI helper function.

        
    // domEl(), domEls() and hide() are BladewindUI helper functions
    deleteRows = () => {
        // Our table is named 'office_supplies' so input.office_supplies is
        // the hidden field Bladewind will write IDs of all selected rows to
        const selectedRows = domEl('input.office_supplies').value.split(',');

        // next we loop over all the rows of our 'office_supplies' table and
        // hide any row that's having the value of its 'data-id' attribute
        // in the selected rows array
        const tableRows = domEls('table.office_supplies tr');
        tableRows.forEach(row => {
            if(selectedRows.indexOf(row.getAttribute('data-id')) !== -1) {
                hide(row, true);
                hide('.office-supplies-actions');
                domEl('input.office_supplies').value = '';
            }
        });
    }
        
    

If you want to by default select rows when your table loads, for example, in edit mode you want to display to the user the previous rows they selected. Set the selected_value attribute on the table. This accepts a comma separated list of IDs.


<x-bladewind::table selectable="true" divider="thin"
    checkable="true"
    selected_value="2,4,19,23"
    name="office_supplies">
    ...

Display a Table From Dynamic Data

There is no point manually building a table tediously when you have an array that contains everything you want to display as a table. The table component has a data attribute that accepts a json encoded array. The component builds its table headings using the array keys.

Let us consider the array below and its resultant table.

        
            $staff = [
                [   'id' => 1,
                    'first_name' => 'Michael',
                    'last_name' => 'Ocansey',
                    'department' => 'Engineering',
                    'marital_status' => 1
                ],
                [
                    'id' => 2,
                    'first_name' => 'Alfred',
                    'last_name' => 'Rowe',
                    'department' => 'Engineering',
                    'marital_status' => 1
                ],
                [
                    'id' => 3,
                    'first_name' => 'Abigail',
                    'last_name' => 'Edwin',
                    'department' => 'Engineering',
                    'marital_status' => 0
                ],
            ];
        
    
        
            <x-bladewind::table :data="$staff" />
        
    

Below is an alternative way to pass data to the component. Note there is no colon before the data attribute and in this case the data is passed as a json encoded string.

        
            <x-bladewind::table data="{{ json_encode($staff) }}" />
        
    

id first name last name department marital status
1 Michael Ocansey Engineering 1
2 Alfred Rowe Engineering 1
3 Abigail Edwin Engineering 0

As you can tell from the above example, the component simply picks the array passed to it and generates a table. You can apply all the table attributes to remove the hover effect, remove the gaps or even make the table striped.

Excluding and Including Columns

By default, the table picks the keys of the array and generates its table headings. Any key with underscores will be replaced with spaces. first_name becomes first name. An API will return staff data with the ID of each user, but it is rare to see the IDs displayed in a table. The table component allows you to exclude some columns using the exclude_columns attribute. There is also the include_columns attribute that lets you specify the only columns to be displayed.

If you have an array with 20 fields and you want to display 5 out of the 20 fields, it will be easier to specify the 5 columns in the include_columns attribute rather than specifying 15 columns in the exclude_columns attribute. Let us exclude id and marital_status from our table above.

include_columns takes precedence over exclude_columns. If you specify both attributes, exclude_columns will be ignored.

first name last name department
Michael Ocansey Engineering
Alfred Rowe Engineering
Abigail Edwin Engineering

    <x-bladewind::table
        exclude_columns="id, marital_status"
        :data="$staff" />

Displaying Action Icons

Using the table component with dynamic data allows you to specify some extra cool attributes. You can show action icons by passing a json encoded array in the action_icons attribute. Each action icon can have the name of the icon, the icon colour (default is the secondary button colour), a tooltip and the click action of the icon. The icons will be displayed in the order they are entered into the array.


    $action_icons = [
        "icon:chat | tip:send message | color:green | click:sendMessage('{first_name}')",
        "icon:pencil | click:redirect('/user/{id}')",
        "icon:trash | color:red | click:deleteUser({id}, '{first_name}')",
    ];


    <x-bladewind::table
        exclude_columns="id, marital_status"
        divider="thin"
        :action_icons="$action_icons"
        :data="$staff" />

first name last name department actions
Michael Ocansey Engineering
Alfred Rowe Engineering
Abigail Edwin Engineering


The icons are displayed from the $action_icons array above. Let us analyze the first line of the $action_icons array. Note how each attribute is separated by a pipe (|).

icon:chat-bubble-left This will display the chat-bubble-left icon
tip:send user a message On hover of the icon, the user will see a tooltip that says "send user a message"
click:sendMessage('{first_name}') When the icon is clicked, the sendMessage Javascript function is triggered. The function name can be any function that exists in your code. Two parameters are passed to the function. The parameters can be any of the keys that exists in your array. In our earlier example our array contains the first_name key so we pass this to our function. It is important to wrap strings in a single quote. The keys also need to be wrapped in curly braces. The table component will replace '{first_name}' with the actual value of first_name from the array.
color:green The icon colour will be green.

Below are the modals and Javascript functions being called when the icons are clicked. Mind you, the Javascript functions below are just for the documentation. THey need to be your own functions that you will call when the action icons are clicked.

        
            <!-- send message modal -->
            <x-bladewind.modal name="send-message" title="">
                <div class="mb-6">
                    The message will be delivered to their company
                    inbox if they are not currently online
                </div>
                <x-bladewind.textarea
                    placeholder="Type message here..." rows="5" />
            </x-bladewind.modal>

            <!-- delete user modal -->
            <x-bladewind.modal
                    name="delete-user"
                    type="error" title="Confirm User Deletion">
                Are you really sure you want to delete <b class="title"></b>?
                This action cannot be reversed.
            </x-bladewind.modal>
        
    
        
        sendMessage = (first_name, last_name) => {
            showModal('send-message');
            domEl('.bw-send-message .modal-title').innerText = `Send Message to ${first_name} ${last_name}`;
        }

        deleteUser = (id, first_name, last_name) => {
            showModal('delete-user');
            domEl('.bw-delete-user .title').innerText = `${first_name} ${last_name}`;
        }

        redirect = (url) => {
            window.open(url);
        }
        
    

No Data Returned

When building dynamic table you will most likely be fetching your data from either an API or a database. You will barely be manually creating arrays as we did above. Now with dynamic data, it is likely your API or query will return no records. You can display a custom translatable message in such a case. You can set the no_data_message to any message you wish to display.

The staff directory is empty


<x-bladewind::table
    no_data_message="The staff directory is empty"
    :data="$staff"  />


The dynamic table builds its column headings from the array keys defined in data. When there are no records to display, the array will be empty, thus, there will be no column headings to deduce. This is why there are no columns displayed with the no data message. If you wish to display column headings with the no data message, you will need to pass column_aliases.

ref # first name last name married?
The staff directory is empty


    $column_aliases = [
        'id' => 'ref #',
        'first_name' => 'first name',
        'last_name' => 'last name',
        'marital_status' => 'married?'
    ];


<x-bladewind::table
    has_border="true"
    no_data_message="The staff directory is empty"
    :column_aliases="$column_aliases"
    :data="$staff"  />

Finally, it is possible to display the no data message using the Empty State component. All the attributes of the component are allowed except message and class, since the table component already has its own class attribute, and message here is already no_data_message.

To display the message in an empty state, set the attribute message_as_empty_state="true".

ref # first name last name married?
The staff directory is empty


<x-bladewind::table
    :data="$no_staff"
    has_border="true"
    :column_aliases="$column_aliases"
    no_data_message="The staff directory is empty"
    message_as_empty_state="true"
    button_label="add staff member" />

Check out the Empty State component for information on how to use its attributes.


Searchable Table Data

The table component provides a very basic way for users to search through table content. If the searchable="true" attribute is set, a search field is placed above the table that makes it possible to search through any column of the table. By placeholder text for the search input can be replaced by setting the search_placeholder attribute on the table.

first name last name department actions
Michael Ocansey Engineering
Alfred Rowe Engineering
Abigail Edwin Engineering

    <x-bladewind::table
        searchable="true"
        :data="$staff"
        divider="thin"
        search_placeholder="Find staff members by name..."
        :action_icons="$action_icons"
        exclude_columns="id, marital_status" />

Aliasing Column Names

There are times your array might contain keys that are not user-friendly enough to be column headings. From our array above assuming we wanted to replace marital_status to married?, we will set the column_aliases attribute. This attributes accepts a json encoded array.


    $column_aliases = [
        'id' => 'ref #',
        'marital_status' => 'married?'
    ];


    <x-bladewind::table
        exclude_columns="id"
        divider="thin"
        :action_icons="$action_icons"
        :column_aliases="$column_aliases"
        :data="$staff" />

ref # first name last name department married?
1 Michael Ocansey Engineering 1
2 Alfred Rowe Engineering 1
3 Abigail Edwin Engineering 0

You can define selectable="true" and checkable="true" on dynamic tables. In this case, the "data-id" attribute of each row in the table is automatically set using the "id" value defined in the data array.

Grouping Rows

Let's assume you have a table of employees and wish to group these employees by department, so all staff in Marketing will be under the marketing heading and so on. This can be achieved by specifying the groupby attribute on the table. The value of groupby will need to be any of the keys in your array .

From the employee example above, we will set our grouping on the department key which happens to be to repeated for our employees. groupby="department".


    $staff = [
        [
            'id' => 1,
            'first_name' => 'Michael',
            'last_name' => 'Ocansey',
            'department' => 'Engineering',
            'email' => 'mike@email.com'
        ],
    ]
    ...


    <x-bladewind::table
        exclude_columns="id"
        divider="thin"
        groupby="department"
        :data="$staff" />

ref # first name last name email
Engineering
1 Michael Ocansey mike@email.com
2 Alfred Rowe alfred@rowe.com
3 Abigail Edwin abi@edwin.com
Sales
4 John Doe john@doe.com
5 Janet Doe jane@email.com
6 Michael Sarpong mike@sarpong.com

You can define selectable="true" and checkable="true" on dynamic tables. In this case, the "data-id" attribute of each row in the table is automatically set using the "id" value defined in the data array.

Full List Of Attributes

The table below shows a comprehensive list of all the attributes available for the Table component.

IMPORTANT: Projects running Laravel 8 please read this

Option Default Available Values
name 'tbl-'.uniqid() Name of the table. Useful if you want to target the table via Javascript. The name is added in the class="" attribute of the table.
striped false Determines if the table rows are striped. Even rows get the stripes. The value should be passed as a string, not boolean.
true false
divided true Determines if the table rows show the lines that divide them. The value should be passed as a string, not boolean.
true false
divider regular Determines how wide the gaps are between table rows.
regular thin
hover_effect false Determines if the borders of the table rows light up when hovered over. The value should be passed as a string, not boolean.
true false
has_shadow true Determines if the table has a drop shadow effect. The value should be passed as a string, not boolean.
true false
compact false If set to true, the spacing between the TRs are reduced.
true false
header blank This slot holds your table header information.
uppercasing true Determines if the table headings should be all uppercase. If false, the text will be displayed as you entered it.

true false
:data null Array of elements to generate the table from. When this has a value, there is no need to manually build the table. Ignore this attribute if you prefer to use data instead.
data null Json encoded array of elements to generate the table from. When this has a value, there is no need to manually build the table. Ignore this attribute if you prefer to use :data instead..
exclude_columns null Comma separated list of columns to exclude when generating the table. The 'columns' need to match keys in your array.
include_columns null Comma separated list of columns to include when generating the table. This list overwrites any columns specified in exclude_columns. In fact, the keys specified in this list will be the only ones used to generate the table.
:action_icons null Array of icon actions that will be displayed on each row of the table. Only used when data is not null. By default no action icons are displayed if value is null This can also be passed as action_icons without the colon but then the array will need to be Json encoded.
action_title actions Heading of the column that shows the actions.
:column_aliases [] Array of column aliases. Aliases are column names to use in place of what is defined in the data array. For example you may want a date_of_birth key to be displayed as birthday. This can also be passed as column_aliases without the colon but then the array will need to be Json encoded.
searchable false Specify if the table is searchable. When true, a search input is placed above the table.

truefalse
search_placeholder Search table below... Only used when searchable="true". Specifies the text to display in the search input field.
no_data_message No records to display Message to display when there is no dynamic data to display.
message_as_empty_state false When there is no dynamic data to display, should the message be displayed as an empty state.
truefalse
image empty-state.svg Image to display in the empty state component when no dynamic data is available.
heading blank Text to display as heading in empty state when no data is available for the dynamic table.
button_label blank Label to display on empty state call to action button.
celled false Display each cell with borders all round. Like you get in an excel sheet.
truefalse
show_image true Should the empty state component image be displayed.
truefalse
transparent false Should the empty table be transparent. ALl background colours are removed to enable the table sit well on any dark mode background colour.
truefalse
onclick blank Action to perform on the empty state component call to action button. Only used when displaying dynamic data.
groupby blank Key of column to group rows by. The key needs to exist in the array you are displaying your data from. Works only for dynamic tables.
selected_value null Comma separated list of row IDs to select when the table is rendered.

Table with all attributes defined

        
            <x-bladewind::table
                striped="true"
                divided="true"
                divider="thin"
                has_shadow="true"
                has_border="true"
                compact="true"
                transparent="true"
                searchable="false"
                search_placeholder=""
                name="staff-table"
                :data="$data"
                :column_aliases="$column_aliases"
                include_columns="first_name, last_name, email"
                exclude_columns="id,picture"
                :action_icons="$action_icons"
                action_title=""
                no_data_message="The staff directory is empty"
                message_as_empty_state="true"
                button_label="add staff member"
                image="asset('images/no-data.png')"
                heading="No Staff"
                groupby="department"
                selected_value="2,3,4"
                onclick="alert('add a staff')"
                hover_effect="true">

                <x-slot name="header">
                    ...
                </x-slot>

                <tr>
                ...
                </tr>

            </x-bladewind::table>
        
    
The source file for this component is available in resources > views > components > bladewind > table.blade.php