Сообщение от laimas
|
Вы можете вообще отказаться от формы как таковой
|
Вы предлагаете изобретать велосипед? И обрабатывать события keyup и click и может ещё какое-то, когда можно подписаться на событие submit, и вы всегда точно будете уверены, когда будет отправлена форма. (Независимо от того, каким образом она была отправлена!) Зачем бороться с тем, что упрощает?
teplov, у вас в коде никуда ничего не отправляется. Я вам уже писал, чтобы пустое сообщение не отправлялось, используйте атрибут
required.
В примере показано, как происходит отправка формы при помощи функции postChatMessage. Это единственный способ отправки. В функции проверяется, что сообщение было не пустым. Затем оно может быть оправлено. Здесь на самом деле возможно много вариантов и вариант, предложенный
laimas (и который я закомментировал в коде), в котором блокируется кнопка, пока отправляется сообщение, является менее дружелюбным к пользователю.
<form action="" class="chat" method="post" onsubmit="postChatMessage(event);">
<img src="https://picsum.photos/id/129/491/325">
<input name="message" placeholder="Add a public reply..." required autocomplete="off">
<button>Send</button>
</form>
<script>
function disableForm(form, disabled = true) {
for(const node of document.querySelectorAll("input, select, button"))
node.disabled = disabled;
}
function postChatMessage(event) {
event.preventDefault();
const form = event.target;
const input = form.querySelector("input[name=message]");
const message = input.value.trim();
if(message === "") return;
alert(`Будет отправлено: ${message}`);
// disableForm(form);
// fetch(form.action, {
// method: form.method,
// body: `message=${encodeURIComponent(message)}`
// })
// .then(response => response.json())
// .then(data => {
// if(data.ok) {
// // только когда действительно сообщение было отправлено,
// // только тогда очищаем поле ввода
// input.value = "";
// } else {
// throw new Error("Ошибка обработки сообщения на сервере");
// }
// })
// .catch(error => {
// // произошла ошибка, поле не очищаем
// // можно вывести диалог, что сообщение не было отправлено
// })
// .then(() => disableForm(form, false))
// ;
}
</script>
<style>
@import url('https://fonts.googleapis.com/css?family=Material+Icons');
html {
background: gainsboro;
}
body {
margin: 0;
}
.chat {
background: white;
display: flex;
align-items: center;
padding: 10px;
transition: 300ms;
}
.chat:focus-within {
box-shadow: 0 0 0 100vmax rgba(0, 0, 0, 0.6);
}
.chat img {
width: 50px;
height: 50px;
object-fit: cover;
border-radius: 50%;
margin-right: -55px;
margin-left: 5px;
z-index: 1;
transition: 300ms;
transform: scale(0.8);
}
.chat:not(:focus-within) img {
transform: scale(0.6);
}
.chat input[name="message"] {
flex: 1;
padding: 0px 60px;
height: 60px;
border: 0;
border-radius: 3px;
box-shadow: 0;
outline: none;
transition: 300ms;
}
.chat:focus-within input[name="message"] {
box-shadow: 0 3px 8px -2px;
}
.chat button {
border: 0;
background: none;
width: 50px;
height: 50px;
margin-left: -55px;
margin-right: 5px;
display: none;
text-transform: lowercase;
font: 2em "Material Icons";
color: #2196F3;
}
.chat input[name="message"]:valid ~ button {
display: block;
}
</style>
Вы можете эту идею взять за основу. А насчёт отправки, то не нужно ничего блокировать, как это предлагает
laimas, достаточно сразу опубликовать сообщение в чате (а значит его нужно удалить из поля ввода), и уже в дальнейшем на самом сообщении будет указываться статус («Отправка...», «Доставлено», «Прочитано», «Не удалось отправить»), и, например, в случае, когда не удалось отправить сообщение, поскольку у вас была отключена сеть, на самом сообщении будет указан статус («Не удалось отправить»), и предоставлена на сообщении кнопка «Отправить заново».