Skip to content

Instantly share code, notes, and snippets.

@cba85
Created December 14, 2023 14:43
Show Gist options
  • Save cba85/b45f1b26b598003c0f55b27b90f14306 to your computer and use it in GitHub Desktop.
Save cba85/b45f1b26b598003c0f55b27b90f14306 to your computer and use it in GitHub Desktop.
jQuery Jikan - IPI Toulouse TSTN2A 2023/2024
function convertDateInFrench(datetime) {
if (!datetime) {
return "-";
}
const date = new Date(datetime);
return date.toLocaleDateString("fr-FR", {
year: "numeric",
month: "long",
day: "numeric",
});
}
function displayManga(data) {
return `<div class="card mt-3">
<div class="card-body">
<h4>${data.title} <span class="badge bg-primary">⭐️ ${
data.score
}</span></h4>
<h5>❤️ ${data.favorites} favorites &nbsp; 🔝 ${data.rank}</h5>
<div class="row mt-3">
<div class="col-12 col-sm-4 col-md-3 text-center">
<img src="${data.images.webp.image_url}" alt="${
data.title
}" class="img-fluid mb-3">
</div>
<div class="col-12 col-sm-8 col-md-9">
<h5>Synopsis</h5>
<p>${
data.synopsis
? data.synopsis.replace(/\n/g, "<br/>")
: "<em>No synopsis</em>"
}</p>
<h5>Background</h5>
<p>${
data.background
? data.background.replace(/\n/g, "<br/>")
: "<em>No background</em>"
}</p>
<table class="table table-striped">
<tbody>
<tr>
<th>Status</th>
<td class="text-end">${data.status}</td>
</tr>
<tr>
<th>Chapters</th>
<td class="text-end">${data.chapters ? data.chapters : "-"}</td>
</tr>
<tr>
<th>From</th>
<td class="text-end">${convertDateInFrench(data.published.from)}</td>
</tr>
<tr>
<th>To</th>
<td class="text-end">${convertDateInFrench(data.published.to)}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>`;
}
function displayAnime(data) {
return `<div class="card mt-3">
<div class="card-body">
<h4>${data.title} <span class="badge bg-primary">⭐️ ${
data.score
}</span></h4>
<h5>❤️ ${data.favorites} favorites &nbsp; 🔝 ${data.rank}</h5>
<div class="row mt-3">
<div class="col-12 col-sm-4 col-md-3 text-center">
<img src="${data.images.webp.image_url}" alt="${
data.title
}" class="img-fluid mb-3">
</div>
<div class="col-12 col-sm-8 col-md-9">
<h5>Synopsis</h5>
<p>${
data.synopsis
? data.synopsis.replace(/\n/g, "<br/>")
: "<em>No synopsis</em>"
}</p>
<h5>Background</h5>
<p>${
data.background
? data.background.replace(/\n/g, "<br/>")
: "<em>No background</em>"
}</p>
<table class="table table-striped">
<tbody>
<tr>
<th>Type</th>
<td class="text-end">${data.type}</td>
</tr>
<tr>
<th>Status</th>
<td class="text-end">${data.status}</td>
</tr>
<tr>
<th>Episodes</th>
<td class="text-end">${data.episodes ? data.episodes : "-"}</td>
</tr>
<tr>
<th>From</th>
<td class="text-end">${convertDateInFrench(data.aired.from)}</td>
</tr>
<tr>
<th>To</th>
<td class="text-end">${convertDateInFrench(data.aired.to)}</td>
</tr>
<tr>
<th>Duration</th>
<td class="text-end">${data.duration}</td>
</tr>
<tr>
<th>Rating</th>
<td class="text-end">${data.rating}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>`;
}
function displayPeople(data) {
return `<div class="card mt-3">
<div class="card-body">
<h4>${data.name} ${data.given_name}</h4>
<h5>❤️ ${data.favorites} favorites</h5>
<div class="row mt-3">
<div class="col-12 col-sm-4 col-md-3 text-center">
<img src="${data.images.jpg.image_url}" alt="${
data.name
}" class="img-fluid mb-3">
</div>
<div class="col-12 col-sm-8 col-md-9">
<h5>About</h5>
<p>${
data.about ? data.about.replace(/\n/g, "<br/>") : "<em>No information</em>"
}</p>
<table class="table table-striped">
<tbody>
<tr>
<th>Birthday</th>
<td class="text-end">${convertDateInFrench(data.birthday)}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>`;
}
function displayCharacter(data) {
return `<div class="card mt-3">
<div class="card-body">
<h4>${data.name} ${data.name_kanji}</h4>
<h5>❤️ ${data.favorites} favorites</h5>
<div class="row mt-3">
<div class="col-12 col-sm-4 col-md-3 text-center">
<img src="${data.images.jpg.image_url}" alt="${
data.name
}" class="img-fluid mb-3">
</div>
<div class="col-12 col-sm-8 col-md-9">
<h5>About</h5>
<p>${
data.about ? data.about.replace(/\n/g, "<br/>") : "<em>No information</em>"
}</p>
<table class="table table-striped">
<tbody>
<tr>
<th>Nicknames</th>
<td class="text-end">${
data.nicknames.length ? data.nicknames.join(", ") : "-"
}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>`;
}
$("#search").on("submit", function (e) {
e.preventDefault();
const q = $("#q").val();
const type = $("input[name=type]:checked").val();
if (!q || !type) {
$("#results").hide();
$("#error").text("Tous les champs sont obligatoires").fadeIn("fast");
return;
}
const validTypes = ["manga", "anime", "people", "characters"];
if (!validTypes.includes(type)) {
$("#results").hide();
$("#error").text("Type incorrect").fadeIn("fast");
return;
}
$("#error").hide();
$.get(
`https://api.jikan.moe/v4/${type}?q=${q}&order_by=favorites&sort=desc&sfw`,
function (response) {
let html = "";
html += `<h3 class="text-center mb-3">${response.pagination.items.total} résultats</h3>
<p class="mb-3 text-center"><em>Affichage des 25 premiers résultats seulement</em></p>`;
for (const data of response.data) {
if (type == "manga") {
html += displayManga(data);
} else if (type == "anime") {
html += displayAnime(data);
} else if (type == "people") {
html += displayPeople(data);
} else if (type == "characters") {
html += displayCharacter(data);
}
}
$("#results").html(html).show();
}
).fail(function () {
$("#error").text("HTTP request error").fadeIn("fast");
return;
});
});
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Anime list</title>
<link
href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css"
rel="stylesheet"
integrity="sha384-T3c6CoIi6uLrA9TneNEoa7RxnatzjcDSCmG1MXxSR1GAsXEV/Dwwykc2MPK8M2HN"
crossorigin="anonymous"
/>
<style>
:root {
--text-primary: #f86754;
}
.text-primary {
color: var(--text-primary) !important;
}
.bg-primary {
background-color: var(--text-primary) !important;
}
.btn-primary {
background-color: var(--text-primary) !important;
border-color: var(--text-primary) !important;
}
.form-check-input:checked {
background-color: var(--text-primary) !important;
border-color: var(--text-primary) !important;
}
</style>
<script
defer
src="https://cdn.jsdelivr.net/npm/jquery@3.7.1/dist/jquery.min.js"
></script>
<script defer src="/app.js"></script>
</head>
<body>
<div class="container my-5">
<h1 class="text-center text-primary">Anime list</h1>
<h4 class="text-center">
Trouvez toutes les informations sur vos mangas, animes, personnages et
auteurs préférés !
</h4>
<form class="mt-5" id="search" method="post">
<div class="mb-3">
<label for="q" class="form-label">🔎 Recherche</label>
<input type="text" class="form-control" id="q" />
</div>
<div class="mb-3">
<div class="form-check form-check-inline">
<input
class="form-check-input"
type="radio"
name="type"
id="type-manga"
value="manga"
checked
/>
<label class="form-check-label" for="type-manga">📖 Manga</label>
</div>
<div class="form-check form-check-inline">
<input
class="form-check-input"
type="radio"
name="type"
id="type-anime"
value="anime"
/>
<label class="form-check-label" for="type-anime">📺 Anime</label>
</div>
<div class="form-check form-check-inline">
<input
class="form-check-input"
type="radio"
name="type"
id="type-people"
value="people"
/>
<label class="form-check-label" for="type-people"
>👤 Personne</label
>
</div>
<div class="form-check form-check-inline">
<input
class="form-check-input"
type="radio"
name="type"
id="type-characters"
value="characters"
/>
<label class="form-check-label" for="type-characters"
>👽 Personnage</label
>
</div>
</div>
<div class="d-grid gap-2 col-12 mx-auto">
<button type="submit" class="btn btn-primary">Rechercher</button>
</div>
</form>
<div
class="alert alert-danger mt-5 text-center"
role="alert"
style="display: none"
id="error"
></div>
<div class="mt-5" id="results" style="display: none"></div>
</div>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment