logo
v2.8.1

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.

Sorting

A BladewindUI table that accepts dynamic data can become sortable by setting sortable="true". Automatically, all columns in the table can be clicked on to sort the table. Each sortable column has a filter icon next to the column heading.

company name first name last name mobile
Morissette-O'Connell Alberta Sawayn (925) 750-0696
Gleason Group Hailey VonRueden (413) 566-4637
Orn PLC Buck Koss +1 (913) 670-3672
Feest, Lindgren and Parker Daphnee Wolff +1.940.281.7982
Koss-Pouros Jazlyn Ritchie 1-534-685-4141
<x-bladewind::table
    exclude_columns="member_id, email"
    sortable="true"
    limit="5"
    :data="$users" />

From the above table you can see every column in the table has a filter icon next to the column heading indicating that the column is sortable. There are cases you will want to sort your table using only very specific columns. This can be achieved by setting the sortable_columns attribute to a comma separated list of columns you want to make sortable.

company name first name last name mobile
Morissette-O'Connell Alberta Sawayn (925) 750-0696
Gleason Group Hailey VonRueden (413) 566-4637
Orn PLC Buck Koss +1 (913) 670-3672
Feest, Lindgren and Parker Daphnee Wolff +1.940.281.7982
Koss-Pouros Jazlyn Ritchie 1-534-685-4141
<x-bladewind::table
    exclude_columns="member_id, email"
    sortable="true"
    limit="5"
    sortable_columns="first_name, last_name"
    :data="$users" />

Pagination

Pagination is useful for displaying a long list of data in sizable chunks that make it easy to look over the data. The BladewindUI table can be paginated when dealing with dynamic data by setting paginated="true". This will display pagination controls at the end of the table. Multiple tables on the same page can be paginated. The page_size attribute determines how many rows are displayed per page. The default value is 25.

For convenience, paginated tables can display row numbers to make it easy to validate row counts. This is not enabled by default. To turn on row numbers set show_row_numbers="true".

# company name first name last name mobile
1 Morissette-O'Connell Alberta Sawayn (925) 750-0696
2 Gleason Group Hailey VonRueden (413) 566-4637
3 Orn PLC Buck Koss +1 (913) 670-3672
4 Feest, Lindgren and Parker Daphnee Wolff +1.940.281.7982
5 Koss-Pouros Jazlyn Ritchie 1-534-685-4141
Showing 1 to 5 of 222 records
1
<x-bladewind::table
    exclude_columns="member_id, email"
    paginated="true"
    page_size="5"
    show_row_numbers="true"
    :data="$users" />
When using show_row_numbers="true" and sortable="true", it is important to note that the row numbering is not reordered to match the sorted data. Row numbers 1, 2, 3, 4 might end up as 4, 1, 2, 3

When sorting paginated tables, the sorting is only applied to the current page and not the entire table.

You may not always want to start displaying your table rows from page 1. Maybe, the user bookmarked a record that is on page 6 and you want to jump to that on page load. This can be achieved by setting the default_page attribute. The value of default_page is set to 1 if the value provided is greater than the total_pages.

# company name first name last name mobile
71 Schmitt Ltd Graciela Cruickshank +1-361-455-4528
72 Mitchell Inc Effie Jacobson +19403771109
73 Treutel-Rippin Alexa Schoen +1-346-500-0330
74 Stanton, Frami and Zieme Sidney Green +1 (820) 214-6681
75 Little, Shanahan and Jast Terrence Kuphal 1-802-840-2088
Showing 71 to 75 of 222 records
15
<x-bladewind::table
    exclude_columns="member_id, email"
    paginated="true"
    page_size="5"
    show_row_numbers="true"
    default_page="15"
    :data="$users" />

Custom Table Layouts

Pagination is automagically applied to a BladewindUI table that accepts dynamic data. By default the table layout is flat. Every key in the array/data is created as a column. Sometimes you may want to have a custom table layout that merges various columns into one but you still want to enjoy the library's pagination. Still set paginated="true" and :data="$your_data" but, in this case you will be responsible for manually setting up a few things on the data rows. You will also need to include the pagination component manually. You will also need to set layout="custom"

