Вход

Просмотр полной версии : undefined в POST запросе


Salvat
08.06.2016, 22:18
Здравствуйте. Имеется форма на php
<form id='submit_wall' name='funforma' >

<p><div class='textarea_stena' id='".$row['id']."' name='comment' tabindex='0' contenteditable='true' ondragend='return true' ></div>
<p> <input type='hidden' name='messageid' id='".$row['id']."' value='".$row['id']."'></p>
<div id='smiles'>
<img src='smile/1.gif'>
<img src='smile/2.gif'>
<img src='smile/3.gif'>
</div>
";

$stena_group .= '<p><a href="javascript:void(0);" onclick="comment( document.getElementById('.$row['id'].').value, '.$row['id'].' );">
Отправить</a> </p>
</form>
Код который отображает смайлики в textarea и отправляет POST запрос скрипту PHP
function comment(text, message_id){
$.ajax({
type: "POST",
url: "profile.php",
data:"comment=" + text+"&messageid="+message_id,
success: function(){
$("ul#wall").prepend("<li style=\"display: none;\">"+ text +"</li>");
$("ul#wall li:first-child").fadeIn();
}
});
return false;
};


var arr = document.getElementById('smiles').getElementsByTag Name('img');
for(var i in arr) {
if(arr.hasOwnProperty(i)) {
arr[i].onclick = function(event) {
if('img' === this.tagName.toLowerCase()) {
var img = ' <img class="emoji" src="'+this.src+'">&nbsp;';
document.execCommand('insertHTML', false, img);
}
};
}
}

Стиль textarea
.textarea_stena{background:#FFFFFF;color:black;bor der:1px solid #C0CAD5;width:328px;min-height:
40px;padding:3px 25px 3px 3px;padding-bottom:5px;margin-bottom:3px;
outline:0;-moz-border-radius:2px;-webkit-border-radius:2px;border-radius:2px;line-height:150%;word-wrap:break-word;cursor:text;}
.emoji{margin:0px;border:none;vertical-align:top;
}
Сообщения из базы данных выводятся через цикл, где в коде PHP row['id'] - это уникальный ид сообщения.
Смайлики отображаются как необходимо в textarea, только работает код только с самым первым textarea который выводит сообщение из базы данных, с другими почему-то не работает. Так же при попытке отправить POST запрос в базу записывается undefined. Если Вас не затруднит, не могли бы пожалуйста объяснить где моя ошибка с отправкой POST(ошибка undefined) и так же с передачей фокуса разным textarea с уникальными id.
Прикладываю скрин-шот
http://s16.radikal.ru/i190/1606/8e/84dfe05abb80.png (http://radikal.ru/big/fc8bb2a708b64472acbb28397392a644)
77,78,79 - это id'ы сообщений, смайлик могут отобразить только в первом 77 textarea. В другие при клике по смайлику их не отображает, но если перетащить мышкой, тогда отобразятся.

laimas
08.06.2016, 23:31
Идентификаторы должны быть уникальны.

Salvat
09.06.2016, 00:51
laimas, раньше форма имела вид
<form id='submit_wall' name='funforma' >
<p><textarea type='text' name='comment' id='".$row['id']."' value='' style='height:100p' /></textarea>
<p> <input type='hidden' name='messageid' id='".$row['id']."' value='".$row['id']."'></p> <div class='smile'>


<a href='javascript:x()' onclick=\"InsertSmile(':-*')\"><img src='smile/1.gif'/></a>
<a href='javascript:x()' onclick=\"InsertSmile(':)')\"><img src='smile/2.gif'/></a>
<a href='javascript:x()' onclick=\"InsertSmile(':(')\"><img src='smile/3.gif'/></a>
<a href='javascript:x()' onclick=\"InsertSmile(';)')\"><img src='smile/4.gif'/></a>
<a href='javascript:x()' onclick=\"InsertSmile(':P')\"><img src='smile/5.gif'/></a>
<a href='javascript:x()' onclick=\"InsertSmile('8)')\"><img src='smile/6.gif'/></a>
<a href='javascript:x()' onclick=\"InsertSmile(':D')\"><img src='smile/7.gif'/></a>
<a href='javascript:x()' onclick=\"InsertSmile('=O')\"><img src='smile/9.gif'/></a>
<a href='javascript:x()' onclick=\"InsertSmile(':-x')\"><img src='smile/10.gif'/></a>
<a href='javascript:x()' onclick=\"InsertSmile('(T_T)')\"><img src='smile/11.gif'/></a>

