Let’s create Dynamic, Reusable DataTable Component with Laravel 8, Bootstrap 5, ReactJS : With Pagination, Sort, Search Functionality

Bijaya Prasad Kuikel
2 min readMar 29, 2021

--

In this article we will learn to create dynamic reusable data table component using Laravel 8 and ReactJS from scratch.

Preparing the backend:

Scaffold new Laravel app: laravel new reactable

Create new database reactable and update .env file accordingly

Update default users migration file:

Schema::create('users', function (Blueprint $table) {  $table->id();  $table->string('name');  $table->string('email')->unique();  $table->timestamp('email_verified_at')->nullable();  $table->string('password');  $table->string('address');  $table->rememberToken();  $table->timestamps();});

Update UserFactory.php file:

return [ 'name'              => $this->faker->name,'email'             => $this->faker->unique()->safeEmail,'address'           => $this->faker->address,'email_verified_at' => now(),'password'          => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password'remember_token'    => Str::random(10),];

So your DatabaseSeeder.php file should have following method:

\App\Models\User::factory(500)->create();

Run the migration: php artisan migrate

Run the seeder: php artisan db:seed

Make the following changes on the app/Http/Controllers/Controller.php

<?phpnamespace App\Http\Controllers;use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Routing\Controller as BaseController;
class Controller extends BaseController
{
public const PER_PAGE = 10;
public const DEFAULT_SORT_FIELD = 'created_at';
public const DEFAULT_SORT_ORDER = 'asc';
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
}

Create new controller: php artisan make:controller UsersController

Inside: app/Http/Controllers/UserController.php

<?phpnamespace App\Http\Controllers;use App\Http\Resources\UserResource;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\AnonymousResourceCollection;
class UsersController extends Controller
{
/**
* @var string[]
*/
protected array $sortFields = ['name', 'address', 'email'];
/**
* UsersController constructor.
*
* @param User $user
*/
public function __construct(public User $user)
{
}
/**
* Display a listing of the resource.
*
* @param Request $request
*
* @return AnonymousResourceCollection
*/
public function index(Request $request): AnonymousResourceCollection
{
$sortFieldInput = $request->input('sort_field', self::DEFAULT_SORT_FIELD);
$sortField = in_array($sortFieldInput, $this->sortFields) ? $sortFieldInput : self::DEFAULT_SORT_FIELD;
$sortOrder = $request->input('sort_order', self::DEFAULT_SORT_ORDER);
$searchInput = $request->input('search');
$query = $this->user->orderBy($sortField, $sortOrder);
$perPage = $request->input('per_page') ?? self::PER_PAGE;
if (!is_null($searchInput)) {
$searchQuery = "%$searchInput%";
$query = $query->where('name', 'like', $searchQuery)->orWhere('email', 'like', $searchQuery)->orWhere(
'address',
'like',
$searchQuery
);
}
$users = $query->paginate((int)$perPage);
return UserResource::collection($users);
}
}

Create UserResouce file: php artisan make:resource UserResource which will create a file called UserResource.php inside app/Http/Resources and update the content of the to following:

<?phpnamespace App\Http\Resources;use App\Models\User;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
class UserResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param $request
*
* @return array
*/
public function toArray($request): array
{
/** @var User $this */
return [
'name' => $this->name,
'email' => $this->email,
'address' => $this->address,
'created_at' => Carbon::parse($this->created_at)->toDayDateTimeString(),
];
}
}

Update routes/api.php file to include:

Route::get('/users', [UsersController::class, 'index']);

With this, we are ready with our backend api.

Frontend part:

  • Install required dependencies for bootstrap: yarn add bootstrap@next react react-dom @babel/preset-react — dev
  • Update webpack.mix.js file:
mix.js("resources/js/app.js", "public/js").react().sass("resources/sass/app.scss", "public/css");
  • Let’s create two new components inside resources/js/components:

### DataTable.js

### Paginator.js

### App.js

Now let’s create another root App component on the same directory:

--

--