ID User Details Contact Details
439299
/assets/images/male.png
Anabel Torp
Schumm Group
+1-201-677-2611
455056
/assets/images/female.png
Estefania Wolff
Schuster, Koepp and Gottlieb
251-880-6469
727505
/assets/images/male.png
Madalyn Russel
Roberts-Paucek
+1 (302) 472-6913
453069
/assets/images/female.png
Haley Rowe
Larkin-Morissette
(938) 267-6693
674750
/assets/images/male.png
Shaylee Jacobi
Runolfsson Inc
1-720-344-1946
Showing 26 to 30 of 222 records
6
<x-bladewind::table
    layout="custom"
    :paginated="true"
    :page_size="$page_size = 5"
    :data="$users"
    :default_page="$default_page = 6">

    <x-slot:header>
        <th>Member ID</th>
        <th>User Details</th>
        <th>Contact Details</th>
    </x-slot:header>

    <tbody>

        @foreach($users as $user)
            @php
                // set avatar url
                $image = ($loop->even) ? 'male.png' : 'female.png';
            @endphp
            <tr {{pagination_row($loop->iteration, $page_size, $default_page)}} >
                <td class="!w-1 !pr-0"><div class="pt-3">{{$user['member_id']}}</div> </td>
                <td>
                    <div class="flex space-x-3">
                        <div><x-bladewind::avatar image="/assets/images/{{$image}}" size="small" /></div>
                        <div>
                            <div class="text-base font-semibold">{{$user['first_name']}} {{$user['last_name']}}</div>
                            <div>{{$user['company_name']}}</div>
                        </div>
                    </div>
                </td>
                <td>
                    <div>{{$user['mobile']}}</div>
                    <div><a href="#">{{$user['email']}}</a></div>
                </td>
            </tr>
        @endforeach

    </tbody>
</x-bladewind::table>

Let's breakdown the example above. Pay attention to lines 2, 4, 6 and 22. Let's talk about line 22 first. The pagination widget relies on a couple of attributes defined on the data rows to work properly. A typical data row in a pagination table looks like this:

<tr data-id="12" data-page="1" class="hidden"> ... </tr>
...
<tr data-id="34" data-page="6"> ... </tr>
<tr data-id="35" data-page="6"> ... </tr>
...
<tr data-id="272" data-page="9" class="hidden"> ... </tr>

As we loop to generate the table rows, any row that has its data-page attribute not corresponding to the default_page is set to class="hidden". So from our example above, we set default_page="6", any row that is not on page 6 will need to be hidden. Generating these attributes required for pagination can be a headache so a helper function is provided.

Adding pagination_row($row_number, $page_size, $default_page) to each row will generate the attributes required by the pagination widget.
$row_number is the current iteration/$index of the loop. Start with 1 not 0.
$page_size is how many records should be displayed per page.
$default_page is which page to select by default.

Note how on line 4 we defined :page_size="$page_size = 5". This simply makes the variable $page_size available for us to use later when calling pagination_row($row_number, $page_size, $default_page). This is simply to avoid repetition and nothing more. We could have alternatively decided to do what's below.

<x-bladewind::table
    ...
    page_size="5"
    default_page="6">
    ...

        @foreach($users as $user)
            <tr {{pagination_row($loop->iteration, 5, 6)}} >
            ...
        @endforeach

    </tbody>
</x-bladewind::table>

From the example above, if we later change page_size="20", we will need to also update pagination_row($loop->iteration, 20, 6).

Pagination Styles

There are three pagination styles to choose from. The default style is arrows. The page number is displayed by default for the arrows pagination style. When you set the show_total_pages="true" attribute, the page number is displayed as a fraction (a/b), where 'a' is the current page and 'b' is the total number of pages.

The pagination totals label (Showing 1 to 5 of 222 records) can be hidden by setting show_total="false". This is turned on by default. Content of the label can be changed by setting the total_label attribute. The default is Showing :a to :b of :c records. There are 3 placeholders, :a, :b, and :c. The alphabets used for the placeholders need to be maintained.