";

$stena_group .= '<p><a href="javascript:void(0);" onclick="comment( document.getElementById('.$row['id'].').value, '.$row['id'].' );">
Отправить</a> </p>
</form>
JavaScript без проблем отправлял POST запрос с одинаковыми id.

laimas
09.06.2016, 05:52
Серверу эти ID как собаке пятая лапа, он получает в качестве ключей имена, а вот для JS нет. Во-первых значение id не должно начинаться цифры, иначе невалидно. Но самая проблема, это обращения к объекту по его ID - JS найдет первый из них в дереве DOM, а остальные с таким же значением для него существовать не будут.

Если форма имеет множество полей и имена полей одинаковы, то имя поля должно быть ключом массива:

name="comment['.$row['id'].']"

и надобность в скрытом поле отпадает.

РНР строковые значения заключенные в двойные кавычки подвергает разбору. Вам этого не требуется, а вы напрасно заставляете это его делать.

Наведите сперва порядок с ID, а уж затем остальное.

Salvat
09.06.2016, 12:13
Если форма имеет множество полей и имена полей одинаковы, то имя поля должно быть ключом массива:

name="comment['.$row['id'].']"

и надобность в скрытом поле отпадает.
Благодарю за этот совет, только скрытое поле мне необходимо чтобы заносить id сообщения в базу данных вместе с комментарием. Для того, чтобы построить диалог, знать к какому сообщению относится комментарий.
http://s009.radikal.ru/i307/1606/f2/d3a488730325.png (http://radikal.ru/big/bfdf28a642814c58ad0feaeadfcaa953)
Это старая форма и вот сам JS
var ie=document.all?1:0;
var ns=document.getElementById&&!document.all?1:0;

function InsertSmile(SmileId)
{
if(ie)
{
document.all.comment.focus();
document.all.comment.value+=" "+SmileId+" ";
}

else if(ns)
{
document.forms['funforma'].elements['comment'].focus();
document.forms['funforma'].elements['comment'].value+=" "+SmileId+" ";
}

else
alert("ошибка браузера");
}

Меня этот код не устраивает тем, что смайлики первоначально отображаются ввиде символов. Так же только к первому textarea можно добавлять смайлики. Да, я понимаю, в коде что привожу выше, все заносится в массив. Но мне необходимо все реализовать совсем другим методом. ID сообщений в базу данных пишутся как положенно, что в первом, что во втором коде. Только код который в первом посте пишет в БД undefined.

laimas
09.06.2016, 12:20
только скрытое поле мне необходимо чтобы заносить id сообщения в базу данных вместе с комментарием.

Для этой цели оно как раз и не нужно - каждое поле формы может содержать этот ключ.

Меня этот код не устраивает тем, что смайлики первоначально отображаются ввиде символов.

А сказать где у вашего решения дыра или сами догадаетесь?

Salvat
09.06.2016, 12:24
Скажите, если не сложно, а то уже как сами видите не первый вариант пытаюсь наладить для нужного мне результата.

laimas
09.06.2016, 13:10
Вы разрешаете клиентам помещать в сообщения html-код - изображения. А для того чтобы смайлы работали они в сообщениях должны быть как есть. Это означает, что нельзя пропустить сообщение через htmlspecialchars перед выводом клиенту, что делается обязательно, чтобы не допустить на странице XSS атак. А значит любой ушлый может поместить в него куда белее вредное, нежели картинку.

Вам придется разбирать посредством рег. выражений каждый пост, отсеивая разрешенное и запрещенное. То есть ваш подход, это не лучшее, что можно сделать. Визуальные редакторы тоже используют подобное решение, но только серверу отправляется textarea, которая на время работы редактора "в тени", а данные которые в нее пишет визуальный редактор обрабатываются.

