-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
121 lines (110 loc) · 4.11 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
const apiBase = "https://api.api-onepiece.com/v2/characters/en";
const fetchButton = document.getElementById("fetch");
const characters = document.getElementById("content");
const loading = document.getElementById("loading");
const modal = document.getElementById("myModal");
const searchBar = document.getElementById("search");
const showLoading = () => loading.style.display = "block";
const hideLoading = () => loading.style.display = "none";
const showErrorMsg = () => characters.innerHTML = "<p>Something went wrong. Please try again later.</p>";
const fetchData = async () => {
showLoading();
try {
const response = await fetch(apiBase);
if (!response.ok) throw new Error('Network response was not ok');
const data = await response.json();
renderTable(data);
} catch (error) {
console.error('Fetch error:', error);
showErrorMsg();
} finally {
hideLoading();
}
};
const renderTable = (data) => {
const html = `
<table>
<thead>
<tr>
<th>Name</th>
<th>Crew</th>
<th>Bounty</th>
<th>Role</th>
</tr>
</thead>
<tbody class="table-responsive">
${data.map(character => `
<tr id="${character.id}" data-id="${character.id}">
<td>${character.name}</td>
<td>${character.crew ? character.crew.name : 'None'}</td>
<td>${character.bounty}</td>
<td>${character.job}</td>
</tr>
`).join('')}
</tbody>
</table>
`;
characters.innerHTML = html;
addRowEventListeners();
};
const addRowEventListeners = () => {
const rows = characters.querySelectorAll("tbody tr");
rows.forEach(row => {
row.addEventListener("click", () => openModal(row.dataset.id));
});
};
const closeModal = () => {
modal.style.display = "none";
};
const openModal = async (id) => {
modal.style.display = "block";
modal.innerHTML = getModalLoadingContent();
try {
const response = await fetch(`${apiBase}/${id}`);
if (!response.ok) throw new Error('Network response was not ok');
const data = await response.json();
renderModalContent(data);
} catch (error) {
console.error('Fetch error:', error);
}
};
const getModalLoadingContent = () => `
<div class="modal-content">
<div class="modal-header">
<span class="close" onclick="closeModal()">×</span>
</div>
<img src="imgs/modaloading.gif" alt="loading">
</div>`;
const renderModalContent = (data) => {
const html = `
<div class="modal-content">
<div class="modal-header">
<span class="close" onclick="closeModal()">×</span>
</div>
<h2>${data.name}</h2>
<hr style="border: 1px solid #000;">
<p><strong>Crew:</strong> ${data.crew ? data.crew.name : 'None'}</p>
<p><strong>Bounty:</strong> ${data.bounty}</p>
<p><strong>Role:</strong> ${data.job}</p>
<p><strong>Devil Fruit:</strong> ${data.devilFruit ? data.devilFruit.name : 'None'}</p>
<p><strong>Position:</strong> ${data.position}</p>
<p><strong>Height:</strong> ${data.height}</p>
<p><strong>Weight:</strong> ${data.weight}</p>
<p><strong>Age:</strong> ${data.age}</p>
</div>`;
modal.innerHTML = html;
};
const filterTable = (query) => {
const rows = characters.querySelectorAll("tbody tr");
rows.forEach(row => {
const name = row.children[0].textContent.toLowerCase();
if (name.includes(query)) {
row.style.display = "";
}
else {
row.style.display = "none";
}
});
};
fetchButton.addEventListener("click", fetchData);
searchBar.addEventListener("keyup", (event) => filterTable(event.target.value.toLowerCase()));