Как я могу заставить jQuery Validate проверять наличие дубликатов имени пользователя в базе данных?

#javascript #jquery #validation #jquery-validate

#javascript #jquery #проверка #jquery-validate

Вопрос:

Я вхожу в середину этого проекта, поэтому мне приходится немного переписывать из-за неаккуратного кода. Я использую jQuery 1.6.1 и проверяю 1.8.1.

Во-первых, вот PHP, который запускает серверную часть (dbquery.php ):

 include("../includes/dbconnection.php");
session_start();

$location='';
$action='';
if($_GET['action']=='')
    $action=$_POST['action'];
else
    $action=$_GET['action'];

if($action=='checkusername'){
    $error='';
    $username=$_GET['username'];
    // exclude denied account
    $checkuserquery=mysql_query("Select * from database_users as user LEFT OUTER JOIN  database_approval as approval on user.user_id=approval.approval_user_id  where (approval.approval_status IS NULL or approval.approval_status <> 4) and user_username='".$username."'");
    $checkuserresult=mysql_numrows($checkuserquery);
    if($checkuserresult>0) {
        $error = 'false';
    } else {
        $error = 'true';
    }
    echo $error;
} 
  

Я пытаюсь использовать скрипт jQuery Validate для быстрого запроса к базе данных существующих имен пользователей. Я либо получаю две крайности: это никогда не работает, либо всегда возвращает заданное имя пользователя как принятое.

Я полагаю, проблема в том, что я не могу получить входное значение переменной username. Когда я создаю alert (username) внутри function (output) , это ничего не возвращает. Я предполагаю, что .val() работает только при загрузке страницы, поэтому все, что я вводю на ввод, по какой-то причине не работает.

Вот jQuery, который я переписал и скопировал из онлайн-источников:

 $(document).ready(function(){

$.validator.addMethod("checkAvailability",function(value,element){
    var username = $("#username").val();
    $.ajax({
          url: "dbquery.php",
          type: "GET",
          async: false,
          data: "action=checkusernameamp;username=" username,
          success: function(output) {
                     return output;
         }
     });
},"Sorry, this user name is not available");

// jQuery Validation script
    $("#signup").validate( {
        rules: {
            username: {
                required: true,
                minlength: 5,
                checkAvailability: true // remote check for duplicate username
            },
        },
        messages: {
            username: {
                required: "Enter a username"
            }
        },
        submitHandler: function(form) {
            form.submit();
        }
    });

});
  

Я всего лишь новичок в jQuery, но изрядно пачкаю руки этим кодом. Я на правильном пути или мне следует использовать remote: под rules и username ? Мне сказали, что remote метод не будет работать из-за динамической природы входного значения, которое я пытаюсь проверить.

Другая серьезная проблема, с которой я столкнулся, заключается в том, что удаленное сообщение об ошибке отображается ТОЛЬКО тогда, когда имя пользователя уже существует в базе данных. К сожалению, это показывает, является ли dbquery.php возвращается как true или false . Если я пытаюсь использовать существующее имя пользователя, оно возвращает false , затем я переписываю новое имя пользователя, которое возвращает true , сообщение не уходит. Аналогично, когда я ввожу имя пользователя и оно возвращается true , я по-прежнему получаю сообщение об ошибке remote.

The original coder was referencing getXMLHTTP and using ActiveXObject . The method he programmed seemed a little outdated so I’m trying to make the code a little more contemporary and clean it up.

5/25 — Я редактирую это, чтобы включить СТАРЫЙ исходный код JavaScript, который работает, но использует устаревший метод, от которого я хотел бы отказаться (с тех пор я удалил следующий код и заменил на jQuery выше):

 function getXMLHTTP() { //function to return the xml http object
    var xmlhttp=false;    
    try{
        xmlhttp=new XMLHttpRequest();
    }
    catch(e)    {        
        try{            
            xmlhttp= new ActiveXObject("Microsoft.XMLHTTP");
        }
        catch(e){
            try{
            xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
            }
            catch(e1){
                xmlhttp=false;
            }
        }
    }

    return xmlhttp;
}
//validate username
function validateUsername(username){
    var strURL="dbquery.php?action=checkusernameamp;username=" username;
    var req = getXMLHTTP();        
    if (req) {            
        req.onreadystatechange = function() {
            if (req.readyState == 4) {
                // only if "OK"
                if (req.status == 200) {          
                    if(req.responseText=='notavailable'){
                        document.getElementById("errorusername").style.display="block";
                        document.getElementById("errorusername").innerHTML="<div id="errors"><strong>" username "</strong> is already taken by another user.</div>";
                        error = true;
                    }
                    else{
                        error = false;
                        document.getElementById("errorusername").style.display="none";   
                    }

                } else {
                    alert("There was a problem while using XMLHTTP:n"   req.statusText);
                }
            }                
        }            
        req.open("GET", strURL, true);
        req.send(null);
    }     
}
  

Ответ №1:

