简体   繁体   中英

Check username availability

I have a form to user login:

<%= form_tag(@action, :method => "post", :name => 'signup' ,:onSubmit => 'return validate();') do %>    
  <%= label_tag(:user, "Username:") %>
  <%= text_field_tag(:user) %>

I want to check if there is the username in the database immediately after:user-field lost focus. I can override this event on the form with javascript, but I can not send Ruby-AJAX request from javascipt code.

Is there any way to check username without adding additional controls (buttons, links) on the form?

You can use some JavaScript (this one written with jQuery) for AJAX cheking:

$(function() {
    $('[data-validate]').blur(function() {
        $this = $(this);
        $.get($this.data('validate'), {
            user: $this.val()
        }).success(function() {
            $this.removeClass('field_with_errors');
        }).error(function() {
            $this.addClass('field_with_errors');
        });
    });
});

This JavaScript will look for any fields with attribute data-validate . Then it assings onBlur event handler (focus lost in JavaScript world). On blur handler will send AJAX request to the URL specified in data-validate attribute and pass parameter user with input value.

Next modify your view to add attribute data-validate with validation URL:

<%= text_field_tag(:user, :'data-validate' => '/users/checkname') %>

Next add route:

resources :users do
  collection do
    get 'checkname'
  end
end

And last step create your validation:

class UsersController < ApplicationController
  def checkname
    if User.where('user = ?', params[:user]).count == 0
      render :nothing => true, :status => 200
    else
      render :nothing => true, :status => 409
    end
    return
  end

  #... other controller stuff
end

I answered this in another post.

It is a friendly way for validating forms if you do not want to write it all from scratch using an existing jquery plugin. Check it out and if you like it let me know!

Check username availability using jquery and Ajax in rails

For what reason can you not send an ajax request from javascript code?

The best way would be to send a GET ajax request when the focus is lost. The get request could then return true or false and your javascript could then reflect this on the page.

The solution that @Viacheslav has, works fine and my answer is a combination of his and my own changes (especially JS) part.

We will be using Ajax in order to achieve this.

Lets first create our function in the controller

def checkname
  if !User.find_by_display_name(params[:dn])
    render json: {status: 200}
  else
    render json: {status: 409}
  end
  return
end

and then adding our routes in routes.rb

resources :yourcontroller do
  collection do
    get 'checkname'
  end
end

Now lets gets our hand on the view. Below you'll see the input:

.field
  = f.text_field :display_name, onblur: "checkDisplayName.validate(this.value)"
  %p.error-name.disp-none username exists

And now by help of JS we get the magic rolling. Blow JS has few functions. validate does the actually validation. getStatus is our Ajax call to get the status and we use showError & disableSubmitButton to our form a bit more production ready to show errors and disabling the submit button.

var checkDisplayName = {
  validate: function(dn){
    checkDisplayName.getStatus(dn).then(function(result) {
      if (!!result){
        if (result.status != 200){
          checkDisplayName.disableSubmitButton(true);
          checkDisplayName.showError();
        } else{
          checkDisplayName.disableSubmitButton(false);
        }
      }
    });
    return false;
  },
  getStatus: async (dn) => {
    const data = await fetch("/pages/checkname?dn=" + dn)
      .then(response => response.json())
      .then(json => {
        return json;
      })
      .catch(e => {
          return false
      });
    
    return data;
  },
  showError: function() {
    let errEl = document.getElementsByClassName('error-name')[0];
    if (!!errEl) {
      errEl.classList.remove("disp-none");
      window.setTimeout(function() { errEl.classList.add("disp-none"); },3500);
    }
  },
  disableSubmitButton: function(status){
    let button = document.querySelector('[type="submit"]');
    button.disabled = status;
  }
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM