У меня есть следующая функция для обновления значений из четырех разных полей ввода:
ОБНОВЛЕНО
Мой класс пакета определяется следующим образом:
class Package {
constructor(packageID, type, weight, height, description) {
this.packageID = packageID;
this.type = type;
this.weight = weight;
this.height = height;
this.description = description;
}
getPackageId() {
return this.packageId;
}
getType() {
return this.type;
}
getWeight() {
return this.weight;
}
getHeight() {
return this.height;
}
getDescription() {
return this.description;
}/*
setPackageId(packageId){
this.packageId= packageId
return packageId;
}*/
setType(type) {
this.type = type;
return type;
}
setWeight(weight) {
this.weight = weight;
return this.weight;
}
setHeight(height) {
this.height = height;
return this.height;
}
setDescription(description) {
this.description = description;
return this.description;
}
}
let inputfieldtype = document.getElementById('selectPackageType');
let inputfieldweight = document.getElementById('floatWeight');
let inputfieldheight = document.getElementById('floatHeight');
let inputfielddescription = document.getElementById('description');
function updateValues() {
var value = this.value;
if (value == null) {
console.info('value of packege is null');
} else if (value != "" && (inputfieldtype == 'selectPackageType')) {
type = value;
} else if (value != "" && (inputfieldweight == 'floatWeight')) {
weight = value;
} else if (value != "" && (inputfieldheight == 'floatHeight')) {
height = value;
} else if (value != "" && (inputfielddescription == 'description')) {
description = value;
}
}
inputfieldweight.addEventListener('change', updateValues);
inputfieldheight.addEventListener('change', updateValues);
inputfielddescription.addEventListener('change', updateValues);
inputfieldtype.addEventListener('change', updateValues);
На данный момент я узнал, что условие моего оператора if бесполезно, потому что во всех четырех случаях строка, с которой я хочу его сравнить, истинна. Моя цель следующая: я хочу проверить, какое поле ввода было нажато, и я хочу сохранить значение этого поля в переменную.
Затем я хочу создать новый экземпляр моего класса «Пакет» и заполнить его атрибуты этими значениями.
//Create instance of package
const package = new Package();
//shoot all the values into one package
function submit() {
if (typeof package != "undefined") {
package.packageID = randomID;
package.type = type;
package.weight = weight;
package.height = height;
package.description = description;
console.info(package);
} else {
console.info(package);
}
}
Вот HTML-код
<form autocomplete = "off">
<div class = "custom-select">
<label for = "selectPackageType">Type</label>
<select id = "selectPackageType" name = "type">
<option value = "1">letter</option>
<option value = "2">package</option>
</select>
</div>
</form>
<div class = "fancy-input">
<label for = "floatWeight">Weight</label>
<input id = "floatWeight" name = "floatWeight" maxlength = "8">
</div>
<div class = "fancy-input">
<label for = "floatHeight">Height</label>
<input id = "floatHeight" name = "floatHeight" maxlength = "8">
</div>
<div class = "fancy-input">
<label for = "description">Description</label>
<input id = "description" name = "description">
</div>
<button onclick = "submit()">Submit</button>
я не думаю, что вам нужна функция updatevalue(), поскольку пользователь отправляет форму, а вы не проверяете изменения
Пара вещей... Как настроен ваш класс Package? Почему бы вам не разместить все поля ввода в форме и, когда пользователь отправит запрос, не запустить один eventListener на кнопке отправки, а затем собрать введенные поля и передать их в конструктор класса в качестве параметров?
@dalelandry Я последовал вашим предложениям, и это кажется хорошим решением.
Рад, что мои рекомендации помогли!
inputfieldtype == 'selectPackageType'
никогда не может быть правдой. inputfieldtype
— это элемент DOM, а не строка. Должно быть inputfieldtype.id == 'selectPackageType'
@Melle ... относительно моего позднего ответа, остались ли еще вопросы?
@Питер, спасибо, что спросил. Конечно, их будет несколько, но сначала мне нужно с этим справиться. К сожалению, это займет много времени, так как я могу работать над этим только один или два часа в день. Надеюсь, StackOwerflow простит мне этот комментарий, не имеющий отношения к теме.
@Мелле ... конечно, не торопись.
Я изменил свой код на следующее:
/**
* this class describes the package that should be send or collect
*/
class Package{
constructor(packageID, type, weight,height,description){
this.packageID = packageID;
this.type = type;
this.weight = weight;
this.height = height;
this.description= description;
}
getPackageId(){
return this.packageId;
}
getType(){
return this.type;
}
getWeight(){
return this.weight;
}
getHeight(){
return this.height;
}
getDescription(){
return this.description;
}
/*setPackageId(packageId){
this.packageId= packageId
return packageId;
}*/
setType(type){
this.type = type;
return type;
}
setWeight(weight){
this.weight = weight;
return this.weight;
}
setHeight(height){
this.height = height;
return this.height;
}
setDescription(description){
this.description = description;
return this.description;
}
}
//Generate PackageId
const generateID = () => Math.random().toString(36).slice(2);
//Global Variables
const randomID = generateID();
const formgetInputfields = document.getElementById("getInputfields");
const inputfieldtype = document.getElementById('selectPackageType');
const inputfieldweight = document.getElementById('floatWeight');
const inputfieldheight = document.getElementById('floatHeight');
const inputfielddescription = document.getElementById('description');
//Create instance of package
const package = new Package();
//shoot all the values into one package
function submit(){
const type = inputfieldtype.value;
const weight = inputfieldweight.value;
const height = inputfieldheight.value;
const description = inputfielddescription.value;
console.info(formgetInputfields);
if (typeof package != "undefined") {
package.packageID = randomID;
package.type = type;
package.weight = weight;
package.height = height;
package.description = description;
console.info(package);
}else {
console.info(package);
}
}
formgetInputfields.addEventListener("change", submit);
Кажется, это работает.
Изучив хорошо документированные предложения @Peter Selinger, я пришел к выводу, что эта версия работает нормально, но не является лучшим решением. Я хотел использовать классы, потому что я привык их использовать, я не знаком с модулями и это показалось хорошим решением для структурирования моего проекта. Встроенные функции, которые может предложить <form>, кажутся лучшим способом реализации моего проекта.
Я считаю, что первое предложение Питера Селигера, в котором реализованы две функции «putPackageData» и «PatchPacketData», очень хорошее.
Для простоты обслуживания/рефакторинга решение должно быть реализовано как в общем виде, так и с более высокой абстракцией.
Для варианта использования OP сначала необходимо немного реорганизовать разметку формы, включая унификацию имен элементов управления формой и имен свойств класса.
Говоря о последнем, реализация класса Package
OP вводит методы получения и установки, которые не служат никакой цели, поскольку а) все свойства в любом случае являются общедоступными и б) с реализацией установки не было введено никакой защиты. Получить/установить имеет смысл только для защищенных данных, то есть для частных данных, где можно контролировать доступ к таким данным или даже их изменение. ОП лучше использовать самую простую Package
абстракцию, включающую только общедоступные данные.
Создание экземпляра пакета всегда должно происходить относительно его узла формы. Чтобы установить такую связь, можно использовать экземпляр WeakMap, где узел формы конфигурации пакета служит ключом для его экземпляра пакета, и последний должен быть обновлен в соответствии со значением любого элемента управления формой. -изменения связанного с ним узла формы.
Можно было бы ввести ровно две функции: Package
которая создает и регистрирует экземпляр пакета, связанный с формой, и putPackageData
которая создает патч данных из текущих значений элементов формы и присваивает его экземпляру пакета, связанному с формой.
Нужно использовать, например. ...
Следующий приведенный пример кода показывает возможную реализацию только что описанного подхода, который из-за своей универсальности исправляет пакет со всеми текущими доступными данными формы каждый раз, когда изменяется одно значение элемента управления формой или форма (-node). должен обрабатывать событие отправки.
function patchPackageData(evt) {
// - prevent the form from being submitted ...
// - but only in case a real event with its own `preventDefault` method was provided.
// - see ... [https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault]
// - see ... [https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining]
evt.preventDefault?.();
const { currentTarget: formNode } = evt;
// - create a form-data instance.
// - see ... [https://developer.mozilla.org/en-US/docs/Web/API/FormData]
const formData = new FormData(formNode);
// - create an object from all form-data entries.
// - see ... [https://developer.mozilla.org/en-US/docs/Web/API/FormData/entries]
// - see ... [https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/fromEntries]
const dataPatch = Object.fromEntries([...formData.entries()]);
// - get the form-node related package instance.
// - see ... [https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap/get]
const package = packageRegistry.get(formNode);
// - assign the data-patch to the package instance.
// - see ... [https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign]
Object.assign(package, dataPatch);
console.info('PATCH package data ...', package);
}
function putPackageData(formNode) {
// - create and register the form-node related package instance.
// - see ... [https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap/set]
packageRegistry.set(
formNode, new Package({ id: formNode.dataset.packageId }),
);
console.info('PUT package data ...', packageRegistry.get(formNode));
// - assign more form-node related data to the newly created package instance.
patchPackageData({ currentTarget: formNode });
}
const packageRegistry = new WeakMap;
document
// - query every available package configuration related form-node ...
.querySelectorAll('form[data-name = "package-config"]')
// - ... where one for each form-control ...
.forEach(elmNode => {
// ... does trigger the creation and registration of the form-node related package instance.
putPackageData(elmNode);
// ... does register the correct handlers with the relevant event-types.
elmNode.addEventListener('change', patchPackageData);
elmNode.addEventListener('submit', patchPackageData);
});
body { margin: 0; }
form {
float: left;
width: 25%;
padding: 8px;
font-size: .8em;
label,
label > span {
display: block;
width: 100%;
}
label > span {
margin: 2px 0;
}
label, fieldset, [type = "submit"] {
margin: 4px 0;
}
select, input {
width: 90%;
}
}
.as-console-wrapper {
left: auto!important;
bottom: 0;
width: 44%;
min-height: 100%;
}
<form data-name = "package-config" data-package-id = "6dfc38b8-41f0-4b4f-86d8-4aea355aef79" autocomplete = "off">
<label>
<span>Type</span>
<select name = "type">
<option value = "1">letter</option>
<option value = "2">package</option>
</select>
</label>
<fieldset>
<legend>Measures</legend>
<label>
<span>Weight</span>
<input name = "weight" maxlength = "8" />
</label>
<label>
<span>Height</span>
<input name = "height" maxlength = "8" />
</label>
</fieldset>
<label>
<span>Description</span>
<input name = "description" />
</label>
<button type = "submit">Submit</button>
</form>
<form data-name = "package-config" autocomplete = "off">
<label>
<span>Type</span>
<select name = "type">
<option value = "1">letter</option>
<option value = "2" selected>package</option>
</select>
</label>
<fieldset>
<legend>Measures</legend>
<label>
<span>Weight</span>
<input name = "weight" maxlength = "8" />
</label>
<label>
<span>Height</span>
<input name = "height" maxlength = "8" />
</label>
</fieldset>
<label>
<span>Description</span>
<input name = "description" />
</label>
<button type = "submit">Submit</button>
</form>
<script>
const isStringValue = value => (typeof value === 'string');
const isNonEmptyStringValue = value => (isStringValue(value) && !!value.trim());
class Package {
// #data = {};
constructor(options) {
const { id, type, weight, height, description } = options;
// Object.assign(this.#data, {
Object.assign(this, {
id: isNonEmptyStringValue(id) && id || crypto.randomUUID(),
type: isNonEmptyStringValue(type) && type || 'not configured',
weight: isNonEmptyStringValue(weight) && weight || 'not provided',
height: isNonEmptyStringValue(height) && height || 'not provided',
description: isNonEmptyStringValue(description) && description || 'not provided',
});
}/*
get id() {
return this.#data.id;
}
get type() {
return this.#data.type;
}
get weight() {
return this.#data.weight;
}
get height() {
return this.#data.height;
}
get description() {
return this.#data.description;
}
set type(value) {
if (isNonEmptyStringValue(value)) {
this.#data.type = value;
}
return this.#data.type;
}
set weight(value) {
if (isNonEmptyStringValue(value)) {
this.#data.weight = value;
}
return this.#data.weight;
}
set height(value) {
if (isNonEmptyStringValue(value)) {
this.#data.height = value;
}
return this.#data.height;
}
set description(value) {
if (isNonEmptyStringValue(value)) {
this.#data.description = value;
}
return this.#data.description;
}
valueOf() {
return this.#data;
}
toString() {
return JSON.stringify(this.valueOf());
}
[Symbol.toPrimitive](hint) {
return (hint === 'string') && this.toString() || this.valueOf();
}*/
}
</script>
Редактировать/Обновить
Приведенное выше решение можно изменить на решение, которое создает экземпляр пакета во время инициализации (как это уже происходит), но выборочно обновляет данные пакета в соответствии с самым последним изменением значения элемента управления формой.
Для этого сценария имеет смысл реализовать класс patchPackageData
с защищенными данными с помощью реальных функций получения/установки.
function patchPackageData(evt) {
const { target: formControl, currentTarget: formNode } = evt;
let { name: key, value } = formControl;
const package = packageRegistry.get(formNode);
// update (protected by a package's setter logic).
package[key] = value;
// bidirectional update (the current package state is the single source of truth).
formControl.value = package[key];
console.info('PATCH package data ...', { id: package.id, key, value: package[key] });
}
function postPackageData(formNode) {
const formData = new FormData(formNode);
const dataPatch = Object.fromEntries([...formData.entries()]);
const package = packageRegistry.get(formNode);
// post/update.
Object.assign(package, dataPatch);
Object
.keys(dataPatch)
// bidirectional update.
.forEach(key => formNode.elements[key].value = package[key]);
console.info('POST package data ...', package.valueOf());
}
function putPackageData(formNode) {
packageRegistry.set(
formNode, new Package({ id: formNode.dataset.packageId }),
);
console.info('PUT package data ...', packageRegistry.get(formNode).valueOf());
postPackageData(formNode);
}
const packageRegistry = new WeakMap;
document
.querySelectorAll('form[data-name = "package-config"]')
.forEach(elmNode => {
putPackageData(elmNode);
elmNode.addEventListener('change', patchPackageData);
elmNode.addEventListener('submit', evt => evt.preventDefault());
});
body { margin: 0; }
form {
float: left;
width: 25%;
padding: 8px;
font-size: .8em;
label,
label > span {
display: block;
width: 100%;
}
label > span {
margin: 2px 0;
}
label, fieldset, [type = "submit"] {
margin: 4px 0;
}
select, input {
width: 90%;
}
}
.as-console-wrapper {
left: auto!important;
bottom: 0;
width: 44%;
min-height: 100%;
}
<form data-name = "package-config" data-package-id = "6dfc38b8-41f0-4b4f-86d8-4aea355aef79" autocomplete = "off">
<label>
<span>Type</span>
<select name = "type">
<option value = "1">letter</option>
<option value = "2">package</option>
</select>
</label>
<fieldset>
<legend>Measures</legend>
<label>
<span>Weight</span>
<input name = "weight" maxlength = "8" value = "20" />
</label>
<label>
<span>Height</span>
<input name = "height" maxlength = "8" />
</label>
</fieldset>
<label>
<span>Description</span>
<input name = "description" value = "letter 20/3" />
</label>
<button type = "submit">Submit</button>
</form>
<form data-name = "package-config" autocomplete = "off">
<label>
<span>Type</span>
<select name = "type">
<option value = "1">letter</option>
<option value = "2" selected>package</option>
</select>
</label>
<fieldset>
<legend>Measures</legend>
<label>
<span>Weight</span>
<input name = "weight" maxlength = "8" />
</label>
<label>
<span>Height</span>
<input name = "height" maxlength = "8" value = "5" />
</label>
</fieldset>
<label>
<span>Description</span>
<input name = "description" />
</label>
<button type = "submit">Submit</button>
</form>
<script>
const isStringValue = value => (typeof value === 'string');
const isNonEmptyStringValue = value => (isStringValue(value) && !!value.trim());
class Package {
#data = {};
constructor(options) {
const { id, type, weight, height, description } = options;
Object.assign(this.#data, {
id: isNonEmptyStringValue(id) && id || crypto.randomUUID(),
type: isNonEmptyStringValue(type) && type || 'not configured',
weight: isNonEmptyStringValue(weight) && weight || 'not provided',
height: isNonEmptyStringValue(height) && height || 'not provided',
description: isNonEmptyStringValue(description) && description || 'not provided',
});
}
get id() {
return this.#data.id;
}
get type() {
return this.#data.type;
}
get weight() {
return this.#data.weight;
}
get height() {
return this.#data.height;
}
get description() {
return this.#data.description;
}
set type(value) {
if (isNonEmptyStringValue(value)) {
this.#data.type = value;
}
return this.#data.type;
}
set weight(value) {
if (isNonEmptyStringValue(value)) {
this.#data.weight = value;
}
return this.#data.weight;
}
set height(value) {
if (isNonEmptyStringValue(value)) {
this.#data.height = value;
}
return this.#data.height;
}
set description(value) {
if (isNonEmptyStringValue(value)) {
this.#data.description = value;
}
return this.#data.description;
}
valueOf() {
return this.#data;
}
toString() {
return JSON.stringify(this.valueOf());
}
[Symbol.toPrimitive](hint) {
return (hint === 'string') && this.toString() || this.valueOf();
}
}
</script>
ок, babysteps: Мне не совсем понятно, откуда берется «formNode» в объекте «const { currentTarget: formNode }». Какую ценность это имеет? Я думаю, он представляет собой саму форму со своими значениями? Но где это определено?
@Melle ... 1/2 ... Поскольку функция-обработчик зарегистрирована в элементе формы, свойство currentTarget
переданного события содержит ссылку на сам узел формы, тогда как его target
указывает на элемент, вызвавший событие первый (здесь, скорее всего, любой из элементов управления формы). В строке const { currentTarget: formNode } = evt;
используется синтаксис деструктуризации присваивания для деструктуризации объекта вместе с псевдонимом (присвоением нового имени переменной).
@Melle ... 2/2 ... Эта линия равна const formNode = evt.currentTarget
.
class
инкапсулированы, а это означает, что переменные и методы не могут использоваться другими классами. Глобальных переменных и функций вне class
должно быть мало, если их вообще не должно быть. <form>
имеет множество встроенных функций, которые избавляют нас от необходимости писать много кода на JavaScript, а class
IMO является излишним. <form>
полагается на взаимодействие с пользователем, поэтому необходимы обработчики событий для событий «изменение», «ввод», «отправка», «клик» и т. д. Способ включения обработчиков событий в class
сложен, вот пример для всех <button>
:
class Example {
constructor(selector) {
this.nodeList = document.querySelectorAll(selector);
for (const node of this.nodeList) {
node.addEventListener("click", this.onClick.bind(this));
}
}
onClick(event) {
event.target.textContent = "You clicked me";
}
}
const x = new Example("button");
Подробности прокомментированы в примере.
<!DOCTYPE html>
<html lang = "en">
<head>
<meta charset = "UTF-8">
<meta name = "viewport" content = "width=device-width, initial-scale=1">
<title>Package Shipments</title>
<style>
:root {
font: 5vmin/1 "Segoe UI";
}
form {
display: flex;
flex-flow: row nowrap;
}
fieldset {
display: inline-block;
max-width: fit-content;
border-radius: 4px;
}
legend {
font-size: 1.2rem;
}
label {
display: inline-block;
width: 6ch;
margin-bottom: 0.5rem;
}
select,
input,
textarea,
button {
margin-bottom: 0.5rem;
font: inherit
}
select {
margin-top: 0.5rem;
padding: 0.15rem 0 0.15rem 0;
}
.buttons {
display: flex;
justify-content: flex-end;
width: 100%;
}
button {
padding: 0.2rem 0.5rem;
cursor: pointer;
}
[type = "number"] {
width: 5ch;
font-weight: 300;
font-family: Consolas;
text-align: right;
}
[for = "type"] {
margin-top: 0.5rem;
}
[for = "notes"] {
vertical-align: top;
}
textarea {
box-sizing: border-box;
width: 100%;
}
#views {
display: inline-flex;
border: 0;
}
output {
display: block;
max-width: 36ch;
margin: 1rem 0 0 2ch;
font-size: 0.6rem;
font-family: Consolas;
white-space: pre-wrap;
word-break: break-word;
line-height: 1.2;
color: blue;
}
#viewResponse {
max-width: 60ch;
color: #930;
}
</style>
</head>
<body>
<!-- #1
A HTMLFormControlsCollection on this <form> includes all form controls:
<fieldset>
<select>
<input>
<textarea>
<button>
<output>
-->
<form id = "shipments">
<fieldset>
<legend>Packages</legend>
<label for = "type">Type</label>
<!-- #2
Any form control with [required] attribute will interrupt
a "submit" event when it has no value or if the value does not
meet criteria.
-->
<select id = "type" name = "type" required>
<option value = "">Choose Type</option>
<option value = "package">Package</option>
<option value = "letter">Letter</option>
</select>
<br>
<label for = "weight">Weight</label>
<!-- #2 -->
<input id = "weight" name = "weight" type = "number" min = "0" max = "50" required>
<label for = "weight"> lbs.</label>
<br>
<label>Dimensions</label>
<br>
<label for = "width">Width</label>
<!-- #2 -->
<!-- #3
Belongs to the "dimensions" HTMLCollection.
-->
<input id = "width" name = "dimensions" type = "number" min = "4" max = "36" required>
<label for = "width"> in.</label>
<br>
<label for = "length">Length</label>
<!-- #2 -->
<!-- #3 -->
<input id = "length" name = "dimensions" type = "number" min = "6" max = "36" required>
<label for = "length"> in.</label>
<br>
<label for = "height">Height</label>
<!-- #2 -->
<!-- #3 -->
<input id = "height" name = "dimensions" type = "number" min = "0" max = "36" required>
<label for = "height"> in.</label>
<br>
<label for = "notes">Notes</label>
<br>
<textarea id = "notes" name = "notes" cols = "20" rows = "3"></textarea>
<br>
<label class = "buttons">
<!-- #4
Belongs to the "buttons" HTMLCollection.
-->
<button id = "view" name = "buttons" type = "button">View</button>
<button type = "reset">Clear</button>
<!-- #4 -->
<!-- #5
A <button> with [type = "submit"] or without any type that's
within a <form> will trigger a "submit" event when clicked.
-->
<button name = "buttons">Done</button>
</label>
</fieldset>
<fieldset id = "views">
<output id = "viewData"></output>
<output id = "viewResponse"></output>
</fieldset>
</form>
<script>
/**
* This gathers data from a <form> that has form controls
* with [name = "..."]: "type", "weight", "dimensions",
* "notes", and "buttons". The data will be formatted and it
* will be assigned a timestamp id when it is sent to a
* server.
* @param formID - #id or [name] of the <form>
*/
class Package {
constructor(formID) {
// #6 Reference the <form>
this.form = document.forms[formID];
// #7 References to all form controls (see #1)
this.io = this.form.elements;
// #8 An array of all form controls with [name = "dimensions"] (see #3)
this.dim = Array.from(this.io.dimensions);
// #9 An array of all form controls with [name = "buttons"] (see #4)
this.btn = Array.from(this.io.buttons);
// #10 This will store formatted data
this.data = {};
/* #11
Register the <select>, <textarea>, and all <input>s
(see #7) to the "change" event
*/
for (const input of this.io) {
input.addEventListener("change", this.onChange.bind(this));
}
// #12 Register all [name = "buttons"] (see #9) to the "click" event
for (const button of this.btn) {
button.addEventListener("click", this.onClick.bind(this));
}
// #13 Register <form> (see #6) to the "reset" event
this.form.addEventListener("reset", this.onReset.bind(this));
// #14 Register <form> (see #6) to the "submit" event
this.form.addEventListener("submit", this.onSubmit.bind(this));
}
/**
* This method is an event handler bound to some form
* controls (see #11) that will be invoked when the
* "change" event occurs (user leaves the form control).
* Each value entered will be assigned to a key name
* identical to the form control's [name] and formatted
* (except "type") to this.data object (see #10).
* @param event - Event object type "change"
*/
onChange(event) {
const name = event.target.name;
switch (name) {
case "type":
this.data.type = this.io.type.value;
break;
case "weight":
this.data.weight = `${this.io.weight.value} lbs.`;
break;
case "dimensions":
const wlh = this.dim
.map(d => `${d.value} in.`)
.join(` x `);
this.data.dimensions = wlh;
break;
case "notes":
this.data.notes = `\n${this.io.notes.value}`;
break;
default:
break;
}
}
/**
* This method is an event handler bound to all form
* controls with [name = "buttons"] (see #12) that will be
* invoked when the "click" event occurs (user clicks a
* <button>). Each key name and any values will be
* displayed. If the submit <button> (see #5) was
* clicked, a timestamp id will be assigned as well.
* This feature can be used to check this.data at any
* time.
* @param event - Event object type "click"
*/
onClick(event) {
this.io.viewData.textContent = `\nData\n====\n`;
if (event.target.id != "view") {
this.data.pkgid = this.pkgID();
}
["pkgid", "type", "weight", "dimensions", "notes"]
.forEach(n => {
if (!this.data[n]) {
this.data[n] = " ";
}
this.io.viewData.textContent += `${n}: ${this.data[n]}\n`;
});
}
/**
* This method is an event handler bound to the <form>
* (see #13) that will be invoked when the "reset" event
* is triggered (user clicks the <button type = "reset">).
* <form> is reset, this.data, and the <output>s are
* cleared.
* This feature can be used at any time.
* @param event - Event object type "reset"
*/
onReset(event) {
["pkgid", "type", "weight", "dimensions", "notes"]
.forEach(n => {
this.data[n] = " ";
});
this.io.views.textContent = "";
}
/**
* This method is an event handler bound to the <form>
* (see #14) that will be invoked when the "submit" event
* is triggered (user clicks the submit <button> (see #5)
* or clicks the enter/return key). A FormData object
* will be instantiated and all of this.data (see #10)
* key names/values will be assigned to it.
* this.sendPkg() method will be invoked. Normal <form>
* behavior will be prevented.
* This feature can only be used when the user has
* entered correct data in the <select> and all of the
* <input>s (see #2).
* @param event - Event object type "submit"
*/
onSubmit(event) {
const fData = new FormData();
["pkgid", "type", "weight", "dimensions", "notes"]
.forEach(n => {
fData.set(n, this.data[n]);
});
this.sendPkg(fData);
event.preventDefault();
}
/**
* This method will pass a FormData object and send it to
* a live test server. It will display the response if it
* was successful.
* @param data - FormData object
*/
async sendPkg(data) {
const response = await fetch(
"https://httpbin.org/post", {
method: "POST",
body: data
});
const json = await response.text();
this.io.viewResponse.textContent = `\nResponse\n========\n`;
this.io.viewResponse.textContent += json;
}
// This method generates a timestamp
pkgID() {
return Date.now();
}
}
// Instantiate
const pkgData = new Package("shipments");
</script>
</body>
</html>
Где вы определили свой класс Package?