Create components for modal dialog and table
This commit is contained in:
parent
295a7853a2
commit
afc53ce5c3
54
js/api.js
Normal file
54
js/api.js
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
const API = "http://localhost:3001";
|
||||||
|
const STUDENTS = `${API}/students`;
|
||||||
|
const GROUPS = `${API}/groups`;
|
||||||
|
|
||||||
|
const addStudent = async (data) => {
|
||||||
|
const response = await fetch(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(`${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) => {
|
||||||
|
const response = await fetch(`${STUDENTS}/${id}`, { method: "delete" });
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error(`Response status: ${response.status}`);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const getGroups = async () => {
|
||||||
|
const response = await fetch(GROUPS);
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error(`Response status: ${response.status}`);
|
||||||
|
}
|
||||||
|
return response.json();
|
||||||
|
};
|
||||||
|
|
||||||
|
const getStudents = async () => {
|
||||||
|
const response = await fetch(`${STUDENTS}?_expand=group`);
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error(`Response status: ${response.status}`);
|
||||||
|
}
|
||||||
|
return response.json();
|
||||||
|
};
|
||||||
|
|
||||||
|
export { addStudent, deleteStudent, editStudent, getGroups, getStudents };
|
48
js/uimodal.js
Normal file
48
js/uimodal.js
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
const studentModal = (idModal, callback) => {
|
||||||
|
const modalEl = document.getElementById(idModal);
|
||||||
|
// eslint-disable-next-line no-undef
|
||||||
|
const myModal = bootstrap.Modal.getOrCreateInstance(modalEl);
|
||||||
|
const studentForm = document.querySelector(`#${idModal} 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();
|
||||||
|
};
|
||||||
|
|
||||||
|
modalEl.addEventListener("shown.bs.modal", (event) => {
|
||||||
|
if (!event.relatedTarget) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setModalData();
|
||||||
|
});
|
||||||
|
|
||||||
|
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);
|
||||||
|
myModal.hide();
|
||||||
|
if (callback) {
|
||||||
|
callback(studentId, data);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return { setData: (element) => setModalData(element) };
|
||||||
|
};
|
||||||
|
|
||||||
|
export default studentModal;
|
59
js/uitable.js
Normal file
59
js/uitable.js
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
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 studentTable = (tableId, editCallback, deleteCallback) => {
|
||||||
|
const draw = async (data) => {
|
||||||
|
const students = document.getElementById(tableId);
|
||||||
|
students.innerHTML = "";
|
||||||
|
|
||||||
|
data.forEach((element) => {
|
||||||
|
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 () => {
|
||||||
|
if (editCallback) {
|
||||||
|
editCallback(element);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
container.appendChild(
|
||||||
|
createButton("Delete", "btn-danger", async () => {
|
||||||
|
if (deleteCallback) {
|
||||||
|
deleteCallback(element.id);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
students.appendChild(container);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return { draw };
|
||||||
|
};
|
||||||
|
|
||||||
|
export default studentTable;
|
174
page-js.html
174
page-js.html
@ -120,147 +120,53 @@
|
|||||||
Автор, 2022
|
Автор, 2022
|
||||||
</footer>
|
</footer>
|
||||||
<script type="module">
|
<script type="module">
|
||||||
// eslint-disable-next-line no-undef
|
import { addStudent, editStudent, getStudents, deleteStudent, getGroups } from "./js/api";
|
||||||
const myModal = bootstrap.Modal.getOrCreateInstance(document.getElementById("studentModal"));
|
import studentModal from "./js/uimodal";
|
||||||
const studentForm = document.querySelector("#studentModal form");
|
import studentTable from "./js/uitable";
|
||||||
|
|
||||||
const setModalData = (element) => {
|
const studentModalDialog = studentModal("studentModal", async (studentId, data) => {
|
||||||
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) {
|
if (!studentId) {
|
||||||
await addStudent(data);
|
await addStudent(data);
|
||||||
} else {
|
} else {
|
||||||
await editStudent(studentId, data);
|
await editStudent(studentId, data);
|
||||||
}
|
}
|
||||||
myModal.hide();
|
// eslint-disable-next-line no-use-before-define
|
||||||
getStudents();
|
getStudentsLogic();
|
||||||
});
|
});
|
||||||
getStudents();
|
|
||||||
|
const deleteStudentLogic = 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;
|
||||||
|
}
|
||||||
|
deleteStudent(id);
|
||||||
|
};
|
||||||
|
|
||||||
|
const studentTableUI = studentTable(
|
||||||
|
"students",
|
||||||
|
async (element) => studentModalDialog.setData(element),
|
||||||
|
async (id) => deleteStudentLogic(id)
|
||||||
|
);
|
||||||
|
|
||||||
|
const getGroupsLogic = async () => {
|
||||||
|
const groups = document.querySelector("#studentModal form select");
|
||||||
|
groups.innerHTML = `<option value="">Select group</option>`;
|
||||||
|
const data = await getGroups();
|
||||||
|
data.forEach((element) => {
|
||||||
|
groups.innerHTML += `<option value="${element.id}">${element.name}</option>`;
|
||||||
|
});
|
||||||
|
console.log("groups", data);
|
||||||
|
};
|
||||||
|
|
||||||
|
const getStudentsLogic = async () => {
|
||||||
|
getGroupsLogic();
|
||||||
|
const data = await getStudents();
|
||||||
|
studentTableUI.draw(data);
|
||||||
|
};
|
||||||
|
|
||||||
|
document.addEventListener("DOMContentLoaded", () => {
|
||||||
|
getStudentsLogic();
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
Loading…
Reference in New Issue
Block a user