В простейшем случае таким же образом можно писать в textarea (в фоновом режиме) не html-теги, а ВВ-теги. Можно вообще без тегов обойтись, а писать :), :0), ... А в div (панели сообщения) естественно будет смайл. В этом случае форма отправляет текст, который без проблемы можно обработать htmlspecialchars, и заменить ВВ-теги или мнемоники на смайлы.

При этом при отключенном JS форма будет работать обычным способом, ваша же не сможет отправить сообщения.

Salvat
09.06.2016, 13:37
Спасибо за совет, только пока у меня проблема не с защитой, а с отправкой самого сообщения. Фильтрацию я напишу чтобы не было XSS уязвимостей. С этим я знаком.

В простейшем случае таким же образом можно писать в textarea (в фоновом режиме) не html-теги, а ВВ-теги. Можно вообще без тегов обойтись, а писать , :0), ... А в div (панели сообщения) естественно будет смайл. В этом случае форма отправляет текст, который без проблемы можно обработать htmlspecialchars, и заменить ВВ-теги или мнемоники на смайлы.

При этом при отключенном JS форма будет работать обычным способом, ваша же не сможет отправить сообщения.
Можете, пожалуйста, пояснить по побродней, не совсем понял принцип реализации данного метода.

laimas
09.06.2016, 13:57
Texarea скрывается, а все изменения в DIV записываются в нее. Это можно делать как по событию, так и по таймеру. При этом если в DIV помещен смайл, то в texarea записывается или ВВ-код [IMG] или, что вполне достаточно для смайлов, просто его мнемоника. Серверу отправляется форма, ее поля, а не то что в DIV.

Серверу достаточно обработать вывод и заменить ВВ или мнемоники на смайлы. Это все подробности.

Salvat
09.06.2016, 15:00
Не могу карму + т.к. до этого Вам уже ставил "+".
Таким образом я добился в div писать смайлы, а в скрытый input записывать его мнемоника.

<!DOCTYPE html>

<html>
<head>

<style>
.textarea_stena{background:#FFFFFF;color:black;bor der:1px solid #C0CAD5;width:328px;min-height:
40px;padding:3px 25px 3px 3px;padding-bottom:5px;margin-bottom:3px;
outline:0;-moz-border-radius:2px;-webkit-border-radius:2px;border-radius:2px;line-height:150%;word-wrap:break-word;cursor:text;}
.emoji{margin:0px;border:none;vertical-align:top;
}
</style>
</head>
<body>
<div id="smiles">
<a href='javascript:x()' onclick="InsertSmile(':-*')"><img src='smile/1.gif'/></a>
<a href='javascript:x()' onclick="InsertSmile(':)')"><img src='smile/2.gif'/></a>
<a href='javascript:x()' onclick="InsertSmile(':(')"><img src='smile/3.gif'/></a>
<a href='javascript:x()' onclick="InsertSmile(';)')"><img src='smile/4.gif'/></a>
<a href='javascript:x()' onclick="InsertSmile(':P')"><img src='smile/5.gif'/></a>
<a href='javascript:x()' onclick="InsertSmile('8)')"><img src='smile/6.gif'/></a>
<a href='javascript:x()' onclick="InsertSmile(':D')"><img src='smile/7.gif'/></a>
<a href='javascript:x()' onclick="InsertSmile('=O')"><img src='smile/9.gif'/></a>
<a href='javascript:x()' onclick="InsertSmile(':-x')"><img src='smile/10.gif'/></a>
<a href='javascript:x()' onclick="InsertSmile('(T_T)')"><img src='smile/11.gif'/></a>
</div>
<form id='submit_wall' name='funforma' >
<div class="textarea_stena" id="comment" tabindex="0" contenteditable="true" ondragend="return true"></div>
<input id="comment_text" value='' type="hidden" style='height:100p' />



</form>
<script type="text/javascript">
var arr = document.getElementById('smiles').getElementsByTag Name('img');
for(var i in arr) {
if(arr.hasOwnProperty(i)) {
arr[i].onclick = function(event) {
if('img' === this.tagName.toLowerCase()) {
var img = ' <img class="emoji" src="'+this.src+'">&nbsp;';
document.execCommand('insertHTML', false, img);
}
};
}
}
var ie=document.all?1:0;
var ns=document.getElementById&&!document.all?1:0;

