11

I'm trying to figure out how I can turn this:

$('#username').blur(function(){
    $.post('register/isUsernameAvailable', 
           {"username":$('#username').val()}, 
           function(data){
               if(data.username == "found"){
                   alert('username already in use');
               }
           }, 'json');
});

into something close to this:

rules: {
        username: {
            minlength: 6,
            maxlength: 12,
            remote: {
                url: 'register/isUsernameAvailable',
                type: 'post',
                data: {
                    'username': $('#username').val()
                } 

            }
        }

However I'm having a hard time finishing it off. What I want is instead of the alert to have it display the error message but I can set the message inside the actual jquery validation messages.

http://docs.jquery.com/Plugins/Validation/Methods/remote#options

UPDATE:

For some reason its not doing it as a POST its doing it as a GET request and not sure why. Here's the updated code:

rules: {
        username: {
            minlength: 6,
            maxlength: 12,
            remote: {
                url: 'register/isUsernameAvailable',
                dataType: 'post',
                data: {
                    'username': $('#username').val()
                },
                success: function(data) {
                    if (data.username == 'found')
                    {
                        message: {
                            username: 'The username is already in use!'
                        }
                    }
                }

            }
        },

UPDATE 2:

Now I'm getting somewhere I'm back to getting the POST request. I'm getting two more problems. One of which is the fact that for another POST request to be done the user has to refresh the form. And the last problem is that if the returned username is found it DOES NOT show the error message.

rules: {
        username: {
            minlength: 6,
            maxlength: 12,
            remote: {
                type: 'post',
                url: 'register/isUsernameAvailable',
                data: {
                    'username': $('#username').val()
                },
                dataType: 'json',
                success: function(data) {
                    if (data.username == 'found')
                    {
                        message: {
                            username: 'The username is already in use!'
                        }
                    }
                }

            }
        },

UPDATE:

public function isUsernameAvailable()
{
    if ($this->usersmodel->isUsernameAvailable($this->input->post('username')))
    {
        return false;
    }
    else
    {
        return true;
    }        
}

UPDATE 4:

Controller:

public function isUsernameAvailable()
{
    if ($this->usersmodel->isUsernameAvailable($this->input->post('username')))
    {
        return false;
    }
    else
    {
        return true;
    }        
}

public function isEmailAvailable()
{
    if ($this->usersmodel->isEmailAvailable($this->input->post('emailAddress')))
    {
        return false;
    }
    else
    {
        return true;
    }        
}

MODEL:

/**
 * Check if username available for registering
 *
 * @param   string
 * @return  bool
 */
function isUsernameAvailable($username)
{
    $this->db->select('username');
    $this->db->where('LOWER(username)=', strtolower($username));
    $query = $this->db->get($this->usersTable);
    if ($query->num_rows() == 0)
    {
        return true;
    }
    else
    {
        return false;
    }
}

/**
 * Check if email available for registering
 *
 * @param   string
 * @return  bool
 */
function isEmailAvailable($email)
{
    $this->db->select('email');
    $this->db->where('LOWER(email)=', strtolower($email));
    $query = $this->db->get($this->usersTable);
    if($query->num_rows() == 0)
    {
        return true;
    }
    else
    {
        return false;
    }
}
6
  • I included a link to the remote function. Commented Jun 5, 2012 at 18:53
  • Are you able to change the server-side code? Commented Jun 5, 2012 at 20:14
  • why would I need to. I'm working with js side. Commented Jun 5, 2012 at 20:27
  • Here's the way the remote rule works (by default). If the result returned by the server is true (boolean), then validation for the rule succeeds. If a string result is returned, that is used as the error message. Commented Jun 5, 2012 at 20:46
  • So what do you think I should do? Commented Jun 5, 2012 at 20:48

9 Answers 9

26

The easiest way to accomplish this is to simply return true, an error message as a string, or false from your server-side resource. According to the jQuery validate documentation for remote:

The response is evaluated as JSON and must be true for valid elements, and can be any false, undefined or null for invalid elements, using the default message; or a string, eg. "That name is already taken, try peter123 instead" to display as the error message.

This means if you can change your server-side code to return true in the event of successful validation or an error message ("username already in use") in the event of unsuccessful validation, you could just write the following remote rule:

remote: {
    type: 'post',
    url: 'register/isUsernameAvailable',
    data: {
        'username': function () { return $('#username').val(); }
    },
    dataType: 'json'
}

You could also simply return true or false from your server-side resource and define the error message on the client. In that case you would have the above rule and then a property in the messages object:

messages: {
    username: {
        remote: "username already in use"
    }
}
Sign up to request clarification or add additional context in comments.

12 Comments

I have both of those parts just like you do however check out my server side code above for some reason it doesn't display the message it shows the css of the error but doesn't echo out the error.
What happens when you return a string in the false case? Does it display then?
it posts the message that is in the js and NOT the text string that i put in the false case
on second thought i guess i just had uploaded the wrong file earlier because with the false true returned it is kind of working now
Note that 'username': $('#username').val() needs to be wrapped in a function i.e. 'username': function() { return $('#username').val() }. Otherwise it'll keep validating the first thing you supplied to the input.
|
11

I know it's too late, but this could help other people.

The remote method is meant to recieve a Json string, so your server side should be returning something like this to the method...

echo(json_encode(true)); // if there's nothing matching
echo(json_encode(false));

This is an example of the JS code that I wrote while trying to validate user's nickname.

$(document).ready(function(){
            $('#form').validate({
            rules: {
                user_nickname: {
                    remote: {
                        url: "available.php",
                        type: "post",
                        data: {
                          user_nickname: function() {
                            return $( "#user_nickname" ).val();
                          }
                        }
                      }               
                }
            },
            messages:{
                user_nickname: {
                    remote: "Username already taken"
                }
            }
        });});

Hope it helps someone, it helped me.

1 Comment

I was going around in circles trying to get something like this working and can confirm that this seems to be the cleanest and most accurate way to do it. Now to stop it from firing on every keyup...
9

I realize this is old but I had a hard time getting this working as well and wanted to share what worked for me.

Client-Side form validation code:

$('#frmAddNew').validate({
onkeyup: false,
rules: {
    ADID: {
        required: true,
        alphanumeric: true,
        maxlength: 10,
        remote: {
            url: "ADIDValidation.cshtml",
            type: "post",
            dataType: "json",
            dataFilter: function (data) {
                if (data) {
                    var json = $.parseJSON(data);
                    if (json[0]) {
                        return JSON.stringify(json[0].valid) /* will be "true" or whatever the error message is */
                    }
                }
            },
            complete: function (data) {
               /* Additional code to run if the element passes validation */
                if (data) {
                    var json = $.parseJSON(data.responseText);
                    if (json[0]) {
                        if (json[0].valid === "true") {
                            $('#FirstName').val(json[0].FirstName);
                            $('#LastName').val(json[0].LastName);
                        }
                    }
                }
            }
        }
    }
},
messages: {
    ADID: {
        required: "Please Enter an ADID of the Employee",
        alphanumeric: "The ADID Can Only Contain Letters and Numbers",
        maxlength: "ADID For User's Current Permissions Must Be 10 Characters or Less"
    }
},
submitHandler: function (form) {
    form.submit();
},
errorContainer: $('section.errorCon'),
errorLabelContainer: $('ol', 'section.errorCon'),
wrapper: 'li',
showErrors: function (errors) {
    var error = this.numberOfInvalids();
    var message = error == 1
        ? 'You missed 1 field:'
        : 'You missed ' + error + ' fields:';
    $('section.errorCon h3').html(message);
    this.defaultShowErrors();
}
});

Server-Side code for ADIDValidation.cshtml (I'm using Razor webpages):

@{

Layout = null;

if(IsPost)
{
    var db = Database.Open("<enter connection name>");
    var sql = "<enter sql or stored procedure>";
    var strADID = Request["ADID"];

    var result = db.Query(sql, strADID);
    IEnumerable<dynamic> response;

    if(result.Any()) 
    {
        @* "true" indicates the element passes validation. Additional data can be passed to a callback function *@
        response = result.Select(x => new
        {
            valid = "true",
            FirstName = x.FirstName,
            LastName = x.LastName
        });
    }

    else
    {
        @* The element did not pass validation, the message below will be used as the error message *@
        response = new[] {
            new {valid = "The Employee's ADID '" + strADID.ToString() + "' Is Not Valid. Please Correct and Resubmit"}
        };
    }

    Json.Write(response, Response.Output);
}
}

Comments

1

I think I am too late to reply. but our code is very easy for all

Validation Code

rules: {
            session: {
               required: true,
                remote: {
                    url: "<?php echo base_url('setting/session_setting/checkSession'); ?>",
                    type: "post",
                    data: {
                      session: function() {
                        return $( "#sessionInput" ).val();
                      }
                    }
                  }
            },
        },

Controller Code

public function checkSession()
    {
        $response = array();
        $session = $this->input->post('session');

        $check = $this->dm->checkData('session','session',array('session'=>$session));

        if($check)
        {
            echo(json_encode("Session Already Exist")); 
        }
        else
        {
            echo(json_encode(true)); 
        }
    }

Model Code

public function checkData($data,$tablename,$where)
    {
        $query = $this->db->select($data)
                 ->from($tablename)
                 ->where($where)
                 ->get();
        if($query->num_rows() > 0)
        {
            return true;
        }
        else
        {
            return false;
        }
    }

1 Comment

Perfect solution.
1
Jquery Code: 
 rules: {
        email: {
                required: true,
                maxlength: 50,
                email: true,
                 remote: {
        url: "<?php echo base_url('user/email_check') ?>",
        type: "post",
        data: {
          email: function() {
            return $( "#email" ).val();
          }
        }
      }
            },     
    },
     messages: {
      email: {
          required: "E-mailadres",
          email: "Please enter valid email",
          maxlength: "The email name should less than or equal to 50 characters",
          remote: jQuery.validator.format("{0} is already taken.")
        },
    },

PHP Code:
  if($results->num_rows == 0)
    {
        echo "true";  //good to register
    }
    else
    {
        echo "false"; //already registered
    }

1 Comment

From Review: Hi, please don't answer just with source code. Try to provide a nice description about how your solution works. See: How do I write a good answer?. Thanks
1

It looks like nobody else is using the data attribute data-rule-remote, so here's how I finally got it working.

<input data-rule-remote="https://myendpoint.api">

Returning true worked fine for me. Returning false would provide the default message. This allowed for a custom message as a data attribute with data-msg-remote like this.

<input data-rule-remote="https://myendpoint.api" data-msg-remote="Please name a mammal.">

But that wasn't dynamic. I wanted to generate the message from the server response.

My endpoint response was simply a string returning like this.

Animal not recognized. Did you mean <strong>duck-billed platypus</strong>?

Which was very close, but wasn't a JSON valid string. It needed to be wrapped in quotes to be valid.

"Animal not recognized. Did you mean <strong>duck-billed platypus</strong>?"

Comments

0

I needed to do remote validation in a rails project recently and struggled to send the correct response from server side if the input is invalid. At the end, the solution was quite simple.

If the server side check returns true, you can send true or "true", else you can return any string like "The email already exists" or "Email does not have valid MX records". This string will be displayed as the validation message on the form. The only catch is that the message string returned from server side should be valid JSON and should be in this format - ["The email already exists"].

Some explanation on how I debugged and found the solution: Please see below the remote method in jquery.validate.js. I had added log statements and an error function to the ajax call to debug. When I returned a normal string from server side, a jQuery.parseJson error was thrown.

// http://jqueryvalidation.org/remote-method/

remote: function( value, element, param ) {
    if ( this.optional( element ) ) {
        return "dependency-mismatch";
    }

    var previous = this.previousValue( element ),
        validator, data;

    if (!this.settings.messages[ element.name ] ) {
        this.settings.messages[ element.name ] = {};
    }
    previous.originalMessage = this.settings.messages[ element.name ].remote;
    this.settings.messages[ element.name ].remote = previous.message;

    param = typeof param === "string" && { url: param } || param;

    if ( previous.old === value ) {
        return previous.valid;
    }

    previous.old = value;
    validator = this;
    this.startRequest( element );
    data = {};
    data[ element.name ] = value;

    $.ajax( $.extend( true, {
        url: param,
        mode: "abort",
        port: "validate" + element.name,
        dataType: "json",
        data: data,
        context: validator.currentForm,
        success: function( response ) {
            console.log("response is "+response);
            var valid = response === true || response === "true",
                errors, message, submitted;
            console.log("valid is "+valid);
            validator.settings.messages[ element.name ].remote = previous.originalMessage;
            if ( valid ) {
                submitted = validator.formSubmitted;
                validator.prepareElement( element );
                validator.formSubmitted = submitted;
                validator.successList.push( element );
                delete validator.invalid[ element.name ];
                validator.showErrors();
            } else {
                errors = {};
                message = response || validator.defaultMessage( element, "remote" );
                console.log("else message is "+message);
                errors[ element.name ] = previous.message = $.isFunction( message ) ? message( value ) : message;
                validator.invalid[ element.name ] = true;
                console.log("else errors[ element.name ] "+errors[ element.name ]);
                validator.showErrors( errors );
            }
            previous.valid = valid;
            validator.stopRequest( element, valid );
        },
        error: function (xhr, ajaxOptions, thrownError) {
            console.log(xhr.status);
            console.log(thrownError);
        }
    }, param ) );
    return "pending";
}

3 Comments

I think is is trying to be an answer, but please clarify your wording, because as it stands it reads like a question instead - the answer is buried in your stream of consciousness.
The accepted answer just does not answer what the server side should returns and there is a comment there as well which says that it does not answer the question. I'm not sure why that was accepted in the first place.
@DileepCK The reason you have these comments is because your question came up in the Low Quality Review queue - the first comment on your post is an auto-generated one because the reviewer thought you were asking another question, not even making an attempt to answer. There are lots of people that erroneously post things like "I have this problem too, did anyone solve it yet?" in the answer box. Your answer looks like this at first blush because it starts with "I needed to ...", which is why I suggested rewording it.
0
rules: {
        username: {
            minlength: 6,
            maxlength: 12,
            remote: 'register/isUsernameAvailable',
         }
        }

You need to pass username

Comments

-2

Well I dunno bout your plugin concept specifically but I gather you want it to check to see with that plugin if the username is greater than 6 or less than 12. Which from your core example with jQuery without the plugin it would be as simple as adding one little if-else to the concept.

$('#username').blur(function(){
    if($('#username').val().length < 6 || $('#username').val().length > 12)
    {
        alert('Username must be between 6 and 12 characters');
    }
    else
    {
       $.post('register/isUsernameAvailable', 
              {"username":$('#username').val()}, 
              function(data){
                  if(data.username == "found"){
                      alert('username already in use');
                  }
              }, 'json');
    }
});

1 Comment

This answer is not related to the plugin

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.