update library

This commit is contained in:
JOSEPH LE 2024-02-22 14:07:40 +07:00
parent 51f9867614
commit 3292226eac
3 changed files with 131 additions and 59 deletions

View File

@ -17,6 +17,7 @@ class TableData {
enable: false, enable: false,
listColumn: [], listColumn: [],
}, },
positionCaption: "top"
}; };
constructor(tableId, config) { constructor(tableId, config) {
@ -35,19 +36,20 @@ class TableData {
) { ) {
this.config.order = null; this.config.order = null;
this.updateConfig(this.config); this.updateConfig(this.config);
// this.attachSortEventListeners(".ri-expand-up-down-fill");
} else { } else {
if (this.config.order === null) { if (this.config.order === null) {
this.config.order = { this.config.order = {
[`order_by_${column}`]: "desc", [`order_by_${column}`]: "desc",
}; };
this.updateConfig(this.config); this.updateConfig(this.config);
this.attachSortEventListeners(".ri-arrow-down-s-fill"); // this.attachSortEventListeners(".ri-arrow-down-s-fill");
} else { } else {
this.config.order = { this.config.order = {
[`order_by_${column}`]: "asc", [`order_by_${column}`]: "asc",
}; };
this.updateConfig(this.config); this.updateConfig(this.config);
this.attachSortEventListeners(".ri-arrow-up-s-fill"); // this.attachSortEventListeners(".ri-arrow-up-s-fill");
} }
} }
} }
@ -188,20 +190,20 @@ class TableData {
}); });
html += "</tbody>"; html += "</tbody>";
// Initial pagination use 'data.links' // Initial pagination use 'data.links'
let htmlPagination = `<ul class="pagination">`; let htmlPagination = `<ul class="pagination m-0">`;
data.links.map((link) => { data.links.map((link) => {
htmlPagination += ` htmlPagination += `
<li class="page-item ${link.active ? "active" : ""}"> <li class="page-item ${link.active ? "active" : ""}" style="width: 30px; height: 30px;">
<span class="page_number page-link" data-column-name="${ <span class="page_number page-link d-flex align-items-center justify-content-center" data-column-name="${
link.url !== null ? link.url.split("=")[1] : null link.url !== null ? link.url.split("=")[1] : null
}" style="cursor: pointer;">${link.label }" style="cursor: pointer; width: 30px; height: 30px;">${link.label
.replace(" Previous", "") .replace(" Previous", "")
.replace("Next ", "")}</span> .replace("Next ", "")}</span>
</li> </li>
`; `;
}); });
htmlPagination += "</ul>"; htmlPagination += "</ul>";
html += `<caption> html += `<caption style="caption-side: ${this.config.positionCaption}">
<div class="d-flex align-items-center" style="justify-content: space-between;">`; <div class="d-flex align-items-center" style="justify-content: space-between;">`;
html += `<div id="perpage"> html += `<div id="perpage">
<!-- Per page --> <!-- Per page -->
@ -251,11 +253,21 @@ class TableData {
per_page: this.config.per_page, per_page: this.config.per_page,
page: this.config.page, page: this.config.page,
}; };
let className = "";
// Clear html // Clear html
$(this.tableId).html(""); $(this.tableId).html("");
// Initial headers // Initial headers
$(this.tableId).append(this.renderHeads()); $(this.tableId).append(this.renderHeads());
this.attachSortEventListeners(".ri-expand-up-down-fill"); if (this.config.order === null) {
className = ".ri-expand-up-down-fill";
} else {
if (Object.values(this.config.order)[0] === "asc") {
className = ".ri-arrow-up-s-fill";
} else {
className = ".ri-arrow-down-s-fill";
}
}
this.attachSortEventListeners(className);
// Append 'order' and 'filter' into params if exist // Append 'order' and 'filter' into params if exist
if (this.config.hasOwnProperty("ajax")) { if (this.config.hasOwnProperty("ajax")) {
@ -359,11 +371,12 @@ class TableData {
headers: apiUpdateInfo.headers, headers: apiUpdateInfo.headers,
success: (response) => { success: (response) => {
// alert("Edit success"); // alert("Edit success");
this.notification(`Row update successful`, "success");
this.render(); this.render();
}, },
error: function (error) { error: function (error) {
console.log(error); console.log(error);
alert("Edit Fail"); this.notification(error, "danger");
}, },
}); });
} else { } else {
@ -380,4 +393,33 @@ class TableData {
this.config.per_page = $(`${this.tableId} #perPageSelect`).val(); this.config.per_page = $(`${this.tableId} #perPageSelect`).val();
this.render(); this.render();
} }
// Toast
notification(message, theme) {
var elementToRemove = document.querySelector(".toasts");
if (elementToRemove) {
elementToRemove.remove();
}
var div = document.createElement("div");
div.classList.add("toasts");
div.innerHTML = `
<div class="toast-container position-fixed bottom-0 end-0 p-3">
<div id="liveToast" class="toast text-bg-${theme} border-0" role="alert" aria-live="assertive" aria-atomic="true">
<div class="toast-header border-0">
<strong class="me-auto text-${theme}">Success</strong>
<small>now</small>
<button type="button" class="btn-close" data-bs-dismiss="toast" aria-label="Close"></button>
</div>
<div class="toast-body border-0">
${message}
</div>
</div>
</div>
`;
document.body.appendChild(div);
const toastLiveExample = document.getElementById("liveToast");
const toast = new bootstrap.Toast(toastLiveExample);
toast.show();
}
} }

