Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > JavaScript: для новичков > Валидация с AJAX. Продлема с отправкой формы


Автор: KonstRuctor 25.6.2011, 00:46
Всем привет! Проверяю простенькую форму:
Код

<form method="post" name="myform">
<fieldset>

<label for="username">Имя</label>
<input type="text" name="username" id="username" size="50" maxlength="50" onblur="checkUser(this.value)" />
<div id="userdivMessage" class="hide"></div>

<label for="msg">Коммент</label>
<input type="text" name="msg" id="msg" size="50" maxlength="50" onblur="checkComment(this.value)" />
<div id="msgdivMessage" class="hide"></div>

<input type="submit" name="action" value="Отправить!" onclick="return validateAll(myform)" />
</fieldset>
</form>

По событию onblur() проверяю данные так:
Код

function checkUser(username)
{
    mydiv = document.getElementById("userdivMessage");
    mydiv.className = 'hide';
    var url = "/inc/ajax.php?username=" + username;
    createRequest();
    request.open("GET", url, true);
    request.onreadystatechange = makeUser;
    request.send(null);
}
function makeUser()
{
  if (request.readyState == 4) {
    if (request.status == 200) {
      var responseXml = request.responseXML;
      var xmlDoc = responseXml.documentElement;
      var action = xmlDoc.getElementsByTagName("action")[0].firstChild.data;
      if ( action == "1" )
      {
            errorMessage = xmlDoc.getElementsByTagName("answer")[0].firstChild.data;
            mydiv = document.getElementById("userdivMessage");
            mydiv.className = 'errdiv';
            mydiv.innerHTML = '<strong>' + errorMessage + '</strong>';
      }
    } else {
      alert("Не удалось получить данные от сервера:\n" + request.statusText);
    }
  }
}

У меня есть php-скрипт ajax.php, который выдает мне xml примерно такой:
Код

$response = '<?xml version="1.0" encoding="windows-1251" standalone="yes"?>'.
'<response>'.
  '<answer>'.
     'Ошибка: Логин должен быть не более 50 символов'.
  '</answer>'.
  '<action>'.
   '1'.
  '</action>'.
'</response>';

Все работает, ошибки показываются. Но я не понимаю, как мне запретить делать саму отправку форму, пока есть ошибки. Другими словами, ошибки-то я на экран показал, но юзер запросто может нажать кнопку и отправить форму с ошибками. Разумеется, я ее проверю еще раз на сервере, это сделает php. Однако хочется сделать юзабильно.
У меня есть функция onclick="return validateAll(myform)", которая прицеплена к кнопке. Получается, что придется этой функции еще раз проверять все поля?
Как сделать правильно? Спасибо

Автор: Shogun 25.6.2011, 00:52
Хммм...

return false в функции если ошибка.

А также советую:
1. POST вместо GET
2. jQuery, Prototype ... вместо простого Javascript
3. JSON вместо XML

не пожалеете имхо...

Автор: KonstRuctor 25.6.2011, 12:36
Я, признаться, ничего не понял.
Если ошибка -- return false это мне понятно, причем кристально понятно.
Я не понимаю, как это реализовать в моем конкретном примере.

По мере заполнения формы у юзера выскакивают предупреждения, что он что-то делает не так.
POST, GET, XML, JSON -- в данном случае это не так важно. 
Предупреждения у меня работают. 
НО мне не понятно как запретить отсылать форму на сервер.
Я имею в виду конкретно -- как в смысле примера кода, а не в смысле "если false, то не отправляй". 

Автор: нуп 25.6.2011, 14:50
Как то так
Код

function validateAll(form) {
   
   if(!form.user_name.value || !form.user_password.value) // тут ваши проверки
        return false;
   return true;
}

onclick="return validateAll(myform)"

Так должно работать

Автор: KonstRuctor 26.6.2011, 23:35
Спасибо, друзья. Все выходные работал.
Shogun натолкнул меня на интересные мысли. Сделал так:
1) В php-скрипте принимаю данные, если у юзера отключен javascript. Здесь все понятно.
2) В html-форме все проверки убрал вообще, назвал ее так:
Код

<form id="ajax-contact-form" method="post" action="#comments">

3) В страницу подключил вот эти скрипты:
Код

<script type="text/javascript" src="/js/jquery-1.2.6.min.js"></script> 
<script type="text/javascript" src="/js/valid.js"></script>

4) Написал скрипт valid.js:
Код

$(document).ready(function(){
$("#ajax-contact-form").submit(function(){
var str = $(this).serialize();
$.ajax({
type: "POST",
url: "ajax.php",
data: str,
contentType: 'application/x-www-form-urlencoded;charset=windows-1251',
success: function(msg){
$("#note").ajaxComplete(function(event, request, settings){
if(msg == 'OK') { window.location='/thankyou.php?e=guestartsigner&referer=' + location.href; }
else if(msg == 'indexOK') { window.location='/index.php'; }
else { result = msg; }
$(this).html(result);
});
}
});
return false;
});
});