:a - the starting row number of the current page.
:b - the ending row number of the current page.
:c - the total records.

total_label=":a - :b of :c" will display: 1 - 5 of 50
total_label="Showing :a - :b" will display: Showing 1 - 5

Arrows

# company name first name last name mobile
71 Schmitt Ltd Graciela Cruickshank +1-361-455-4528
72 Mitchell Inc Effie Jacobson +19403771109
73 Treutel-Rippin Alexa Schoen +1-346-500-0330
74 Stanton, Frami and Zieme Sidney Green +1 (820) 214-6681
75 Little, Shanahan and Jast Terrence Kuphal 1-802-840-2088
Records 71 - 75
15 /45
<x-bladewind::table
    exclude_columns="member_id, email"
    paginated="true"
    page_size="5"
    total_label="Records :a - :b"
    show_row_numbers="true"
    pagination_style="arrows"
    :data="$users"
    show_total_pages="true"/>

Dropdown

Set pagination_style="dropdown" on the table component.

# company name first name last name mobile
71 Schmitt Ltd Graciela Cruickshank +1-361-455-4528
72 Mitchell Inc Effie Jacobson +19403771109
73 Treutel-Rippin Alexa Schoen +1-346-500-0330
74 Stanton, Frami and Zieme Sidney Green +1 (820) 214-6681
75 Little, Shanahan and Jast Terrence Kuphal 1-802-840-2088
Records 71 - 75
15

Numbers

Set pagination_style="numbers" on the table component.

# company name first name last name mobile
71 Schmitt Ltd Graciela Cruickshank +1-361-455-4528
72 Mitchell Inc Effie Jacobson +19403771109
73 Treutel-Rippin Alexa Schoen +1-346-500-0330
74 Stanton, Frami and Zieme Sidney Green +1 (820) 214-6681
75 Little, Shanahan and Jast Terrence Kuphal 1-802-840-2088
Records 71 - 75
<x-bladewind::table
    exclude_columns="member_id, email"
    paginated="true"
    page_size="5"
    total_label="Records :a - :b"
    show_row_numbers="true"
    pagination_style="numbers"
    :data="$users"
    show_total_pages="true"/>

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..
layout auto Determines if the component should automatically build the table or not.
auto custom
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.
show_row_numbers false Should each row have its number displayed as the first column.
truefalse
sortable false Should the table be sortable.
truefalse
sortable_columns [] By default you can click on all columns to sort the table if sortable="true". To restrict this behaviour, provide a comma separated list of columns that should be clickable for sorting..
paginated false Should the table be paginated.
truefalse
pagination_style arrows How should the pagination controls be displayed.
arrowsdropdownnumbers
page_size 25 How many rows should be displayed per page.
show_total true Should the pagination total be displayed.
truefalse
show_page_number true This only applies when pagination_style="arrows". Should the current page number be displayed between the previous and next buttons.
truefalse
show_total_pages false By default only the current page number is displayed. When this is true, the page number will be displayed as currentPage/totalPages. Example: 3/20. meaning on page 3 out of 20.
truefalse
default_page 1 When pagination="true", what should be the default selected page. Useful if you want to load any page other than 1.
limit null How many rows should be displayed in total. You can have a total of 100 rows but want to explicitly set the table to display ONLY 20. Set limit="20".
total_label Showing :a to :b of :c records Applicable when show_total="true". How should the label be displayed. Note there are 3 placeholders, :a, :b, and :c. These placeholders need to exist in your label to properly replace the values.
:a - the starting row number of the current page.
:b - the ending row number of the current page.
:c - the total records.

total_label=":a - :b of :c"
will become: 1 - 5 of 50

total_label="Showing :a - :b"
will become: Showing 1 - 5
layout auto Applicable when data is not manual. By default the library builds a flat table from the array data. Each array key becomes its own column. This allows you to build your own complex layout.
auto custom

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')"
    sortable="false",
    paginated="false",
    pagination_style="arrows",
    page_size="25",
    show_row_numbers="false",
    show_page_number="false",
    show_total="true",
    limit="40"
    layout="custom"
    total_label="Showing :a to :b of :c records",
    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