Hi, I want to create several tables on a webpage and dynamically populate it using an API call. Is it possible in bootstrap studio or will I have to use custom code?
Any resources to help me achieve my goal to would appreciated
Hi, I want to create several tables on a webpage and dynamically populate it using an API call. Is it possible in bootstrap studio or will I have to use custom code?
Any resources to help me achieve my goal to would appreciated
Bootstrap studio does not have a built in function for this, you shall have to create a solution using JavaScript, or backend logic once you have designed and exported your site.
You can do it like this
link simple-datatables css
external css https://cdn.jsdelivr.net/npm/simple-datatables@latest/dist/style.css
HTML markup
<div class="container mt-5">
<div id="input-area">
<input type="text"
id="api-input"
class="form-control"
placeholder="Enter API URL (must return array of objects)"
>
<button class="btn btn-success"
id="add-api-btn" type="button">Add Table</button>
</div>
</div>
<div id="tables-container" class="container mt-5"></div>
Javascript
main.mjs
import { DataTable } from 'https://esm.sh/simple-datatables';
const container = document.getElementById('tables-container');
const input = document.getElementById('api-input');
const addButton = document.getElementById('add-api-btn');
let tableCounter = 0;
// Default APIs
const initialApiUrls = [
'https://yoursite.com/api1',
'https://yoursite.com/api2',
// add more if needed
];
const extractArrayFromResponse = (data) => {
if (Array.isArray(data)) return data;
for (const value of Object.values(data)) {
if (Array.isArray(value) && value.length && typeof value[0] === 'object') {
return value;
}
}
return [];
};
const createTableFromApi = async (apiUrl) => {
try {
const response = await fetch(apiUrl);
const rawData = await response.json();
const data = extractArrayFromResponse(rawData);
if (!Array.isArray(data) || data.length === 0) {
console.warn(`No array data from ${apiUrl}`);
return;
}
const keys = Object.keys(data[0]);
const rows = data.map((item) =>
keys.map((key) => {
const value = item[key];
if (value instanceof Date) {
return value.toLocaleDateString();
} else if (typeof value === 'string' && !isNaN(Date.parse(value))) {
return new Date(value).toLocaleDateString();
} else if (value && typeof value === 'object') {
return JSON.stringify(value);
}
return value;
})
);
const numberColumns = keys
.map((key, i) =>
data.some((item) => typeof item[key] === 'number') ? i : null
)
.filter((i) => i !== null);
const tableId = `table-${tableCounter++}`;
const details = document.createElement('details');
details.open = true;
const summary = document.createElement('summary');
summary.textContent = `Data from ${apiUrl}`;
details.appendChild(summary);
const tableWrapper = document.createElement('div');
tableWrapper.innerHTML = `<table id="${tableId}" class="table"></table>`;
details.appendChild(tableWrapper);
container.appendChild(details);
const dataTable = new DataTable(`#${tableId}`, {
searchable: true,
fixedHeight: true,
perPage: 5,
data: {
headings: keys.map((key) => key.charAt(0).toUpperCase() + key.slice(1)),
data: rows,
},
columns: numberColumns.map((colIndex) => ({
select: colIndex,
type: 'number',
format: (val) => val,
cellClass: 'text-end',
})),
});
dataTable.on('datatable.init', () => {
const headerRow = document.querySelector(`#${tableId} thead tr`);
if (headerRow) {
numberColumns.forEach((colIndex) => {
const th = headerRow.children[colIndex];
if (th) th.classList.add('text-end');
});
}
});
} catch (error) {
console.error(`Error loading ${apiUrl}:`, error);
}
};
// Load initial tables
initialApiUrls.forEach(createTableFromApi);
// Add button listener
addButton.addEventListener('click', () => {
const url = input.value.trim();
if (url) {
createTableFromApi(url);
input.value = '';
}
});
here is an example