Created
January 25, 2023 19:55
Revisions
-
ffflabs created this gist
Jan 25, 2023 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,11 @@ Data Table with TailwindCSS & AlpineJS -------------------------------------- Alpine Js & TailwindCSS Datatable.. Modified version of @mithicher Pen https://codepen.io/mithicher/pen/OJyRjvb A [Pen](https://codepen.io/Salmi/pen/NWjvMRY) by [salmi iliass](https://codepen.io/Salmi) on [CodePen](https://codepen.io). [License](https://codepen.io/license/pen/NWjvMRY). This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,126 @@ <body class="antialiased sans-serif bg-gray-100"> <div class="container mx-auto px-4" x-data="datatables()" x-cloak> <div x-show="selectedUsers.length" class="bg-indigo-200 fixed top-4 right-4 z-40 w-1/4 shadow"> <div class="container mx-auto px-4 py-4"> <div class="flex md:items-center"> <div class="mr-4 flex-shrink-0"> <svg class="h-8 w-8 text-indigo-600" viewBox="0 0 20 20" fill="currentColor"> <path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z" clip-rule="evenodd" /> </svg> </div> <div x-html="selectedUsers.length + ' rows are selected'" class="text-indigo-800 text-lg"></div> </div> </div> </div> <div class="border-b mb-4"> <h1 class="text-3xl py-3 border-b mb-6">Datatable</h1> <pre><strong>Source Pen :</strong> <a href="https://codepen.io/mithicher/pen/OJyRjvb" target="_blank" class="text-blue-500 hover:text-blue-700 underline">Table UI with TailwindCSS & AlpineJS by @mithicher</a> <strong>Things I added :</strong> Upgraded AlpineJS to v3 & TailwindCSS to v2 Added Search Functionality Refactor Vanilla JS Code & DOM Selectors to only AlpineJS Code.. No need for specific Class names anymore </pre> </div> <div class="mb-4 flex justify-between items-center"> <div class="flex-1 pr-4"> <div class="relative md:w-1/3"> <input type="search" x-model="search" class="w-full pl-10 pr-4 py-2 rounded-lg shadow focus:outline-none focus:shadow-outline text-gray-600 font-medium" placeholder="Search..."> <div class="absolute top-0 left-0 inline-flex items-center p-2"> <svg xmlns="http://www.w3.org/2000/svg" class="w-6 h-6 text-gray-400" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"> <rect x="0" y="0" width="24" height="24" stroke="none"></rect> <circle cx="10" cy="10" r="7" /> <line x1="21" y1="21" x2="15" y2="15" /> </svg> </div> </div> </div> <div> <div class="shadow rounded-lg flex"> <div class="relative"> <button @click.prevent="open = !open" class="rounded-lg inline-flex items-center bg-white hover:text-blue-500 focus:outline-none focus:shadow-outline text-gray-500 font-semibold py-2 px-2 md:px-4"> <svg xmlns="http://www.w3.org/2000/svg" class="w-6 h-6 md:hidden" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"> <rect x="0" y="0" width="24" height="24" stroke="none"></rect> <path d="M5.5 5h13a1 1 0 0 1 0.5 1.5L14 12L14 19L10 16L10 12L5 6.5a1 1 0 0 1 0.5 -1.5" /> </svg> <span class="hidden md:block">Display</span> <svg xmlns="http://www.w3.org/2000/svg" class="w-5 h-5 ml-1" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"> <rect x="0" y="0" width="24" height="24" stroke="none"></rect> <polyline points="6 9 12 15 18 9" /> </svg> </button> <div x-show="open" @click.away="open = false" class="z-40 absolute top-0 right-0 w-40 bg-white rounded-lg shadow-lg mt-12 -mr-1 block py-1 overflow-hidden"> <template x-for="heading in headings"> <label class="flex justify-start items-center text-truncate hover:bg-gray-100 px-4 py-2"> <div class="text-blue-600 mr-3"> <input type="checkbox" class="form-checkbox focus:outline-none focus:shadow-outline" checked @click="toggleColumn(heading.key)"> </div> <div class="select-none text-gray-700" x-text="heading.value"></div> </label> </template> </div> </div> </div> </div> </div> <div class="overflow-x-auto bg-white rounded-lg shadow overflow-y-auto relative" style="height: 405px;"> <table class="border-collapse table-auto w-full whitespace-no-wrap bg-white table-striped relative"> <thead> <tr class="text-left"> <th class="py-2 px-3 sticky top-0 border-b border-indigo-200 bg-indigo-100"> <label class="text-indigo-500 inline-flex justify-between items-center hover:bg-gray-300 px-2 py-2 rounded-lg cursor-pointer"> <input type="checkbox" class="form-checkbox focus:outline-none focus:shadow-outline" @click="selectAllCheckbox($event);"> </label> </th> <template x-for="heading in headings"> <th class="bg-indigo-100 sticky top-0 border-b border-indigo-200 px-6 py-2 text-gray-700 font-bold tracking-wider uppercase text-xs" x-text="heading.value" x-show="columns.includes(heading.key)"></th> </template> </tr> </thead> <tbody> <template x-for="user in filtered(users, 'firstName', 'lastName','emailAddress', 'phoneNumber')" :key="user.userId"> <tr> <td class="border-dashed border-t border-gray-300 px-3"> <label class="text-blue-500 inline-flex justify-between items-center hover:bg-gray-200 px-2 py-2 rounded-lg cursor-pointer"> <input type="checkbox" x-model="user.selected" class="form-checkbox rowCheckbox focus:outline-none focus:shadow-outline" :name="user.userId"> </label> </td> <td class="border-dashed border-t border-gray-300" x-show="columns.includes('userId')"> <span class="text-gray-700 px-6 py-3 flex items-center" x-text="user.userId"></span> </td> <td class="border-dashed border-t border-gray-300" x-show="columns.includes('firstName')"> <span class="text-gray-700 px-6 py-3 flex items-center" x-text="user.firstName"></span> </td> <td class="border-dashed border-t border-gray-300" x-show="columns.includes('lastName')"> <span class="text-gray-700 px-6 py-3 flex items-center" x-text="user.lastName"></span> </td> <td class="border-dashed border-t border-gray-300" x-show="columns.includes('emailAddress')"> <span class="text-gray-700 px-6 py-3 flex items-center" x-text="user.emailAddress"></span> </td> <td class="border-dashed border-t border-gray-300" x-show="columns.includes('gender')"> <span class="text-gray-700 px-6 py-3 flex items-center" x-text="user.gender"></span> </td> <td class="border-dashed border-t border-gray-300" x-show="columns.includes('phoneNumber')"> <span class="text-gray-700 px-6 py-3 flex items-center" x-text="user.phoneNumber"></span> </td> </tr> </template> </tbody> </table> </div> </div> <!-- Alpine Plugins --> <script defer src="https://unpkg.com/@alpinejs/[email protected]/dist/cdn.min.js"></script> <!-- Alpine Core --> <script defer src="https://unpkg.com/[email protected]/dist/cdn.min.js"></script> </body> </html> This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,222 @@ function datatables() { return { headings: [ { key: "userId", value: "User ID" }, { key: "firstName", value: "Firstname" }, { key: "lastName", value: "Lastname" }, { key: "emailAddress", value: "Email" }, { key: "gender", value: "Gender" }, { key: "phoneNumber", value: "Phone" } ], users: [ { selected: false, userId: 1, firstName: "Cort", lastName: "Tosh", emailAddress: "[email protected]", gender: "Male", phoneNumber: "327-626-5542" }, { selected: false, userId: 2, firstName: "Brianne", lastName: "Dzeniskevich", emailAddress: "[email protected]", gender: "Female", phoneNumber: "144-190-8956" }, { selected: false, userId: 3, firstName: "Isadore", lastName: "Botler", emailAddress: "[email protected]", gender: "Male", phoneNumber: "350-937-0792" }, { selected: false, userId: 4, firstName: "Janaya", lastName: "Klosges", emailAddress: "[email protected]", gender: "Female", phoneNumber: "502-438-7799" }, { selected: false, userId: 5, firstName: "Freddi", lastName: "Di Claudio", emailAddress: "[email protected]", gender: "Female", phoneNumber: "265-448-9627" }, { selected: false, userId: 6, firstName: "Oliy", lastName: "Mairs", emailAddress: "[email protected]", gender: "Female", phoneNumber: "221-516-2295" }, { selected: false, userId: 7, firstName: "Tabb", lastName: "Wiseman", emailAddress: "[email protected]", gender: "Male", phoneNumber: "171-817-5020" }, { selected: false, userId: 8, firstName: "Joela", lastName: "Betteriss", emailAddress: "[email protected]", gender: "Female", phoneNumber: "481-100-9345" }, { selected: false, userId: 9, firstName: "Alistair", lastName: "Vasyagin", emailAddress: "[email protected]", gender: "Male", phoneNumber: "520-669-8364" }, { selected: false, userId: 10, firstName: "Nealon", lastName: "Ratray", emailAddress: "[email protected]", gender: "Male", phoneNumber: "993-654-9793" }, { selected: false, userId: 11, firstName: "Annissa", lastName: "Kissick", emailAddress: "[email protected]", gender: "Female", phoneNumber: "283-425-2705" }, { selected: false, userId: 12, firstName: "Nissie", lastName: "Sidnell", emailAddress: "[email protected]", gender: "Female", phoneNumber: "754-391-3116" }, { selected: false, userId: 13, firstName: "Madalena", lastName: "Fouch", emailAddress: "[email protected]", gender: "Female", phoneNumber: "584-300-9004" }, { selected: false, userId: 14, firstName: "Rozina", lastName: "Atkins", emailAddress: "[email protected]", gender: "Female", phoneNumber: "792-856-0845" }, { selected: false, userId: 15, firstName: "Lorelle", lastName: "Sandcroft", emailAddress: "[email protected]", gender: "Female", phoneNumber: "882-911-7241" } ], open: false, search: '', columns: [], get selectedUsers() { return this.users.filter((user) => user.selected); }, init() { this.columns = this.headings.map((h) => { return h.key; }); }, toggleColumn(key) { this.columns.includes(key) ? (this.columns = this.columns.filter((i) => i !== key)) : this.columns.push(key); }, selectAllCheckbox() { let filteredUsers = this.filtered(this.users); if (filteredUsers.length === this.selectedUsers.length) { return filteredUsers.map((user) => (user.selected = false)); } filteredUsers.map((user) => (user.selected = true)); }, filtered(...items) { // Search filter Function for any Array of Objects ! // You can pass only the Array of Objects, // it will search all props of every Object except "ID" // Example : filtered(users) // OR you can pass additional props, it will only search passed props // Example : filtered(users, 'firstName', 'lastName','emailAddress', 'phoneNumber') values = items.shift(); // get the list of objects props = items.length ? items : null; // get list of props return values.filter((i) => { y = Object.assign({}, i); delete y['userId']; // Specifie the id prop to remove from object if (props) { okeys = Object.keys(y).filter((b) => !props.includes(b)); okeys.map((d) => delete y[d]); } itemToSearch = Object.values(y).join(); // Object to array, then join to String return itemToSearch.toLowerCase().includes(this.search.toLowerCase()); // Return filtred Object }); } }; } This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,66 @@ [x-cloak] { display: none; } /* input:checked + svg { display: block; } */ [type="checkbox"] { box-sizing: border-box; padding: 0; } .form-checkbox { -webkit-appearance: none; -moz-appearance: none; appearance: none; -webkit-print-color-adjust: exact; color-adjust: exact; display: inline-block; vertical-align: middle; background-origin: border-box; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; flex-shrink: 0; color: currentColor; background-color: #fff; border-color: #bfc0c2; border-width: 1px; border-radius: 0.25rem; height: 1.2em; width: 1.2em; } .form-checkbox:checked { background-image: url("data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='white' xmlns='http://www.w3.org/2000/svg'%3e%3cpath d='M5.707 7.293a1 1 0 0 0-1.414 1.414l2 2a1 1 0 0 0 1.414 0l4-4a1 1 0 0 0-1.414-1.414L7 8.586 5.707 7.293z'/%3e%3c/svg%3e"); border-color: transparent; background-color: currentColor; background-size: 100% 100%; background-position: center; background-repeat: no-repeat; } /* width */ ::-webkit-scrollbar { width: 0.5em; } /* Track */ ::-webkit-scrollbar-track { background: #f1f1f1; } /* Handle */ ::-webkit-scrollbar-thumb { background: #7e8590; } /* Handle on hover */ ::-webkit-scrollbar-thumb:hover { background: #555; } This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1 @@ <link href="https://cdnjs.cloudflare.com/ajax/libs/tailwindcss/2.2.4/tailwind.min.css" rel="stylesheet" />