Javascript-форум (https://javascript.ru/forum/)
-   Events/DOM/Window (https://javascript.ru/forum/events/)
-   -   Sumbit формы (https://javascript.ru/forum/events/43703-sumbit-formy.html)

Riddik 17.12.2013 05:32

Sumbit формы
 
Вопрос не совсем по JS, а, возможно, по PHP.

Когда юзер ввёл данные формы и нажал Sumbit, как при этом остаться на этой же странице?

Форма - это просто отправка мыла, на мыло отправляю в php скрипте.
Но при этом загружается и страница sendmail.php.

Как сделать так, чтобы просто показать окно с сообщением вместо перехода на новую страницу?

<form action="sendmail.php" method="post">
		<p><input type="text" size="40" placeholder="Ваше имя" name="user"></p>			
		<p><input type="text" size="40" placeholder="E-mail" name="email"></p>
		<p><input type="text" size="40" placeholder="Тема письма" name="subj"></p>
		<p>Текст обращения<Br>
		<textarea placeholder="Текст обращения" name="text" cols="40" rows="6"></textarea></p>
		<p><input type="submit" value="Отправить" name="submit_form1"></p>						
	</form>


<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
	</head> 
<body >
<h3>Заявка успешно отправлена!</h3>
<?php	

if(isset($_POST['submit_form1']))
{	
	$name = $_POST['user'];
	$mail = $_POST['email'];
	$subj = $_POST['subj'];
	$body = "Имя отправителя: ".$name."\nE-mail отправителя: ".$mail."\n\nТекст письма:\n\n".$_POST['text'];		
	mail("mymain@gmail.com", $subj, $body, "Content-Type: text/plain; charset=utf-8\n");
	header("Refresh: 4; url=".$_SERVER['HTTP_REFERER']);
}
?>

danik.js 17.12.2013 06:14

В нормальных браузерах можно так сделать:
<script>
function sendForm(form, success) {
    var request = new XMLHttpRequest();
    request.open(form.method, form.action);
    request.onreadystatechange = function() {
        if (request.readyState == request.DONE) {
            if (request.code == 200) {
                success(request.responseText);
            }
        }
    };
    request.send(new FormData(form));
}
</script>
<form onsubmit="return sendForm(this, alert), false" action....>

Riddik 17.12.2013 11:46

Цитата:

Сообщение от danik.js
В нормальных браузерах можно так сделать:

Т.е. в IE ниже 9ки работать не будет?

Спасибо!

danik.js 17.12.2013 12:33

Цитата:

Сообщение от Riddik
Т.е. в IE ниже 9ки работать не будет?

К сожалению в 9 работать тоже не будет. Только начиная с 10.
Если нужна кроссбраузерность, то у тебя два пути:
1) Подключить либу jQuery, там есть .serialize() и $.ajax()
2) Вместо FormData написать функцию сериализации в строку.
Функция выглядит примерно так:

function isSubmittable(control) {
    var element = control.nodeName.toLowerCase();
    if (['select', 'textarea', 'keygen'].indexOf(element) > -1)
        return true;
    if (element == 'input') {
        if (['submit', 'button', 'image', 'reset', 'file'].indexOf(control.type) > -1)
            return false;
        if (['checkbox', 'radio'].indexOf(control.type) > -1 && !control.checked)
            return false;
        return true;
    }
    return false;
}
    
function serialize(form) {
    var segments = [];
    for (var i = 0, control; control = form.elements[i]; i++) {
        if (!control.name || control.disabled || !isSubmittable(control))
            continue;
        segments.push(encodeURIComponent(control.name) + '=' + encodeURIComponent(control.value));
    }
    return segments.join('&');
}


Код особо не тестил.

К сожалению костыля для FormData найти не удалось..

Riddik 17.12.2013 12:54

Принцип понял - спасибо ещё раз!

danik.js 17.12.2013 14:56

Забыл проинициализировать i в коде, поправил.

moskitos80 17.12.2013 15:32

Riddik, то что тебе нужно - можно реализовать вообще без JS, если конечно doctype позволит: загрузка нескольких файлов на сервер

danik.js 17.12.2013 17:30

moskitos80, а причем тут загрузка файлов? И как аякс будет работать без JS по-твоему?
И кстати, разве doctype что-либо позволяет/запрещает?

Vlasenko Fedor 17.12.2013 18:04

есть варианты можно в фрейме отправлять
или JsonP использовать и даже img если не нужно ответ получать

Riddik 17.12.2013 18:09

danik.js,
Вместо request.send(new FormData(form));
Вставил request.send(serialize(form));
Ничего не происходит, php скрипт не вызывается. Неправильно запрос формирую?

moskitos80,
спасибо, попробую так.

moskitos80 17.12.2013 18:16

Цитата:

а причем тут загрузка файлов? И как аякс будет работать без JS по-твоему?
Вообще, конечно, загрузка файлов и аякс здесь не причем. Просто статья так называется. В ней есть ответ на заданный вопрос. Если указать в теге формы атрибут target, который будет ссылаться на iframe- то по событию отправки формы страница не будет перезагружена, а результат ответа сервера отобразится в указанном iframe.
Цитата:

И кстати, разве doctype что-либо позволяет/запрещает
На сколько я помню есть doctype которые запрещают использовать iframe/

danik.js 17.12.2013 18:47

Цитата:

Сообщение от moskitos80
На сколько я помню есть doctype которые запрещают использовать iframe/

Верно. Но это все пережитки прошлого. Да и браузеры забивают на все эти формальные запреты в угоду максимальной работоспособности.

Riddik 17.12.2013 19:12

Беда прямо какая-то с этим, вроде простая отправка на мыло...

Вариант с FormData работает только в Хроме - во всех остальных ничего не происходит, php-скрипт даже не выполняется.
Вариант с serialize вообще не работает нигде.

Вариант по ссылке moskitos80 вроде можно обойтись без js, но тогда, насколько я понял, достаточно просто добавить атрибут target в form и какой-то фрейм - в этом весь смысл статьи? Js всё равно придется делать, иначе как окошко, что сообщение отправлено или нет вывести?

Riddik 17.12.2013 19:15

С FormData даже в хроме то работает, то нет.
Выдаёт сообщение:

Warning: mail()[function.mail]: Could not execute mail delivery program '/usr/sbin/sendmail -t -i' in /home/uez-host/uez.ru/docs/sendmail.php on line 11

Это уже проблемы на стороне хостера? К ним стучать?

danik.js 17.12.2013 19:34

Цитата:

Сообщение от Riddik
Вариант с serialize вообще не работает нигде.

Покажи как ты пытаешься его использовать. Ты обновил код после моей правки var i = 0? Какие ошибки? F12 жал в браузере?
Цитата:

Сообщение от Riddik
Это уже проблемы на стороне хостера? К ним стучать?

Может ограничение на кол-во отправок в минуту?

Riddik 17.12.2013 19:51

Вариант с target везде сработал, спасибо!

Riddik 17.12.2013 19:52

Цитата:

Сообщение от danik.js
Покажи как ты пытаешься его использовать. Ты обновил код после моей правки var i = 0? Какие ошибки? F12 жал в браузере?

Да, жал - никаких ошибок нет.

Вот полный код:

<script>
function isSubmittable(control)
{
    var element = control.nodeName.toLowerCase();
    if(['textarea'].indexOf(element) > -1) return true;
    if(element == 'input')
	{
        if(['submit', 'button'].indexOf(control.type) > -1) return false;        
        return true;
    }
    return false;
}
    
function serialize(form)
{
    var segments = [];
    for(var i = 0, control; control = form.elements[i]; i++)
	{
        if (!control.name || control.disabled || !isSubmittable(control)) continue;
        segments.push(encodeURIComponent(control.name) + '=' + encodeURIComponent(control.value));
    }
    return segments.join('&');
}

function sendForm(form, success)
{
    var request = new XMLHttpRequest();
    request.open(form.method, form.action);
    request.onreadystatechange = function() {
        if (request.readyState == request.DONE) {
            if (request.status == 200) {
                success(request.responseText);
            }
        }
    };	
    request.send(serialize(form));
}
</script>
<h3>Форма отправки обращения</h3>
<form onsubmit="return sendForm(this, alert), false" action="../sendmail.php" method="post">
	<p><input type="text" size="40" placeholder="Ваше имя" name="user"></p>			
	<p><input type="text" size="40" placeholder="E-mail" name="email"></p>
	<p><input type="text" size="40" placeholder="Тема письма" name="subj"></p>
	<p>Текст обращения<Br>
	<textarea placeholder="Текст обращения" name="text" cols="40" rows="6"></textarea></p>
	<p><input type="submit" value="Отправить" name="submit_form1"></p>						
</form>

Riddik 17.12.2013 20:04

Цитата:

Сообщение от danik.js
Может ограничение на кол-во отправок в минуту?

Непохоже, пробовал несколько подряд отправлять - уходят. Затем через какое-то время не уходят.

Кстати, ответ сервера на срочку в php-скрипте:
header('Content-Type: text/html; charset=utf-8');

Warning: Cannot modify header information - headers already sent by (output started at /home/uez-host/uez.ru/docs/sendmail.php:1) in /home/uez-host/uez.ru/docs/sendmail.php on line 2

Что за ерунда? Как он может быть уже установлен?
Настройки сервера виноваты? Т.к. на другом хосте этот же код работает как часы.

moskitos80 17.12.2013 22:42

Цитата:

Сообщение от Riddik (Сообщение 287470)
Непохоже, пробовал несколько подряд отправлять - уходят. Затем через какое-то время не уходят.

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

Цитата:

Сообщение от Riddik (Сообщение 287470)
Кстати, ответ сервера на срочку в php-скрипте:
header('Content-Type: text/html; charset=utf-8');

Warning: Cannot modify header information - headers already sent by (output started at /home/uez-host/uez.ru/docs/sendmail.php:1) in /home/uez-host/uez.ru/docs/sendmail.php on line 2

Что за ерунда? Как он может быть уже установлен?
Настройки сервера виноваты? Т.к. на другом хосте этот же код работает как часы.

- Такое бывает, когда на серверной стороне в PHP - скрипте произведен любой вывод в буфер (читай - отправка клиенту) какой либо из функций печати или попался файл с кодировкой utf-8 с маркером порядка байтов. В любом случае перед каким либо выводом в буфер сервер отсылает http - заголовки, что бы потом послать буфер в теле запроса. Следовательно после вывода он заголовки уже отослать не может, о чем тебе и сообщается - эта проблема решается в коде переносом строки:
header('Content-Type: text/html; charset=utf-8');

до момента какого либо вывода либо с использованием механизма буферизации опять же можно у меня глянуть: PHP: Буферизация вывода

Riddik 18.12.2013 01:42

moskitos80,
так и есть, спасибо большое за помощь!

Riddik 18.12.2013 02:11

Несмотря на кодировку utf-8, в IE 11 все равно сообщения выводятся в тарабарщине (где используется кириллица)

Обращение не отправлено, попробуйте позже!

В других браузерах всё нормально. Можно ли как-нибудь это вылечить для IE 11?

danik.js 18.12.2013 05:05

Блин, перед request.send() добавь строчку:
request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');

danik.js 18.12.2013 05:08

Цитата:

Сообщение от Riddik
Обращение не отправлено, попробуйте позже!

Выглядит как utf-8 текст, интерпретированный как win-1251. То есть неправильно указан атрибут charset в заголовке Content-Type, отдаваемом сервером. Если сервак - Apache, фиксится установкой AddDefaultCharset utf8 в .htaccess

Riddik 18.12.2013 11:14

Благодарю!)


Часовой пояс GMT +3, время: 05:21.