Запретить ввод пустого сообщения
Всем привет!Есть чат,по кнопке send в чат отправляется пустое сообщение как от этого избавиться?Вот код формы
<div class="input-group" >
<form target="myIFR" action="" name="order">
<input id="text" type="text" class="form-control message_input" onclick ="var self = this; setTimeout(function(){self.value=''}, 50)" placeholder="введите текст" name="goodss" autocomplete="off" >
<iframe name="myIFR" style="display: none"></iframe>
</form>
<span class="input-group-btn" >
<button class="btn btn-secondary send_message" type="button"><i class="fa fa-send"></i><span class="glyphicon glyphicon-send"></span></button>
</span>
</div>
|
Цитата:
Цитата:
<button class="btn btn-secondary send_message" type="submit">которое по-умолчанию можно пропустить. Кнопка должна находиться внутри формы. Таймер можно удалить. Также вместо <i class="fa fa-send"></i><span class="glyphicon glyphicon-send"></span> можно указать просто текст. Тип текст можно не указывать. <div class="input-group"> <form target="myIFR" action="" name="order"> <input id="text" class="form-control message_input" onclick="this.value='';" placeholder="введите текст" name="goodss" autocomplete="off" required> <iframe name="myIFR" style="display: none"></iframe> <span class="input-group-btn"> <button class="btn btn-secondary send_message">Send</button> </span> </form> </div> |
Цитата:
|
Немного не так видимо изложил свою проблему ,у меня в чате появляется сообщение даже если проверку ввода в поле включить,то есть оставить одну кнопку сенд и по ней можно чат заспамить пустыми сообщениями...
|
teplov,
а на сервере фильтровать пустые сообщения? |
laimas, 👌 👍
В примере атрибут form не использовался (и на самой форме нет атрибута id), поэтому я решил, что там неправильно закрыт элемент. |
Цитата:
|
Цитата:
Обычно то, что вы отправили вам не нужно сразу вставлять в чат. Нужно чтобы сервер всем прислал текст, включая вас. (Только у вас он будет отображаться как будто вы отправитель) Тогда вы точно будете уверены, что текст был отправлен, и соответственно только тогда можно очистить поле ввода (Поскольку вы получили ответ от сервера). А если сообщение не было отправлено, то и текстовое поле не нужно очищать (Поскольку его придётся вводить заново и ещё это создаёт ложное впечатление, будто бы текст был отправлен!) Цитата:
|
Вот я и не знаю как на сервере отфильтровать...чат на сокетах вот код скрипта чата
var getMessageText, sendMessage, Message;
Message = function (arg) {
this.text = arg.text, this.message_side = arg.message_side;
this.draw = function (_this) {
return function () {
var $message;
var json = JSON.parse(_this.text);
alertChat();
return createMessage(json.text, json.name, json.photo, _this.message_side);
};
}(this);
return this;
};
getMessageText = function () {
var $message_input;
$message_input = $('.message_input');
return $message_input.val();
};
sendMessage = function (text, message_side) {
var $messages, message;
if (text.trim() === '') {
return;
}
$messages = $('.messages');
message = new Message({
text: text,
message_side: message_side
});
message.draw();
return $messages.animate({scrollTop: $messages.prop('scrollHeight')}, 300);
};
function createMessage(text, name, photo, message_side){
$message = $($('.message_template').clone().html());
if(message_side==="left"){
$message.find('.text_wrapper').removeClass("pull-left").addClass("pull-right");
$message.find('.text_wrapper').removeClass("alert-info").addClass("alert-warning");
$message.find('.name').removeClass("label-info").addClass("label-warning");
$message.find('.avatar').removeClass("pull-right").addClass("pull-left");
}
$message.find('.text').html(text);
$message.find('.name').html(name);
$message.find('.photo').attr('src', photo);
$('.messages').append($message);
$message.addClass('appeared');
}
|
Вот именно что пустые сообщения не нужны,получается пользователь жмет Enter и в чат летят пустышки,а где и что зафильтровать я не пойму,все перепробовал,но видимо не хватает у меня на старости лет ума (((
|
Цитата:
|
Представленный код, это клиентская часть, а не серверная. Кроме проверки сообщения на пустоту также необходимо блокировать кнопку отправления на время запроса и снимать блокировку после его окончания. У вас форма отправляется естественным образом, а значит сервер должен быть защищен от такой напасти как F5.
|
вот обработчик
<?php
namespace MyApp;
use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface;
require_once dirname(__FILE__) . '/../../configuration.php';
require_once dirname(__FILE__) . '/Objects/ChatObj.php';
class Chat implements MessageComponentInterface {
protected $clients;
public function __construct() {
$this->clients = new \SplObjectStorage;
}
public function onOpen(ConnectionInterface $conn) {
// Store the new connection to send messages to later
$this->clients->attach($conn);
echo "New connection! ({$conn->resourceId})\n";
}
public function onMessage(ConnectionInterface $from, $msg) {
$p = \Plugin::loadPlugin("Chat");
$object = json_decode($msg);
$canSendMessage = $p->canSendMessage($object->userId);
if(empty($canSendMessage)){
echo "Cant Send message\n";
return false;
}
//var_dump($msg);
echo "Saving message\n";
$lc = new \ChatObj(0);
$lc->setStatus('a');
$lc->setText($object->text);
$lc->setUsers_id($object->userId);
$lc->save();
$numRecv = count($this->clients) - 1;
echo sprintf('Connection %d sending message "%s" to %d other connection%s' . "\n"
, $from->resourceId, $msg, $numRecv, $numRecv == 1 ? '' : 's');
foreach ($this->clients as $client) {
if ($from !== $client) {
$client->send($msg);
}
}
}
public function onClose(ConnectionInterface $conn) {
$this->clients->detach($conn);
echo "Connection {$conn->resourceId} has disconnected\n";
}
public function onError(ConnectionInterface $conn, \Exception $e) {
echo "An error has occurred: {$e->getMessage()}\n";
$conn->close();
}
public function getTags() {
return array('free', 'chat');
}
}
|
Если метод canSendMessage(), это и есть полная проверка принятого сообщения, то пустота не запишется на сервере. А вот дубликаты вполне может принять, то есть обновление страницы по F5 или повторная отправка формы (нет блокировки).
А проблема отправления пустых сообщений клиентом, это в нем разбираться надо. |
получается нужно искать проблему тут
var getMessageText, sendMessage, Message;
Message = function (arg) {
this.text = arg.text, this.message_side = arg.message_side;
this.draw = function (_this) {
return function () {
var $message;
var json = JSON.parse(_this.text);
alertChat();
return createMessage(json.text, json.name, json.photo, _this.message_side);
};
}(this);
return this;
};
getMessageText = function () {
var $message_input;
$message_input = $('.message_input');
return $message_input.val();
};
sendMessage = function (text, message_side) {
var $messages, message;
if (text.trim() === '') {
return;
}
$messages = $('.messages');
message = new Message({
text: text,
message_side: message_side
});
message.draw();
return $messages.animate({scrollTop: $messages.prop('scrollHeight')}, 300);
};
function createMessage(text, name, photo, message_side){
$message = $($('.message_template').clone().html());
if(message_side==="left"){
$message.find('.text_wrapper').removeClass("pull-left").addClass("pull-right");
$message.find('.text_wrapper').removeClass("alert-info").addClass("alert-warning");
$message.find('.name').removeClass("label-info").addClass("label-warning");
$message.find('.avatar').removeClass("pull-right").addClass("pull-left");
}
$message.find('.text').html(text);
$message.find('.name').html(name);
$message.find('.photo').attr('src', photo);
$('.messages').append($message);
$message.addClass('appeared');
}
|
Всем спасибо за подсказки,буду дальше читать литературу может разберусь,а нет снова обращусь )))
|
Цитата:
|
Всем день добрый!вот что нашел по свое проблеме,теперь пустышки в чат не отправляются но и сообщения при f5 не сохранятся ,исходный рабочи код (отправляются пустышки)
var getMessageText, sendMessage, Message;
Message = function (arg) {
this.text = arg.text, this.message_side = arg.message_side;
this.draw = function (_this) {
return function () {
var $message;
var json = JSON.parse(_this.text);
alertChat();
return createMessage(json.text, json.name, json.photo, _this.message_side);
};
}(this);
return this;
};
getMessageText = function () {
var $message_input;
$message_input = $('.message_input');
return $message_input.val();
};
sendMessage = function (text, message_side) {
var $messages, message;
if (text.trim() === '') {
return;
}
$messages = $('.messages');
message = new Message({
text: text,
message_side: message_side
});
message.draw();
return $messages.animate({scrollTop: $messages.prop('scrollHeight')}, 300);
};
function createMessage(text, name, photo, message_side){
$message = $($('.message_template').clone().html());
if(message_side==="left"){
$message.find('.text_wrapper').removeClass("pull-left").addClass("pull-right");
$message.find('.text_wrapper').removeClass("alert-info").addClass("alert-warning");
$message.find('.name').removeClass("label-info").addClass("label-warning");
$message.find('.avatar').removeClass("pull-right").addClass("pull-left");
}
$message.find('.text').html(text);
$message.find('.name').html(name);
$message.find('.photo').attr('src', photo);
$('.messages').append($message);
$message.addClass('appeared');
}
а это чем заменил (не проходят пустышки,но и не сохраняются сообщения при перезагрузке)
(function () {
var Message;
Message = function (arg) {
this.text = arg.text, this.message_side = arg.message_side;
this.draw = function (_this) {
return function () {
var $message;
$message = $($('.message_template').clone().html());
$message.addClass(_this.message_side).find('.text').html(_this.text);
$('.messages').append($message);
return setTimeout(function () {
return $message.addClass('appeared');
}, 0);
};
}(this);
return this;
};
$(function () {
var getMessageText, message_side, sendMessage;
message_side = 'right';
getMessageText = function () {
var $message_input;
$message_input = $('.message_input');
return $message_input.val();
};
sendMessage = function (text) {
var $messages, message;
if (text.trim() === '') {
return;
}
$('.message_input').val('');
$messages = $('.messages');
message = new Message({
text: text,
message_side: message_side
});
message.draw();
return $messages.animate({ scrollTop: $messages.prop('scrollHeight') }, 300);
};
$('.send_message').click(function (e) {
return sendMessage(getMessageText());
});
$('.message_input').keyup(function (e) {
if (e.which === 13) {
return sendMessage(getMessageText());
}
});
sendMessage('Hello');
});
}.call(this));
function createMessage(text, name, photo, message_side){
$message = $($('.message_template').clone().html());
if(message_side==="left"){
$message.find('.text_wrapper').removeClass("pull-left").addClass("pull-right");
$message.find('.text_wrapper').removeClass("alert-info").addClass("alert-warning");
$message.find('.name').removeClass("label-info").addClass("label-warning");
$message.find('.avatar').removeClass("pull-right").addClass("pull-left");
}
$message.find('.text').html(text);
$message.find('.name').html(name);
$message.find('.photo').attr('src', photo);
$('.messages').append($message);
$message.addClass('appeared');
}
где что не так сделал |
Цитата:
|
ifarame стоит от перезагрузки страница при отправлении сообщения
|
Цитата:
|
Это не решит мою проблему
|
Мне нужно сделать чтоб по кнопке send не отправлялись пустые сообщения
|
вот код где они отправляются
var getMessageText, sendMessage, Message;
Message = function (arg) {
this.text = arg.text, this.message_side = arg.message_side;
this.draw = function (_this) {
return function () {
var $message;
var json = JSON.parse(_this.text);
alertChat();
return createMessage(json.text, json.name, json.photo, _this.message_side);
};
}(this);
return this;
};
getMessageText = function () {
var $message_input;
$message_input = $('.message_input');
return $message_input.val();
};
sendMessage = function (text, message_side) {
var $messages, message;
if (text.trim() === '') {
return;
}
$messages = $('.messages');
message = new Message({
text: text,
message_side: message_side
});
message.draw();
return $messages.animate({scrollTop: $messages.prop('scrollHeight')}, 300);
};
function createMessage(text, name, photo, message_side){
$message = $($('.message_template').clone().html());
if(message_side==="left"){
$message.find('.text_wrapper').removeClass("pull-left").addClass("pull-right");
$message.find('.text_wrapper').removeClass("alert-info").addClass("alert-warning");
$message.find('.name').removeClass("label-info").addClass("label-warning");
$message.find('.avatar').removeClass("pull-right").addClass("pull-left");
}
$message.find('.text').html(text);
$message.find('.name').html(name);
$message.find('.photo').attr('src', photo);
$('.messages').append($message);
$message.addClass('appeared');
}
а вот где кнопка не активна если в поле ввода нет сообщения
(function () {
var Message;
Message = function (arg) {
this.text = arg.text, this.message_side = arg.message_side;
this.draw = function (_this) {
return function () {
var $message;
$message = $($('.message_template').clone().html());
$message.addClass(_this.message_side).find('.text').html(_this.text);
$('.messages').append($message);
return setTimeout(function () {
return $message.addClass('appeared');
}, 0);
};
}(this);
return this;
};
$(function () {
var getMessageText, message_side, sendMessage;
message_side = 'right';
getMessageText = function () {
var $message_input;
$message_input = $('.message_input');
return $message_input.val();
};
sendMessage = function (text) {
var $messages, message;
if (text.trim() === '') {
return;
}
$('.message_input').val('');
$messages = $('.messages');
message_side = message_side === 'left' ? 'right' : 'left';
message = new Message({
text: text,
message_side: message_side
});
message.draw();
return $messages.animate({ scrollTop: $messages.prop('scrollHeight') }, 300);
};
$('.send_message').click(function (e) {
return sendMessage(getMessageText());
});
$('.message_input').keyup(function (e) {
if (e.which === 13) {
return sendMessage(getMessageText());
}
});
sendMessage('Hello ! :)');
});
}.call(this));
что мне из одного кода в другой вставить ? |
Не пониманию что куда все перепробовал
|
Не понятно каким образом кнопка становится недоступной, если только не скрывается посредством класса, а вообще для этого достаточно менять ее свойство disabled - true/false.
Сделайте вывод в консоль в контрольных точках, то есть значения аргументов функции, что они возвращают, найдете место конфликтное. |
Цитата:
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, достаточно сразу опубликовать сообщение в чате (а значит его нужно удалить из поля ввода), и уже в дальнейшем на самом сообщении будет указываться статус («Отправка...», «Доставлено», «Прочитано», «Не удалось отправить»), и, например, в случае, когда не удалось отправить сообщение, поскольку у вас была отключена сеть, на самом сообщении будет указан статус («Не удалось отправить»), и предоставлена на сообщении кнопка «Отправить заново». |
Цитата:
Цитата:
|
Цитата:
Цитата:
Цитата:
|
Цитата:
Если на это наплевать и заняться только "красивой стороной" вопроса, то грош цена всей вашей красоте. А вообще же активную/неактивную кнопку можно разукрасить как угодно, для этого есть :enabled/:disabled. |
Цитата:
|
Цитата:
Например, самодополняющийся текст (список товаров, городов, и пр.) в поле ввода как раз таки требует повторной отправки формы, чтобы получить варианты дополнения, и не пару раз, а много раз. (Обычно делается ограничение, например, 500мс, т. е. не более 2 раз в секунду) Кстати некоторые данные довольно редко обновляются, так что можно только один раз их скачать и уже с ними работать... а при отправке формы тогда вообще не нужно подключение к сети. Цитата:
Цитата:
Кстати, валидация поля ввода означает не только соответствие его значения определённому шаблону, но и то, что такое значение может быть принято на сервере (а значит нужен отдельный запрос на то, что такое значение возможно, и невозможно скачать заранее все такие значения, поскольку они представляют личную информацию), которое опять же будет проверено при окончательном запросе (т. е. отправке формы) Другой приём заключается в том, что после отправки валидной формы, мы её делаем невалидной, таким образом её невозможно отправлять подряд. Если этот чат, то я не вижу где тут может быть проблема, ведь имеется условие, что пустое сообщение нельзя отправлять. |
Причем тут jQuery, cURL? Просто форма, а делать кнопку неактивной или выпендриваться с флагами, это уж как вам нравится.
|
Цитата:
Цитата:
|
Цитата:
И вообще, прежде чем "а нафига, взяли сразу и поместили сообщение в ...", не плохо бы удостовериться, что сервер принял его, и не просто принял, а "норма", тем более, что вот такое:
if(empty($canSendMessage)){
echo "Cant Send message\n";
это загадка. |
| Часовой пояс GMT +3, время: 19:24. |