2016-04-01 10 views
1

Ich habe eine Hand Roll-Registrierungsformular, wo ich die Ambethia Recaptcha gem verwenden. Alles funktioniert gut, wenn das Formular gültig ist. Wenn dies nicht der Fall ist, muss ReCaptcha zurückgesetzt werden. Hier ist die create-Methode:Zurücksetzen von Recaptcha in Rails Form

def create 
    @users = User.all 
    @user = User.create(user_params) 

    respond_to do |format| 
     if verify_recaptcha(model: @user, timeout: 300, message: "Problem with ReCAPTCHA, please try again.") && @user.save 
     session[:user_id] = @user.id 
     flash[:notice] = "Thank you for signing up!" 
     format.html 
     format.js {render js: "window.location = '#{root_path}';"} 
     format.json { render :show, status: :created, location: @user } 

     if Rails.env.production? 
      UserMailer.welcome_email(@user).deliver 
     end 
     else 
     flash[:alert] = "Sign Up Failed!" 
     format.html { redirect_back(fallback_location: root_path) } 
     format.js 
     format.json { render json: @user.errors, status: :unprocessable_entity } 
     end 
    end 
    end 

Sie sehen, wenn das Formular korrekt ist, die ReCaptcha funktioniert, aber wenn es einen Überprüfungsfehler ist, wie Passwörter nicht übereinstimmt, die Recaptcha zeigt sich bereits geprüft. Dann, wenn Sie die Validierungsfehler korrigieren, können Sie die ReCaptcha nicht wiederholen und Sie erhalten den Fehler "Problem mit ReCAPTCHA ...". Dies ist die Form, die enthält meine recaptcha_tags:

<div class="modal-dialog"> 
    <div class="spinner"> 
    <%= image_tag "loading.gif" %> 
    </div> 
    <div class="modal-content"> 
     <div id="registration-form"> 
     <h1>Sign Up</h1> 
     <%= form_for @user, remote: true, html: { style: "display:inline;" } do |f| %> 
     <div class="modal-body"> 
      <ul class="errors"></ul> 
      <div class="field"> 
      <%= f.label :email %><br> 
      <%= f.email_field :email, required: true, autofocus: true, placeholder: "Enter a valid email" %> 
      </div> 
      <div class="field"> 
      <%= f.label :username, 'Username' %><br> 
      <%= f.text_field :username, required: true, placeholder: "Pick a username" %> 
      </div> 
      <div class="field"> 
      <%= f.label :password %><br> 
      <%= f.password_field :password, required: true, placeholder: "Create a password" %> 
      <p id="form-tip">Passwords must be at least <strong>8 characters</strong> in length and contain at least <strong>one upper case letter</strong>, <strong>one lower case letter</strong>, and <strong>one number or special character</strong>.</p> 
      </div> 
      <div class="field"> 
      <%= f.label :password_confirmation %><br> 
      <%= f.password_field :password_confirmation, required: true, placeholder: "Password again" %> 
      </div> 

      <%= render 'recaptcha' %> 

      <div class="modal-footer actions"> 
      <%= f.submit "Sign Up", class: "btn btn-l btn-success"%> 
      <%= link_to "Cancel", "#", class: "btn btn-l btn-danger", data: {dismiss: "modal"} %> 
      </div> 
     <% end %> 
     </div> 
    </div> 
    </div> 
</div> 

Diese Form mit einer AJAX-Anforderung von einer navbar-Taste wiedergegeben wird. Formulareinreichung löst folgende _save.js.erb:

$("ul.errors").html("") 
<% if @user.errors.any? %> 
    <% @user.errors.full_messages.each do |message| %> 
     $("ul.errors").append($("<li />").html("<%= message.html_safe %>")) 
    <% end %> 
<% else %> 
    $("#new_user_modal").modal("hide") 
<% end %> 

Ich habe versucht, $(".g-recaptcha").grecaptcha.reset(); hinzufügen, um die recaptcha reload zu machen. Ich habe viele Dinge ausprobiert. Nichts scheint zu funktionieren. Wenn mein Formular mit den Überprüfungsfehlern erneut geladen wird, sollte eine neue ReCAPTCHA-Box angezeigt werden. Entweder das oder irgendwie erlauben Sie dem Benutzer, ihre Fehler zu beheben und fortzufahren, ohne das recaptcha erneut zu machen.

Dank

Antwort

1

So hat niemand geantwortet, aber ich habe einen Weg, um das Problem für jetzt gefunden. Ich kann das ReCaptcha immer noch nicht "zurücksetzen", aber durch das Entfernen der "optionalen" Parameter von der verify_recaptcha Methode im Controller erwartet es nicht länger, dass der Benutzer ein neues Recaptcha erneut einreicht. Hauptsächlich ist es die Aufhebung der Bindung von ReCaptcha an das Benutzermodell, die es ermöglicht, die Modellvalidierung zu umgehen. Ich aktualisiert, um diese Zeile in users_controller.rb:

... 
if verify_recaptcha(model: @user, timeout: 300, message: "Problem with ReCAPTCHA, please try again.") && @user.save 
     session[:user_id] = @user.id 
... 

dazu:

... 
if verify_recaptcha && @user.save 
     session[:user_id] = @user.id 
... 

immer noch daran interessiert zu wissen, wie gehen die ReCaptcha tatsächlich Zurücksetzen (vorzugsweise über das Juwel selbst oder ein jQuery-Aufruf). Ich habe alles darauf geworfen (das div clearing, Klassen, g-recaptcha.reset() Funktion, messing mit dem timeout Attribut, etc ...) und nichts hat funktioniert.

Vielen Dank an alle, die helfen können!

2

Versuchen Sie so etwas wie die folgenden Code, der (über jquery) an die Ajax binden: Fehler durch Ihre JSON zurückgeben geworfen/422.

$('#registration-form form').on("ajax:error", function(e, xhr, status, error) { 
    if (window.grecaptcha) grecaptcha.reset(); 
}) 

Der einfachste Weg, etwas mit wie jQuery zu binden würde zu Ihrem Formularelement und behandeln es bei Fehler. Wenn Ihr Remote-Aufruf zurückkehrt, können Sie das Formular einfach zurücksetzen, aber nur bei einem Fehler. Auf diese Weise können Sie sicherstellen, dass Ihre Benutzer immer ein neues ReCaptcha-Formular erhalten und erneut validieren. Dies scheint Teil des RAILS-Edelsteins zu sein, als ich heute Abend das gleiche Stück traf und es damit löste.