форма

This commit is contained in:
2025-04-16 22:13:31 +04:00
parent 3f1c93c1fb
commit 5e341c99a2
3 changed files with 163 additions and 0 deletions

View File

@@ -0,0 +1,48 @@
import FormModel from "./model";
import FormView from "./view";
class FormElement extends HTMLElement {
constructor() {
super();
this.currentId = null;
const saveCallback = this.save.bind(this);
const backCallback = this.back.bind(this);
this.view = new FormView(this, saveCallback, backCallback);
this.model = new FormModel();
}
async connectedCallback() {
const params = new URLSearchParams(document.location.search);
this.currentId = params.get("id") || null;
await this.model.getGroups();
this.view.render(this.model);
this.get();
}
async get() {
if (this.currentId) {
await this.model.get(this.currentId);
}
this.view.update(this.model);
}
async save() {
if (!this.currentId) {
await this.model.create();
}
else {
await this.model.update();
}
this.view.successToast();
this.view.update(this.model);
}
back() {
window.location.href = "/index";
}
}
customElements.define("news-form", FormElement);

View File

@@ -0,0 +1,54 @@
import { createItem, getAllItems, getItem, updateItem } from "../../api/client";
import moment from "moment";
const PATH = "news";
const DATE_DB = "DD.MM.YYYY";
const DATE_UI = "YYYY-MM-DD";
export default class FormModel {
constructor() {
this.element = {};
this.groups = [];
}
async getGroups() {
this.groups = [];
this.groups = await getAllItems("groups");
}
async get(id) {
if (!id) {
throw new Error("Element id is not defined!");
}
this.element = await getItem(PATH, id);
}
async create() {
if (!this.element || Object.keys(this.element).length === 0) {
throw new Error("Item is null or empty!");
}
this.element = await createItem(PATH, this.element);
}
async update() {
if (!this.element || Object.keys(this.element).length === 0) {
throw new Error("Item is null or empty!");
}
this.element = await updateItem(PATH, this.element.id, this.element);
}
getValue(attribute) {
if (attribute !== "bdate") {
return this.element[attribute] || "";
}
return moment(this.element[attribute], DATE_DB).format(DATE_UI);
}
setValue(attribute, value) {
if (attribute !== "bdate") {
this.element[attribute] = value;
} else {
this.element[attribute] = moment(value, DATE_UI).format(DATE_DB);
}
}
}

View File

@@ -0,0 +1,61 @@
import validation from "../../../js/validation";
import populateSelect from "../../select-helper";
import { showToast, toastsInit } from "../../toast-helper";
function getKey(input) {
return input.getAttribute("id").replace("-", "_");
}
export default class FormView {
constructor(root, saveCallback, backCallback) {
this.root = root;
this.saveCallback = saveCallback;
this.backCallback = backCallback;
}
render(model) {
const template = document.getElementById("news-form-template").content.cloneNode(true);
const form = template.querySelector("form");
form.addEventListener("submit", async () => {
if (!form.checkValidity()) {
return;
}
this.saveCallback();
});
this.inputs = template.querySelectorAll("input");
this.inputs.forEach((input) => {
input.addEventListener("change", (event) => {
model.setValue(getKey(event.target), event.target.value);
});
});
this.groupsSelector = template.getElementById("group");
this.groupsSelector.addEventListener("change", (event) => {
model.setValue("groupId", event.target.value);
});
populateSelect(this.groupsSelector, model.groups);
const backButton = template.getElementById("btn-back");
backButton.addEventListener("click", this.backCallback);
this.root.appendChild(template);
this.toasts = toastsInit();
validation();
}
update(model) {
this.inputs.forEach((input) => {
const control = input;
control.value = model.getValue(getKey(input));
});
this.groupsSelector.value = model.element.groupId || "";
}
successToast() {
showToast(this.toasts, "Сохранение", "Сохранение успешно завершено");
}
}