function InsertSmile(SmileId)
{
if(ie)
{
document.all.comment.focus();
document.all.comment.value+=" "+SmileId+" ";
}

else if(ns)
{
document.forms['funforma'].elements['comment_text'].focus(); // тут ошибка, понять как исправить я не знаю, очень плохо знаю JS
document.forms['funforma'].elements['comment_text'].value+=" "+SmileId+" ";
}

else
alert("ошибка браузера");
}
</script>
</body>
</html>
У меня возникли следующие проблемы, это передача текста в скрытый input, и так же фокус уходит на input после вставки мнемоника. Если что-то криво, поправьте меня пожалуйста.

Salvat
09.06.2016, 15:01
Мнемоников я переведу при выводе из базы данных в смайлы при помощи PHP.

laimas
09.06.2016, 15:25
У меня возникли следующие проблемы, это передача текста в скрытый input


А он зачем? Напишите маленький скрипт - форма в которой textarea и input. Textarea в тексте имеет перевод на новую строку. Скопируйте программно значение textarea в input и отправьте форму. Что получим на сервере?

PS. щелкать можно и по изображению, которое может содержать в data-xxx мнемонику смайла, то есть без <a href='javascript:x()' onclick="InsertSmile(':-*')"> можно спокойно обойтись.

Salvat
09.06.2016, 16:16
Текст у меня получается передавать только с input в input, с DIV textarea не получается в input. Или с одного textarea в другой. Использую JS
function copy_text(val) {
document.getElementById("comment_text").value = val;
}
Форма
<form id='submit_wall' name='funforma' >
<div class="textarea_stena" id="comment" tabindex="0" contenteditable="true" ondragend="return true" onkeyup="copy_text(this.value)"></div>
<input id="comment_text" value='' type="text" style='height:100p' />



</form>
Снова получаю ошибку undefined

laimas
09.06.2016, 17:11
Еще раз - вы хотите принять комментарии (!), а это далеко не текст типа "Все Ок". Сделайте форму о которой я говорил, отправьте, поймете о чем речь.

Salvat
09.06.2016, 17:44
Может я что-то недопонимаю. Если я сделаю textarea без использования div, тогда у меня получится текст, вместо изображений, то есть : ). Я же думал сделать таким образом, чтобы в div отображались смайлики, а в скрытый input передавались мнемоники. И так же текст который выводится в textarea(div) передавался так же в input. Просто не понимаю, о какой форме имеете ввиду, она у меня вроде такая же как пишите, textarea(div) и input.

laimas
09.06.2016, 19:14
Я пишу ответ и в этом месте нажимаю Enter
что попадет в поле ввода?

execCommand будет помещать при вставках неразрывные пространства (&nbsp;), html-перевод (<br>). Если <br> заменять на \r\n, то input type=text не пришлет его на сервер.

И ковыряться серверу не зачем, он должен знать одно - от клиента получены безопасные данные, поэтому он присланное помещает в базу. При выводе в браузер он пропускает текст через htmlspacialchars и заменяет ВВ или мнемонику смайлов на изображения. И это все. Если же кто-то вставит < > или вообще код, то все это будет преобразовано в html-сущности.

Что в этом не понятного? И вообще, поле type=text не служит для целей передачи объемного текста.

Сервер локальный есть? Поместить это и запустить. Допустим на странице есть сообщения, щелчок по кнопке под ним добавляет окно визуального редактора и добавляет скрытую textarea. Все действия в редакторе отображаются в textarea, с заменой того минимума о чем сказано выше.

Отправьте форму, станет понятно. Но:

1) ищите на этом форуме, думаю должно быть, или в ином месте сети типа "вставить текст в положении курсора"

2) все не так просто взять и document.execCommand(), если требуется добавления комментария к нескольким сообщениям одной формой. На эту тему тоже есть что почитать в сети.

<?php
if($_POST) {
echo '<pre>';
print_r($_POST);
echo '</pre>';
}
?>
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<style>
.boxedit {
display: none;
}
.editor {
width: 500px;
height: 300px;
border: 1px solid #ccc;
}
</style>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
<script>
var edt = '<div class="smiles"><img sml=":-*" src="smile/1.gif"><img sml=":)" src="smile/2.gif"><img sml=":(" src="smile/3.gif"></div><div class="editor" contenteditable="true"></div><textarea></textarea>';