Проверьте, когда вызывается функция проверки, каково значение username и каково output значение true : это "true" или не это?

Я предполагаю, что последнее: строка, поэтому вы могли бы просто сделать:

 return output === "true" ? true : false; // I sincerely recommend using === here
  

Поскольку, если вы return "false"; будете оценивать true , потому что это непустая строка — ура динамическим языкам! :/

Пример с remote :

 $("#signup").validate( {
    rules: {
        username: {
            required: true,
            minlength: 5,
            remote: {
                url: "dbquery.php",
                type: "get",
                data: {
                    action: function () {
                        return "checkusername";
                    },
                    username: function() {
                        var username = $("#username").val();
                        return username;
                    }
                }
            }
        }
    },
    messages: {
        username: {
            required: "Enter a username"
        }
    },
    submitHandler: function(form) {
        form.submit();
    }
});
  

Чтобы задать пользовательское сообщение об ошибке, ваш PHP-файл должен возвращать сообщение вместо false, поэтому echo "Sorry, this user name is not available" в вашем PHP-файле.

Комментарии:

1. @frits-van-campen Firebug говорит, что это true без кавычек. Я выполнил alert (output) а также получаю true без кавычек. Однако значение имени пользователя — это именно то, что я ввожу во входные данные, поэтому проблем больше нет.

2. @frits-van-campen Я думаю, что моя главная цель — заставить сообщение об ошибке отображаться ТОЛЬКО при возврате значения username false . Кажется, я исправил свою первоначальную проблему, возвращаясь true и false при необходимости.

3. Итак, в чем ваша текущая проблема?

4. @frits-van-campen Приведенный выше код постоянно возвращает, Sorry, this user name is not available независимо от того, возвращает username true или false . Я хочу, чтобы оно отображалось только при его возврате false и исчезало при его возврате true .

5. Вы действительно действительно уверены, что это так, true а не "true" нет? Firebug обычно не добавляет кавычки при регистрации строки, и я точно знаю, что alert этого не делает. Попробуйте строку, которую я опубликовал: return output === "true" ? true : false;

Ответ №2:

При добавлении addMethod вы должны возвращать true или false со стороны сервера.

а также это значение должно быть возвращено из addMethod.

т.е. что-то вроде этого

 $.validator.addMethod("checkAvailability",function(value,element){
    var parameter="action=checkusernameamp;username=" username;
    $.ajax({
          url: "dbquery.php",
          type: "POST",
          async: false,
          data: parameter
          success:function(output)
                 {
                    return output
                 }
     });
},"Sorry, this user name is not available");
  

Комментарии:

1. @mahesh Следует ли использовать ваш success ответ буквально? Значение, function(output) это буквально то, что я должен использовать? Или, вы имеете в виду, что мне нужно использовать true или false ?

2. @Micah: это то, что я буквально написал. Вы должны вернуть значение true или false с сервера, а также должны вернуть его из addMethod

3. @mahesh хорошо, я вставил это в код, и это не меняет результат. Каждое имя пользователя, которое я пытаюсь использовать, недоступно.

4. можете ли вы просто предупредить вывод внутри функции success. Возвращает ли оно ожидаемое значение

5. @mahesh Я действительно ценю все, что вы сделали. Если ничего другого, я узнал несколько вещей. Если я найду способ проверить то, что вы говорите, я обязательно оставлю другой комментарий.

Ответ №3:

Я столкнулся с той же проблемой, но я нахожу самое простое решение, просто возвращающее true или false после кодирования в json через php.

 if ($users->username_exists())
{
    echo json_encode(FALSE);
}else{
    echo json_encode(TRUE);
}
  

Ответ №4:

В вашем серверном скрипте попробуйте вернуть true or false вместо available и notavailable , поскольку обе эти строки эквивалентны true .

Комментарии:

1. @minboost Да, я действительно пробовал это, но это не изменило результат. Спасибо за предложение.

2. Вы проверили, правильно ли возвращается ваша страница PHP? И вы уверены, что возвращаете СТРОКИ ‘true’ и ‘false’? Если вы попытаетесь повторить логические значения, оно вернет 1 или (пустое).

3. @minboost да, исходный JS-код работал правильно, но был запутанным. Итак, я уверен, что PHP-код функционирует должным образом, но что-то, вероятно, потребуется изменить для новой версии jQuery. Я просто пока не знаю, что это такое.

4. Я бы использовал remote: вместо создания нового метода. Вероятно, метод возвращает значение (NULL) до завершения ajax. Функции JS, использующие ajax, не ждут результата, прежде чем продолжить обработку.

5. Кроме того, ваш PHP-файл уязвим для внедрения SQL.

Ответ №5:

Мой код:

 $( "#myform" ).validate({
  rules: {
    EMAIL: {
      remote: {
        type: "post",  
        url: "checkMail.php",           
        data:{checkUsername:function(){return $("#EMAIL").val()}            
        }
      }
    }
  },messages:{EMAIL:{remote: "Already taken!"}}
});