I want to organize some JavaScript code using module pattern.
The scenario is as follows: Having the following html table created dynamically
<table class="table table-hover">
<tbody>
<tr>
<td colspan="2" style="border-top: 0">2018-03-27</td>
</tr>
<tr>
<td data-id="8" data-user="Yesenia" data-classroom="D101" data-date="2018-03-27" style="vertical-align: middle;">
<a href="http://localhost:8080/ds/request/show/8">Yesenia en D101</a>
</td>
<td width="1">
<form action="http://localhost:8080/ds/request/delete/8" method="POST" value="DELETE" onsubmit="if (!confirm('¿Estás seguro?')) return false;" style="margin: 0;">
<input name="_method" value="DELETE" type="hidden">
<button type="submit" class="btn btn-link btn-small">
<i class="icon-trash"></i>
</button>
</form>
</td>
</tr>
<tr>
<td colspan="2">2018-03-26</td>
</tr>
<tr>
<td data-id="1" data-user="user user" data-classroom="D101" data-date="2018-03-26" style="vertical-align: middle;">
<a href="http://localhost:8080/ds/request/show/1">user user en D101</a>
</td>
<td width="1">
<form action="http://localhost:8080/ds/request/delete/1" method="POST" value="DELETE" onsubmit="if (!confirm('¿Estás seguro?')) return false;" style="margin: 0;">
<input name="_method" value="DELETE" type="hidden">
<button type="submit" class="btn btn-link btn-small">
<i class="icon-trash"></i>
</button>
</form>
</td>
</tr>
<tr>
<td data-id="2" data-user="user user" data-classroom="D102" data-date="2018-03-26" style="vertical-align: middle;">
<a href="http://localhost:8080/ds/request/show/2">user user en D102</a>
</td>
<td width="1">
<form action="http://localhost:8080/ds/request/delete/2" method="POST" value="DELETE" onsubmit="if (!confirm('¿Estás seguro?')) return false;" style="margin: 0;">
<input name="_method" value="DELETE" type="hidden">
<button type="submit" class="btn btn-link btn-small">
<i class="icon-trash"></i>
</button>
</form>
</td>
</tr>
<tr>
<td data-id="7" data-user="Yesenia" data-classroom="D103" data-date="2018-03-26" style="vertical-align: middle;">
<a href="http://localhost:8080/ds/request/show/7">Yesenia en D103</a>
</td>
<td width="1">
<form action="http://localhost:8080/ds/request/delete/7" method="POST" value="DELETE" onsubmit="if (!confirm('¿Estás seguro?')) return false;" style="margin: 0;">
<input name="_method" value="DELETE" type="hidden">
<button type="submit" class="btn btn-link btn-small">
<i class="icon-trash"></i>
</button>
</form>
</td>
</tr>
<tr>
<td data-id="9" data-user="Cesar" data-classroom="D101" data-date="2018-03-26" style="vertical-align: middle;">
<a href="http://localhost:8080/ds/request/show/9">Cesar en D101</a>
</td>
<td width="1">
<form action="http://localhost:8080/ds/request/delete/9" method="POST" value="DELETE" onsubmit="if (!confirm('¿Estás seguro?')) return false;" style="margin: 0;">
<input name="_method" value="DELETE" type="hidden">
<button type="submit" class="btn btn-link btn-small">
<i class="icon-trash"></i>
</button>
</form>
</td>
</tr>
</tbody>
</table>
And an input to filter the table
<input id="filter" placeholder="Filtrar...">
The following JavaScript logic is implemented to allow filter the table
const dataset = Array.from(document.querySelectorAll('[data-id]')).map(td => Object.assign({}, td.dataset));
const trigger = document.querySelector('#filter');
const serverURL = window.serverURL;
function applyFilter(event) {
const results = dataset.filter(data => data.user.toLowerCase().includes(event.target.value));
render(results);
}
function render(dataset) {
let date = null;
const rows = [];
dataset.forEach((data, index) => {
if (data.date !== date) {
rows.push(renderDateRow(data.date, index));
}
rows.push(renderDataRow(data));
date = data.date;
});
document.querySelector('table tbody').innerHTML = rows.join('');
}
function renderDateRow(date, index) {
return `<tr>
<td colspan="2" ${index === 0 ? 'style="border-top: 0"' : ''}>${date}</td>
</tr>`;
}
function renderDataRow(data) {
return `<tr>
<td
data-id="${data.id}"
data-user="${data.user}"
data-classroom="${data.classroom}"
data-date="${data.date}"
style="vertical-align: middle;">
<a href="${serverURL}/request/show/${data.id}">${data.user} en ${data.classroom}</a>
</td>
<td width="1">
<form
action="${serverURL}/request/delete/${data.id}"
method="POST"
value="DELETE"
onSubmit="if (!confirm('¿Estás seguro?')) return false;"
style="margin: 0;">
<input type="hidden" name="_method" value="DELETE">
<button type="submit" class="btn btn-link btn-small">
<i class="icon-trash"></i>
</button>
</form>
</td>
</tr>`;
}
trigger.addEventListener('keyup', applyFilter);
I use Module pattern in order to organize the code, the final implementation looks like this:
const FilterModule = (() => {
const dataset = Array.from(document.querySelectorAll('[data-id]')).map(td => Object.assign({}, td.dataset));
function loadServerURL() {
return window.serverURL;
}
function applyFilter(event) {
const results = dataset.filter(data => data.user.toLowerCase().includes(event.target.value));
render(results);
}
function loadTrigger() {
document.querySelector('#filter').addEventListener('keyup', applyFilter);
}
function render(dataset) {
let date = null;
const rows = [];
dataset.forEach((data, index) => {
if (data.date !== date) {
rows.push(renderDateRow(data.date, index));
}
rows.push(renderDataRow(data));
date = data.date;
});
document.querySelector('table tbody').innerHTML = rows.join('');
}
function renderDateRow(date, index) {
return `<tr>
<td colspan="2" ${index === 0 ? 'style="border-top: 0"' : ''}>${date}</td>
</tr>`;
}
function renderDataRow(data) {
const serverURL = loadServerURL();
return `<tr>
<td
data-id="${data.id}"
data-user="${data.user}"
data-classroom="${data.classroom}"
data-date="${data.date}"
style="vertical-align: middle;">
<a href="${serverURL}/request/show/${data.id}">${data.user} en ${data.classroom}</a>
</td>
<td width="1">
<form
action="${serverURL}/request/delete/${data.id}"
method="POST"
value="DELETE"
onSubmit="if (!confirm('¿Estás seguro?')) return false;"
style="margin: 0;">
<input type="hidden" name="_method" value="DELETE">
<button type="submit" class="btn btn-link btn-small">
<i class="icon-trash"></i>
</button>
</form>
</td>
</tr>`;
}
function init() {
loadTrigger();
}
return {
init
};
})();
FilterModule.init();
I thank you for any comments in order to better organize the code