| Да все просто делается. Атрибуту target фрмы указываете имя фрейма как целевого контейнера ответа сервера. По событию onload фрейма (когда он получит ответ на отправку формы), можете сразу перегрузить содержимое фрейма в DIV:
onload="window.document.getElementById('as').innerHTML= frame.document.body.innerHTML
где 'as' это id DIV в который перегружаем ответ сервера. IFARANE, DIV и форма, все они пренадлежат родительскому окну.
Но сперва надо решить, что вы отдаете клиенту - все накопившиеся сообщения для него, либо сообщения за период, а может лучше возвращать ему только последнее новое сообщение?
Синхронизация. Вы уверены, что во время ответа сервера на обновление, передача формы не прервет его, или наоборот?
По большому счету, все можно сделать на AJAX, не заморачиваясь с фреймами, и если это для вас вызывает трудности, воспользоваться jQuery, там все просто для понимания, тогда:
1. Есть постоянный ajax-запрос к серверу на получение новых сообщений. Каждое, полученное сервером, новое сообщение устанавливает метку времени, которая определяет, что сообщения равные и меньше ее по времени уже отданы клиенту и отдавать нечего. То есть клиенту будет отдаваться только новые сообщения.
2. Отправляете форум также ajax-запросом.
3. Можно пренебречь синхроницазией, полагаясь на то, что форма клиентом отправляется намного реже, чем постоянный опрос сервера. Но, если произойдет обрыв соединения, то гарантировано, что это сообщение клиент уже не увидит, так как в нашем случае оно будет уже помечено сервером как отданное, а значит старое.
4. Лучше синхронизируем запрос на обновление с отправкой формы. Будем использовать флаг. В начале работы он сброшен, и первым (по времени) начнет работу ajax-запрос на обновление, он проверяет сброшен или установлен флаг, и если сброшен, то устанавливает его, и делает запрос к серверу. Если в это время будет произведена отправка формы, то она должна проверить, установлен или сброшен флаг, если установлен, то ждем когда он будет сброшен.
При удачном приеме нового сообщения, методом jQuery создаем DIV, в который помещаем ответ, и добавляем его последним в основной DIV, который и является окном сообщений, с прокруткой, и сбрасываем флаг. Если нет новых сообщений, просто сбрасываем флаг.
Форма получила сброшенный флаг, устанавливает его (запрещая на время отправки формы запросы на обновление) и производит отправку.
Если прием прошел удачно, возвращаем время записи ответа в базу, которое помещаем вместе сохранненным временно ответом на клиенте в основной DIV, так же с помощью метода jQuery. То есть сам ответ отправляемый формой не обязательно возвращать, чтобы поместить его в окно сообщений. Его можно держать в переменной. Возврат, либо его игнорирование необходимо только при ошибках ввода.
В общем после все работ над ошибками, или при все ОК-ситуациях, после окончания передачи сообщения на сервер, форма сбрасывает флаг, разрешая обновление.
5. Процесс работы над ошибками в форме может занять время, и за это время сервер может накопить более одного нового сообощения, поэтому сообщения лучше передавать в JSON-формате. В простейшем случае это массив, но лучше возвращать массив объектов, каждый из которых будет содержать время, имя и собственно сообщение. То есть, на сервере это многомерный массив, а клиент получит его в виде объекта (после eval).
Обходим в цикле этот массив, помещая объекты его в HTML-элементы, и добавляем последними к окну сообщений.
Вот я бы так делал, если бы делал. Про работу IFRAME как ajax контейнера можете почитать тут. jQuery найдете в сети (если на нем делать), описание API jQuery в прикреплении. А это функция, которая будет преобразовывать данные на входе в JSON формат:
<?
function toJSON($var) {
switch (gettype($var)) {
case 'boolean': return $var ? 'true' : 'false';
case 'integer':
case 'double': return $var;
case 'resource':
case 'string': return '"'. str_replace(array("\r", "\n", "<", ">", "&"),
array('\r', '\n', '\x3c', '\x3e', '\x26'),
addslashes($var)) .'"';
case 'array':
if (empty ($var) || array_keys($var) === range(0, sizeof($var) - 1)) {
$output = array();
foreach ($var as $v) {
$output[] = toJSON($v);
}
return '['. implode(',',$output).']';
}
case 'object':
$output = array();
foreach ($var as $k => $v) {
$output[] = toJSON(strval($k)) .': '. toJSON($v);
}
return '{'.implode(',',$output).' }';
default: return 'null';
}
}
header('Content-Type: text/javascript; charset=/*здесь указать кодировку*/');
echo toJSON($var);
?>
|
| |