форма
This commit is contained in:
48
components/news/form/controller.js
Normal file
48
components/news/form/controller.js
Normal 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);
|
||||||
54
components/news/form/model.js
Normal file
54
components/news/form/model.js
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
61
components/news/form/view.js
Normal file
61
components/news/form/view.js
Normal 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, "Сохранение", "Сохранение успешно завершено");
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user