268 lines
13 KiB
HTML
268 lines
13 KiB
HTML
<!doctype html>
|
|
<html lang="ru" class="h-100">
|
|
<head>
|
|
<meta charset="utf-8" />
|
|
<title>Моя страница</title>
|
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
<script type="module" src="./node_modules/bootstrap/dist/js/bootstrap.min.js"></script>
|
|
<link href="./node_modules/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet" />
|
|
<link href="./node_modules/bootstrap-icons/font/bootstrap-icons.min.css" rel="stylesheet" />
|
|
<link rel="stylesheet" href="./css/style.css" />
|
|
</head>
|
|
|
|
<body class="h-100 d-flex flex-column">
|
|
<header>
|
|
<nav class="navbar navbar-expand-md navbar-dark">
|
|
<div class="container-fluid">
|
|
<a class="navbar-brand" href="/">
|
|
<i class="bi bi-app"></i>
|
|
Мой сайт
|
|
</a>
|
|
<button
|
|
class="navbar-toggler"
|
|
type="button"
|
|
data-bs-toggle="collapse"
|
|
data-bs-target="#navbarNav"
|
|
aria-controls="navbarNav"
|
|
aria-expanded="false"
|
|
aria-label="Toggle navigation"
|
|
>
|
|
<span class="navbar-toggler-icon"></span>
|
|
</button>
|
|
<div class="navbar-collapse collapse justify-content-end" id="navbarNav">
|
|
<div class="navbar-nav">
|
|
<a class="nav-link" href="./index.html">Главная страница</a>
|
|
<a class="nav-link" href="./page2.html">Вторая страница</a>
|
|
<a class="nav-link" href="./page3.html">Третья страница</a>
|
|
<a class="nav-link active" href="./page-js.html">JavaScript</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</nav>
|
|
</header>
|
|
<main class="container-fluid p-3">
|
|
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#studentModal">
|
|
New student
|
|
</button>
|
|
<table class="table table-sm table-hover mt-2">
|
|
<thead>
|
|
<tr>
|
|
<th scope="col">#</th>
|
|
<th scope="col">Last</th>
|
|
<th scope="col">First</th>
|
|
<th scope="col">Birthday</th>
|
|
<th scope="col">E-Mail</th>
|
|
<th scope="col">Phone</th>
|
|
<th scope="col">Group</th>
|
|
<th scope="col"></th>
|
|
</tr>
|
|
</thead>
|
|
<tbody id="students"></tbody>
|
|
</table>
|
|
|
|
<div class="modal fade" id="studentModal" tabindex="-1">
|
|
<div class="modal-dialog">
|
|
<div class="modal-content">
|
|
<form>
|
|
<div class="modal-header">
|
|
<h1 class="modal-title fs-5">Student</h1>
|
|
<button
|
|
type="button"
|
|
class="btn-close"
|
|
data-bs-dismiss="modal"
|
|
aria-label="Close"
|
|
></button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<div class="mb-3">
|
|
<label for="id" class="form-label">ID:</label>
|
|
<input type="text" class="form-control" id="id" disabled />
|
|
</div>
|
|
<div class="mb-3">
|
|
<label for="last_name" class="form-label">Last Name:</label>
|
|
<input type="text" class="form-control" id="last_name" required />
|
|
</div>
|
|
<div class="mb-3">
|
|
<label for="first_name" class="form-label">First Name:</label>
|
|
<input type="text" class="form-control" id="first_name" required />
|
|
</div>
|
|
<div class="mb-3">
|
|
<label for="bdate" class="form-label">Birth date:</label>
|
|
<input type="date" class="form-control" id="bdate" required />
|
|
</div>
|
|
<div class="mb-3">
|
|
<label for="email" class="form-label">Email:</label>
|
|
<input type="email" class="form-control" id="email" required />
|
|
</div>
|
|
<div class="mb-3">
|
|
<label for="phone" class="form-label">Phone:</label>
|
|
<input type="text" class="form-control" id="phone" required />
|
|
</div>
|
|
<div class="mb-3">
|
|
<select class="form-select" aria-label="Select group" required>
|
|
<option value="">Select group</option>
|
|
<option value="1">One</option>
|
|
<option value="2">Two</option>
|
|
<option value="3">Three</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
|
|
<button id="saveStudent" type="submit" class="btn btn-primary">Save</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</main>
|
|
<footer class="footer mt-auto d-flex flex-shrink-0 justify-content-center align-items-center">
|
|
Автор, 2022
|
|
</footer>
|
|
<script type="module">
|
|
// eslint-disable-next-line no-undef
|
|
const myModal = bootstrap.Modal.getOrCreateInstance(document.getElementById("studentModal"));
|
|
const studentForm = document.querySelector("#studentModal form");
|
|
|
|
const setModalData = (element) => {
|
|
const inputs = studentForm.querySelectorAll("input[required]");
|
|
inputs.forEach((input) => {
|
|
const control = input;
|
|
control.value = element ? element[input.getAttribute("id")] : "";
|
|
});
|
|
const idInput = studentForm.querySelector("#id");
|
|
idInput.value = element ? element.id : "";
|
|
const groupSelector = studentForm.querySelector("select");
|
|
groupSelector.value = element ? element.group.id : "";
|
|
myModal.show();
|
|
};
|
|
|
|
const modalEl = document.getElementById("studentModal");
|
|
modalEl.addEventListener("shown.bs.modal", (event) => {
|
|
if (!event.relatedTarget) {
|
|
return;
|
|
}
|
|
setModalData();
|
|
});
|
|
|
|
const addStudent = async (data) => {
|
|
const response = await fetch("http://localhost:3001/students", {
|
|
method: "post",
|
|
headers: {
|
|
"Content-Type": "application/json",
|
|
},
|
|
body: JSON.stringify(data),
|
|
});
|
|
if (!response.ok) {
|
|
throw new Error(`Response status: ${response.status}`);
|
|
}
|
|
};
|
|
|
|
const editStudent = async (id, data) => {
|
|
const response = await fetch(`http://localhost:3001/students/${id}`, {
|
|
method: "put",
|
|
headers: {
|
|
"Content-Type": "application/json",
|
|
},
|
|
body: JSON.stringify(data),
|
|
});
|
|
if (!response.ok) {
|
|
throw new Error(`Response status: ${response.status}`);
|
|
}
|
|
};
|
|
|
|
const deleteStudent = async (id) => {
|
|
// eslint-disable-next-line no-restricted-globals, no-alert
|
|
const answer = confirm(`Do you want to delete student with id = ${id}?`);
|
|
if (!answer) {
|
|
return;
|
|
}
|
|
const response = await fetch(`http://localhost:3001/students/${id}`, { method: "delete" });
|
|
if (!response.ok) {
|
|
throw new Error(`Response status: ${response.status}`);
|
|
}
|
|
};
|
|
|
|
const getStudents = async () => {
|
|
const students = document.getElementById("students");
|
|
students.innerHTML = "";
|
|
const response = await fetch("http://localhost:3001/students?_expand=group");
|
|
if (!response.ok) {
|
|
throw new Error(`Response status: ${response.status}`);
|
|
}
|
|
const data = await response.json();
|
|
data.forEach((element) => {
|
|
const createTh = (value) => {
|
|
const th = document.createElement("th");
|
|
th.setAttribute("scope", "row");
|
|
th.innerText = value;
|
|
return th;
|
|
};
|
|
const createTd = (value) => {
|
|
const td = document.createElement("td");
|
|
td.innerText = value;
|
|
return td;
|
|
};
|
|
const createButton = (text, type, action) => {
|
|
const btn = document.createElement("button");
|
|
btn.setAttribute("type", "button");
|
|
btn.classList.add("btn", type);
|
|
btn.innerHTML = text;
|
|
btn.addEventListener("click", action);
|
|
const td = document.createElement("td");
|
|
td.appendChild(btn);
|
|
return td;
|
|
};
|
|
|
|
const container = document.createElement("tr");
|
|
container.classList.add("align-middle");
|
|
container.appendChild(createTh(element.id));
|
|
container.appendChild(createTd(element.last_name));
|
|
container.appendChild(createTd(element.first_name));
|
|
container.appendChild(createTd(element.bdate));
|
|
container.appendChild(createTd(element.email));
|
|
container.appendChild(createTd(element.phone));
|
|
container.appendChild(createTd(element.group.name));
|
|
container.appendChild(
|
|
createButton("Edit", "btn-warning", async () => {
|
|
setModalData(element);
|
|
})
|
|
);
|
|
container.appendChild(
|
|
createButton("Delete", "btn-danger", async () => {
|
|
await deleteStudent(element.id);
|
|
getStudents();
|
|
})
|
|
);
|
|
students.appendChild(container);
|
|
});
|
|
console.log(data);
|
|
};
|
|
|
|
document.addEventListener("DOMContentLoaded", () => {
|
|
studentForm.addEventListener("submit", async (event) => {
|
|
event.preventDefault();
|
|
const data = {};
|
|
const inputs = studentForm.querySelectorAll("input[required]");
|
|
inputs.forEach((input) => {
|
|
data[input.getAttribute("id")] = input.value;
|
|
});
|
|
const idInput = studentForm.querySelector("#id");
|
|
const studentId = idInput.value;
|
|
const groupSelector = studentForm.querySelector("select");
|
|
data.groupId = groupSelector.value;
|
|
console.log(data);
|
|
if (!studentId) {
|
|
await addStudent(data);
|
|
} else {
|
|
await editStudent(studentId, data);
|
|
}
|
|
myModal.hide();
|
|
getStudents();
|
|
});
|
|
getStudents();
|
|
});
|
|
</script>
|
|
</body>
|
|
</html>
|