$(function() {
$('span[data-msg]').click(function() {
var p = $(this.parentNode);
if(!p.next('.boxedit').length) {

$('<div class="boxedit">').insertAfter(p)
.append(edt)
.find('textarea').attr('name', 'comment['+$(this).data('msg')+']').hide()
.end()
.find('.smiles').on('click', 'img', function() {
document.execCommand('insertHTML', false, ' <img sml="'+this.getAttribute('sml')+'" src="'+this.src+'"> ');
$('.editor').focus()
})
.end()
.slideDown(300)
.find('.editor')[0].oninput = function() {
$(this).closest('form')
.find('textarea')
.val(this.innerHTML
.replace(/&nbsp;/g,' ') //заменить неразрывное пространство
.replace(/<br>/g, '\n') //заменить html-перевод строки
.replace(/<img[^>]+>/g, function(i) { //смайлы
//заменить на мнемонику
//хотя могут быть нежелательные последствия
//что можно наблюдать например в Скайп, и в этом сообщении
//но можно воспользоваться ВВ-тегом
//а изображения смайлов могут иметь различные атрибуты
//которые можно обрабатывать здесь и подставляя их в ВВ
return i.match(/sml="([^"]+)"/)[1]
}))
}
}
})
});
</script>
</head>
<body>
<form autocomplete="off" method="post">
<p>text <span data-msg="123">Add comment</span></p>
<br><br><button>Send</button>
</form>
</body>
</html>

Salvat
09.06.2016, 21:58
laimas, Огромное спасибо Вам уважаемый, так работает все отлично. Прикрутил к своему коду, одна из проблем сама собой решилась, теперь комментируются как и хотел именно нужные сообщения. Подскажите, как можно сворачивать неактивные textarea, а то их можно кучу открывать за раз. И еще раз благодарю Вас:)

Salvat
09.06.2016, 22:39
Со смайликами где их разместить что-то я совсем подустал, раз задал такой вопрос, аж самому смешно. За весь день запарился)

laimas
10.06.2016, 01:00
как можно сворачивать неактивные textarea

Сперва определиться с общей логикой добавления комментариев. Например, если у какого либо сообщения уже открыта панель добавления, то она удаляется, то есть считается, что добавление отменяется. Это же действие производится, если в панели добавления нажать кнопку Отмена.

Комментарий добавляется сообщению (но не отправлен) если в панели добавления нажата кнопка Добавить. При этом панель сворачивается, из нее удаляется редактор, остается только TEXTAREA. Кнопка Add comment меняет текст на Edit comment, а ее нажатие добавляет в уже существующую панель "boxedit" редактор, предварительно загрузив в него текст из TEXTAREA с обратным преобразованием - переводы строк заменяются на <br>, мнемоники/ВВ смайлов на соответствующие изображения.

Все комментарии добавленные сообщениям помещаются в базу после отправки формы.

Но можно делать то и используя Ajax, и в этом случае будет несколько иное. То есть от общей логики работы будет и зависеть код.

Со смайликами где их разместить

Не понял.

Salvat
12.06.2016, 14:20
Не понял.

Здравствуйте. Спасибо, а на счет вывода смайликов - это то, что они выводятся в самом верху, над textarea, хотелось бы произвести вывод снизу textarea.

Salvat
12.06.2016, 14:26
Или подскажите, пожалуйста, каким образом сделать чтобы textarea была постоянно открыто, без разворачивания.

laimas
12.06.2016, 16:03
они выводятся в самом верху, над textarea, хотелось бы произвести вывод снизу textarea.

Переменная edt хранит html-код, который содержит все, переставьте DIV "smiles" после DIV "editor". И упаси господь использовать один к одному, что я написал. Это просто пример, а кнопки управления панелью и прочее добавляйте сами.

каким образом сделать чтобы textarea была постоянно открыто, без разворачивания

Она не разворачивается, ее вообще нет, она добавляется к сообщению, если выбрать добавления комментария. Разворачивается родительский элемент содержащий ее, смайлики и т.д., TEXTAREA скрыт, не видим на странице. Если TEXTAREA сразу добавить и не делать скрытым, то нужно менять логику всего скрипта.