View File

@ -7,11 +7,13 @@ A library used to initialize a basic data table. Includes the main components of
[Tech Stack](#tech-stack) [Tech Stack](#tech-stack)
[Initialization](#initialization) [Initialization](#initialization)
- [1. Create a table element in HTML](#1-create-a-table-element-in-html) - [1. Create a table element in HTML](#1-create-a-table-element-in-html)
- [2. Initialize a TableData class in javascript](#2-initialize-a-tabledata-class-in-javascript) - [2. Initialize a TableData class in javascript](#2-initialize-a-tabledata-class-in-javascript)
- [3. Render table](#3-render-table) - [3. Render table](#3-render-table)
[Configuration](#configuration) [Configuration](#configuration)
- [1. Structure of config variable](#1-structure-of-config-variable) - [1. Structure of config variable](#1-structure-of-config-variable)
- [2. Default configuration](#2-default-configuration) - [2. Default configuration](#2-default-configuration)
- [3. Detailed configuration](#3-detailed-configuration) - [3. Detailed configuration](#3-detailed-configuration)
@ -21,12 +23,14 @@ A library used to initialize a basic data table. Includes the main components of
[Search](#search) [Search](#search)
[Edit cell content directly](#edit-cell-content-directly) [Edit cell content directly](#edit-cell-content-directly)
- [1. Functions to use](#1-functions-to-use) - [1. Functions to use](#1-functions-to-use)
- [2. Example](#2-example) - [2. Example](#2-example)
[Sample data structure](#sample-data-structure) [Sample data structure](#sample-data-structure)
[Demo](#demo) [Demo](#demo)
## Tech Stack ## Tech Stack
**Language:** HTML, JavaScript. **Language:** HTML, JavaScript.
@ -93,6 +97,9 @@ var config = {
page: 1, page: 1,
// Number of lines on the page // Number of lines on the page
per_page: 15, per_page: 15,
// Position of caption
// Caption includes per page, detail and pagination
positionCaption: "",
}; };
``` ```
@ -117,6 +124,7 @@ config = {
enable: false, enable: false,
listColumn: [], listColumn: [],
}, },
positionCaption: "top",
}; };
``` ```
@ -125,12 +133,13 @@ _Note: The user-declared configuration will be merged with the default configura
#### 3. Detailed configuration #### 3. Detailed configuration
| Properties | Type | Description | | Properties | Type | Description |
| ---------- | ----- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | --------------- | ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| data | Array | The array contains data to render when the user wants to pass data directly to the table. By default, the library will receive this `data` variable as rendering data if the user does not declare the config.ajax attribute. | | data | Array | The array contains data to render when the user wants to pass data directly to the table. By default, the library will receive this `data` variable as rendering data if the user does not declare the config.ajax attribute. |
| order | Object | Columns are sorted by default when initialized. The syntax includes 'order*by*' + column name to sort. Example: `{order_by_id: 'desc'}` | | order | Object | Columns are sorted by default when initialized. The syntax includes 'order*by*' + column name to sort. Example: `{order_by_id: 'desc'}` |
| filter | Object | Filter based on columns declared in config.heads. Example: `{email: '@gmail.com', name: 'Jonh'}` | | filter | Object | Filter based on columns declared in config.heads. Example: `{email: '@gmail.com', name: 'Jonh'}` |
| page | Number | Current page. Default is 1. | | page | Number | Current page. Default is 1. |
| per_page | Number | Number of lines on the page. Default is 15. | | per_page | Number | Number of lines on the page. Default is 15. |
| positionCaption | String | Position of caption. Caption includes per page, detail and pagination. Values: `top`, `bottom`. |
| heads | Array | An array of objects representing the columns of the table. Each object has two fields: `name` (the column name) and `value` (the display title of the column). It can have a `render` field to customize the display of the header. | | heads | Array | An array of objects representing the columns of the table. Each object has two fields: `name` (the column name) and `value` (the display title of the column). It can have a `render` field to customize the display of the header. |
| | | | | | | |
@ -160,7 +169,7 @@ Example:
``` ```
| Properties | Type | Description | | Properties | Type | Description |
| ---------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | ---------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| rowRender | Function | A function used to customize the display of each cell in a row. Takes three parameters: `colName` (the column name), `colValue` (the value of the cell), and `row` (the data of the row). Returns an HTML string to display. | | rowRender | Function | A function used to customize the display of each cell in a row. Takes three parameters: `colName` (the column name), `colValue` (the value of the cell), and `row` (the data of the row). Returns an HTML string to display. |
Example: Example:
@ -278,11 +287,8 @@ HTML
<label for="code">Code:</label> <label for="code">Code:</label>
<input type="text" class="form-control" id="code" name="code" /> <input type="text" class="form-control" id="code" name="code" />
</div> </div>
<button <button type="button" class="btn btn-primary mt-2" onclick="getFormValues('filter')">Filter</button>
type="button" <button type="button" class="btn btn-warning mt-2" onclick="getFormValues('clear')">Clear</button>
class="btn btn-primary mt-2"
onclick="getFormValues()"
>
Filter Filter
</button> </button>
</form> </form>
@ -295,7 +301,8 @@ JS
```js ```js
// Get values from form html and append to config -> re-render with new data // Get values from form html and append to config -> re-render with new data
const getFormValues = () => { const getFormValues = (action) => {
if (action === "filter") {
const formData = {}; const formData = {};
const form = document.getElementById("filterForm"); const form = document.getElementById("filterForm");
@ -310,6 +317,12 @@ const getFormValues = () => {
} }
config.filter = formData; config.filter = formData;
}
if (action === "clear") {
config.filter = {};
}
config.page = 1;
tableData.updateConfig(config); tableData.updateConfig(config);
}; };
``` ```
@ -348,13 +361,14 @@ $("#search_input").on("keyup", function () {
### 1. Functions to use: ### 1. Functions to use:
| Function | Description | Parameters | | Function | Description | Parameters |
| -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------ | | -------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------ |
| tableData.cellEdit | Used to initialize a cell that can be edited directly. Used in `config.rowRender` | tableData.cellEdit(colName, colValue). `colName` (the column name), `colValue` (the value of the cell) | | tableData.cellEdit | Used to initialize a cell that can be edited directly. Used in `config.rowRender` | tableData.cellEdit(colName, colValue). `colName` (the column name), `colValue` (the value of the cell) |
| tableData.actionEdit | Used to initialize an edit button action to perform editing operations. Used in `config.rowRender` and usually declared in the `__actions` column. | tableData.actionEdit(row). `row` (the data of the row) | | tableData.actionEdit | Used to initialize an edit button action to perform editing operations. Used in `config.rowRender` and usually declared in the `__actions` column. | tableData.actionEdit(row). `row` (the data of the row) |
### 2. Example ### 2. Example
* `rowRender` in `config` variable - `rowRender` in `config` variable
```js ```js
rowRender: (colName, colValue, row) => { rowRender: (colName, colValue, row) => {
switch (colName) { switch (colName) {
@ -369,7 +383,8 @@ rowRender: (colName, colValue, row) => {
} }
}; };
``` ```
* Result
- Result
![OpenAI Logo](https://i.ibb.co/S36CYxj/Screenshot-2024-02-21-150628.png) ![OpenAI Logo](https://i.ibb.co/S36CYxj/Screenshot-2024-02-21-150628.png)
@ -663,14 +678,16 @@ rowRender: (colName, colValue, row) => {
} }
``` ```
### *Note: The API that retrieves the data must ensure that the data returned is in the correct structure. Additionally, the sorting and filtering functions have been reconfigured. Information on handling APIs will be updated soon!.* ### _Note: The API that retrieves the data must ensure that the data returned is in the correct structure. Additionally, the sorting and filtering functions have been reconfigured. Information on handling APIs will be updated soon!._
## Demo ## Demo
[Demo JDataTable](https://jsfiddle.net/joseph_le/eLx17fk9/880/) [Demo JDataTable](https://jsfiddle.net/joseph_le/eLx17fk9/880/)
## License ## License
[MIT](https://choosealicense.com/licenses/mit/) [MIT](https://choosealicense.com/licenses/mit/)
## Authors ## Authors
#### Joseph Le
[@JosephLe](https://github.com/luanlt632000)

View File

@ -16,7 +16,9 @@
<div class="container mt-3"> <div class="container mt-3">
<h2>JDataTable</h2> <h2>JDataTable</h2>
<p>A library used to initialize a basic data table. Includes the main components of a data table such as: sorting, per page, pagination, table. Supports additional configuration of search and filtering features.</p> <p>A library used to initialize a basic data table. Includes the main components of a data table such as:
sorting, per page, pagination, table. Supports additional configuration of search and filtering features.
</p>
<!-- Filter --> <!-- Filter -->
<div class="card mb-3"> <div class="card mb-3">
@ -31,7 +33,8 @@
<label for="code">Code:</label> <label for="code">Code:</label>
<input type="text" class="form-control" id="code" name="code"> <input type="text" class="form-control" id="code" name="code">
</div> </div>
<button type="button" class="btn btn-primary mt-2" onclick="getFormValues()">Filter</button> <button type="button" class="btn btn-primary mt-2" onclick="getFormValues('filter')">Filter</button>
<button type="button" class="btn btn-warning mt-2" onclick="getFormValues('clear')">Clear</button>
</form> </form>
</div> </div>
</div> </div>
@ -43,19 +46,17 @@
<input id="search_input" type="text" class="form-control"> <input id="search_input" type="text" class="form-control">
</div> </div>
<!-- Search --> <!-- Search -->
<!-- Table --> <!-- Table -->
<table class="table table-striped table-bordered table-hover" id="bookTabe"> <table class="table table-striped table-bordered table-hover" id="bookTabe">
</table> </table>
<!-- Table --> <!-- Table -->
<!-- Pagination --> <!-- Pagination -->
<div id="pagination"></div> <div id="pagination"></div>
<!-- Pagination --> <!-- Pagination -->
</div> </div>
<script> <script>
const token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwczovL3BheW1lbnQubnN3dGVhbS5uZXQvYXBpL3YxL2FkbWluL2xvZ2luIiwiaWF0IjoxNzA4NTY3NjcwLCJleHAiOjE3MDg2NTQwNzAsIm5iZiI6MTcwODU2NzY3MCwianRpIjoiMmRpT3RybDNxY3JFeHRrQyIsInN1YiI6IjUiLCJwcnYiOiJkMmZmMjkzMzlhOGEzZTgyYzM1ODJhNWE4ZTczOWRmMTc4OWJiMTJmIn0.7MAtakWsatvd06dQsW_VNb0kcyUBXWqIQ8xUh6f7OqA"
var config = { var config = {
// Declare configuration for table headers // Declare configuration for table headers
// 'render' function is used to customize the header // 'render' function is used to customize the header
@ -117,7 +118,7 @@
type: "GET", type: "GET",
data: params, data: params,
headers: { headers: {
Authorization: "Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwczovL3BheW1lbnQubnN3dGVhbS5uZXQvYXBpL3YxL2FkbWluL2xvZ2luIiwiaWF0IjoxNzA4NDgxMDUwLCJleHAiOjE3MDg1Njc0NTAsIm5iZiI6MTcwODQ4MTA1MCwianRpIjoid0k3alN1OWxlZHJxM3IwSiIsInN1YiI6IjUiLCJwcnYiOiJkMmZmMjkzMzlhOGEzZTgyYzM1ODJhNWE4ZTczOWRmMTc4OWJiMTJmIn0.8aWr2DlfNvQZqBiXIFaDRS8_VsARAl1TEynsuYpZcqY", // Include the token in the request header Authorization: "Bearer " + token, // Include the token in the request header
}, },
success: function (response) { success: function (response) {
resolve(response); resolve(response);
@ -134,7 +135,7 @@
url: "https://payment.nswteam.net/api/v1/admin/discount/update", url: "https://payment.nswteam.net/api/v1/admin/discount/update",
type: "POST", type: "POST",
headers: { headers: {
Authorization: "Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwczovL3BheW1lbnQubnN3dGVhbS5uZXQvYXBpL3YxL2FkbWluL2xvZ2luIiwiaWF0IjoxNzA4NDgxMDUwLCJleHAiOjE3MDg1Njc0NTAsIm5iZiI6MTcwODQ4MTA1MCwianRpIjoid0k3alN1OWxlZHJxM3IwSiIsInN1YiI6IjUiLCJwcnYiOiJkMmZmMjkzMzlhOGEzZTgyYzM1ODJhNWE4ZTczOWRmMTc4OWJiMTJmIn0.8aWr2DlfNvQZqBiXIFaDRS8_VsARAl1TEynsuYpZcqY", // Include the token in the request header Authorization: "Bearer " + token, // Include the token in the request header
}, },
}, },
footer: { footer: {
@ -145,6 +146,10 @@
enable: true, enable: true,
listColumn: ["id", "email", "code", "created_at"] listColumn: ["id", "email", "code", "created_at"]
}, },
order: {
order_by_id: 'desc'
},
positionCaption: "top"
}; };
// Initial table // Initial table
@ -152,7 +157,8 @@
tableData.render(); tableData.render();
// Get values from form html and append to config -> re-render with new data // Get values from form html and append to config -> re-render with new data
const getFormValues = () => { const getFormValues = (action) => {
if (action === 'filter') {
const formData = {}; const formData = {};
const form = document.getElementById("filterForm"); const form = document.getElementById("filterForm");
@ -167,6 +173,12 @@
} }
config.filter = formData; config.filter = formData;
}
if (action === 'clear') {
config.filter = {};
}
config.page = 1;
tableData.updateConfig(config); tableData.updateConfig(config);
}; };
@ -177,6 +189,7 @@
$(this).toggle($(this).text().toLowerCase().indexOf(value) > -1); $(this).toggle($(this).text().toLowerCase().indexOf(value) > -1);
}); });
}); });
</script> </script>
</body> </body>