5) Самое сложное было сделать скрипт ajax.php. Он большой, в нем у меня проверяются капча, юзернэйм, заполнение скрытого с помощью css поля email (роботы ведь его обязательно заполнят, и сработает "indexOK" smile и так далее и так далее.
Поэтому приведу тут только маленький его фрагмент, для ясности изложения мысли:
Код

header('Content-type: text/html; charset=windows-1251'); // эта строка не помогает, ее можно удалить
$post = (!empty($_POST)) ? true : false;
if( $post )
{
$error = '';
$username    = iconv('UTF-8', 'CP1251', $username);
if( !$username || strlen($username) < 3 )
    {
        $error .= "<li>Укажите Ваше имя.</li>\n";
    }
....................................
....................................
if(!$error) echo 'OK';
else echo '<div class="err"><p>ОШИБКА!</p><ul>'.$error.'</ul></div>';
}

6) Основная идея = если нет ошибок, в скрипт valid.js приходит строка 'OK' и юзера перенаправляют в скрипт thankyou.php, где ему говорят "спасибо, друге" и оттуда уже на ту же страницу с формой. Это важно, чтобы сбросить параметры капчи, сессию и так далее.

Внимание!
 несмотря на прямое указание везде где только можно "windows-1251" в базу записываются закарюки вместо букв. Только прямое указание $username = iconv('UTF-8', 'CP1251', $username); решает проблему.

Вроде бы все работает. Хорошо понимаю, что Америки я не открыл и велосипеда не изобрел, вернее попытался smile
Однако парился все выходные и решил поделиться своим решением.
Если есть мысли по поводу моего алгоритма, буду искренне рад обсудить. 
Спасибо!!!

Автор: fish9370 18.7.2011, 13:02
Цитата(KonstRuctor @  26.6.2011,  23:35 Найти цитируемый пост)
Если есть мысли по поводу моего алгоритма, буду искренне рад обсудить


да в целом все стандартно, ничего нового.. у меня только притензии к оформлению кода.. 
и в PHP тебя не учили отделять код от HTML?

Автор: KonstRuctor 18.7.2011, 13:06
При чем тут отделение php кода от HTML?
Я задавал вопрос по сути алгоритма и надеялся услышать конструктивный комментарий.
Например, используй такой подход или попробуй делать так-то и так-то.

Свой рабочий код я не показывал и, в принципе, в его рефакторинге не нуждаюсь.

Автор: нуп 18.7.2011, 14:48
Цитата(fish9370 @  18.7.2011,  13:02 Найти цитируемый пост)
да в целом все стандартно, ничего нового.. у меня только притензии к оформлению кода.. 
и в PHP тебя не учили отделять код от HTML?

А в чем ужас такого подхода, и какая ему замена? Шаблоны?

Автор: fish9370 19.7.2011, 00:04
Цитата(нуп @  18.7.2011,  14:48 Найти цитируемый пост)
А в чем ужас такого подхода, и какая ему замена? Шаблоны?


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

выход - конечно шаблоны.. и лично я сторонник не нативных шаблонов.. 

Автор: нуп 19.7.2011, 00:59
Покажите пример как вы бы написали вывод html кода.

Автор: fish9370 19.7.2011, 09:33
пожалуйста:
Код

        /* ajax.php */

        $_tpl_dir = 'tpl/ajax/';

        $tpl = new Template;
        $tpl->set_filenames(array(
                'info' => $_root_dir . $_tpl_dir . 'info.tpl',
        ));

        $tpl->assign_vars(array(
                'IMG' => $_img_dir,
                'JS' => $_js_dir
        ));

        switch($_page) {
                case "info":
                        $tpl->assign_vars(array(
                            'AID' => $aid,
                            'CALLERID' => "",
                            'ACCOUNT_STATUS' => "Вкл"));

                        echo $tpl->getparsed('info');
                        break;
        }


Код

<!-- info.tpl -->
<table>
        <tr>
                <td colspan=2 class="decore_1" align="center"> Учетная запись {AID}
        <tr>
                <td class="decore_2" align="right">Статус: &nbsp;
                <td><input type="text" value="{ACCOUNT_STATUS}" readonly class="inpt200">
        <tr>
                <td class="decore_2" align="right">АОН: &nbsp;
                <td><input type="text" value="{CALLERID}" readonly class="inpt200">
        <tr>
                <td class="decore_2" align="right">Многоканальность: &nbsp;
                <td><input type="text" value="" readonly class="inpt200">
        <tr>
                <td class="decore_2" align="right">Переадресация: &nbsp;
                <td><input type="text" value="" readonly class="inpt200">
        <tr>
                <td class="decore_2" align="right">Факс на почту: &nbsp;
                <td><input type="text" value="" readonly class="inpt200">
        <tr>
                <td class="decore_2" align="right">Запись разговоров: &nbsp;
                <td><input type="text" value="" readonly class="inpt200">
</table>


вот что-то типа того.. как видете, шаблон можно спокойно отдать дизайнеру (верстальщику), на любой стадии проекта.. если нужно переделать дизайн, нужно только переделать шаблон.. код остается..

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

Автор: fish9370 19.7.2011, 09:57
и что касается, первоначальной темы, быть может есть смысл, передавать данные в виде JSON.. 
и лично я бы отказался от механизма form вообще, передавал бы данные аджаксом - но на этом я не настаиваю (хотя считаю так удобнее)

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)