Rails 4 将登录设计为弹出窗口

2024-02-10

您好,我正在使用设备对用户进行身份验证

我已经按照各种教程在弹出窗口中登录,但我没有成功,任何人都可以详细告诉我如何做到这一点。我已经尝试了各种教程,但没有任何效果,每件事都再次重定向到登录页面。

我是 Rails 的新手请帮忙。

我无法在同一页面上登录

这是我的 new.html.erb

<%= form_for(:user,  :html => {:id => 'login_form'}, :url => user_session_path, :remote => :true, :format => :json) do |f| %>

  <%= f.email_field :email, :autofocus => true, :placeholder => "email", :id => 'login_email' %>
  <%= f.password_field :password, :placeholder => "password", :id => 'login_password' %>

  <% if devise_mapping.rememberable? -%>
    <div><%= f.check_box :remember_me %> <%= f.label :remember_me %></div>
  <% end -%>

  <div><%= image_submit_tag('modals/account/login_submit.png') %></div>
<% end %>

这是我的标题页

 <% if user_signed_in? %>
  <p>Welcome <%= current_user.email %></p>
   <%= link_to "Sign out", destroy_user_session_path, :method => :delete %>
<% else %>
  <p>You are not signed in.</p>
  <%= link_to "Sign in", new_user_session_path, :remote => :true %>

<% end %>

首先,你想要一个弹出窗口或弹出窗口 http://www.quora.com/User-Interface-Design/Whats-the-difference-between-a-modal-a-popover-and-a-popup?

弹出窗口是新的 Windows,让人想起 90 年代的广告,而弹出窗口(有时称为模态窗口)是 UI 中的集成元素,基本上只是深色背景上的一个 div

所有 Web 2.0 网站都使用弹出窗口来增强可用性,而弹出窗口会降低体验:)


约夏克布丁

我们已经实现了您寻求的功能。

要使这项工作成功,您必须做好几件事 - 我将在这里为您详细介绍:


Routes

#config/routes.rb
devise_for :users, :path => '', :controllers => {:sessions => 'sessions', :registrations => 'registrations'}, :path_names => { :sign_in => 'login', :password => 'forgot', :confirmation => 'confirm', :unlock => 'unblock', :registration => 'register', :sign_up => 'new', :sign_out => 'logout'}

第一步是对您的路线进行排序

虽然设计有良好的路由文档 https://github.com/plataformatec/devise/wiki,您需要自定义您的路线以包括自定义session / registration控制器,以及您想要的任何自定义路径

路线最重要的部分是(您需要自定义控制器!):

:controllers => {:sessions => 'sessions', :registrations => 'registrations'}

控制器

接下来,您需要将 ajax 响应功能添加到您的sessions and registrations控制器。尽管 Devise 在每次安装时都会添加这些控制器,但它们仍然是隐藏的,如果您想添加功能,则必须扩展它们

这是我们的会话和注册控制器(很多代码可以删除,但它现在对我们有用):

Session

#app/controllers/sessions_controller.rb
class SessionsController < DeviseController
  prepend_before_filter :require_no_authentication, :only => [ :new, :create ]
  prepend_before_filter :allow_params_authentication!, :only => :create
  prepend_before_filter { request.env["devise.skip_timeout"] = true }
  
  prepend_view_path 'app/views/devise'
  
  # GET /resource/sign_in
  def new
    self.resource = resource_class.new(sign_in_params)
    clean_up_passwords(resource)
    respond_with(resource, serialize_options(resource))
  end

  # POST /resource/sign_in
  def create
    self.resource = warden.authenticate!(auth_options)
    set_flash_message(:notice, :signed_in) if is_navigational_format?
    sign_in(resource_name, resource)
    
    respond_to do |format|
        format.json { render :json => {}, :status => :ok }
        format.html { respond_with resource, :location => after_sign_in_path_for(resource) } 
    end
  end

  # DELETE /resource/sign_out
  def destroy
    redirect_path = after_sign_out_path_for(resource_name)
    signed_out = (Devise.sign_out_all_scopes ? sign_out : sign_out(resource_name))
    set_flash_message :notice, :signed_out if signed_out && is_navigational_format?

    # We actually need to hardcode this as Rails default responder doesn't
    # support returning empty response on GET request
    respond_to do |format|
      format.all { head :no_content }
      format.any(*navigational_formats) { redirect_to redirect_path }
    end
  end
  

  protected

  def sign_in_params
    devise_parameter_sanitizer.sanitize(:sign_in)
  end

  def serialize_options(resource)
    methods = resource_class.authentication_keys.dup
    methods = methods.keys if methods.is_a?(Hash)
    methods << :password if resource.respond_to?(:password)
    { :methods => methods, :only => [:password] }
  end

  def auth_options
    { :scope => resource_name, :recall => "#{controller_path}#new" }
  end
end

登记

#app/controllers/registrations_controller.rb
class RegistrationsController < DeviseController
  prepend_before_filter :require_no_authentication, :only => [ :new, :create, :cancel ]
  prepend_before_filter :authenticate_scope!, :only => [:edit, :update, :destroy]
  
  before_filter :configure_permitted_parameters
  
  prepend_view_path 'app/views/devise'

  # GET /resource/sign_up
  def new
    build_resource({})
    respond_with self.resource
  end

  # POST /resource
  def create
    build_resource(sign_up_params)

    if resource.save
      if resource.active_for_authentication?
        set_flash_message :notice, :signed_up if is_navigational_format?
        sign_up(resource_name, resource)
        respond_with resource, :location => after_sign_up_path_for(resource)
      else
        set_flash_message :notice, :"signed_up_but_#{resource.inactive_message}" if is_navigational_format?
        expire_session_data_after_sign_in!
        respond_with resource, :location => after_inactive_sign_up_path_for(resource)
      end
    else
      clean_up_passwords resource
      
      respond_to do |format|
        format.json { render :json => resource.errors, :status => :unprocessable_entity }
        format.html { respond_with resource }
      end
    end
  end

  # GET /resource/edit
  def edit
    render :edit
  end

  # PUT /resource
  # We need to use a copy of the resource because we don't want to change
  # the current user in place.
  def update
    self.resource = resource_class.to_adapter.get!(send(:"current_#{resource_name}").to_key)
    prev_unconfirmed_email = resource.unconfirmed_email if resource.respond_to?(:unconfirmed_email)

    if update_resource(resource, account_update_params)
      if is_navigational_format?
        flash_key = update_needs_confirmation?(resource, prev_unconfirmed_email) ?
          :update_needs_confirmation : :updated
        set_flash_message :notice, flash_key
      end
      sign_in resource_name, resource, :bypass => true
      respond_with resource, :location => after_update_path_for(resource)
    else
      clean_up_passwords resource
      respond_with resource
    end
  end

  # DELETE /resource
  def destroy
    resource.destroy
    Devise.sign_out_all_scopes ? sign_out : sign_out(resource_name)
    set_flash_message :notice, :destroyed if is_navigational_format?
    respond_with_navigational(resource){ redirect_to after_sign_out_path_for(resource_name) }
  end

  # GET /resource/cancel
  # Forces the session data which is usually expired after sign
  # in to be expired now. This is useful if the user wants to
  # cancel oauth signing in/up in the middle of the process,
  # removing all OAuth session data.
  def cancel
    expire_session_data_after_sign_in!
    redirect_to new_registration_path(resource_name)
  end

  protected
  
  # Custom Fields
  def configure_permitted_parameters
    devise_parameter_sanitizer.for(:sign_up) do |u|
      u.permit(:first_name, :last_name,
        :email, :password, :password_confirmation)
    end
  end

  def update_needs_confirmation?(resource, previous)
    resource.respond_to?(:pending_reconfirmation?) &&
      resource.pending_reconfirmation? &&
      previous != resource.unconfirmed_email
  end

  # By default we want to require a password checks on update.
  # You can overwrite this method in your own RegistrationsController.
  def update_resource(resource, params)
    resource.update_with_password(params)
  end

  # Build a devise resource passing in the session. Useful to move
  # temporary session data to the newly created user.
  def build_resource(hash=nil)
    self.resource = resource_class.new_with_session(hash || {}, session)
  end

  # Signs in a user on sign up. You can overwrite this method in your own
  # RegistrationsController.
  def sign_up(resource_name, resource)
    sign_in(resource_name, resource)
  end

  # The path used after sign up. You need to overwrite this method
  # in your own RegistrationsController.
  def after_sign_up_path_for(resource)
    after_sign_in_path_for(resource)
  end

  # The path used after sign up for inactive accounts. You need to overwrite
  # this method in your own RegistrationsController.
  def after_inactive_sign_up_path_for(resource)
    respond_to?(:root_path) ? root_path : "/"
  end

  # The default url to be used after updating a resource. You need to overwrite
  # this method in your own RegistrationsController.
  def after_update_path_for(resource)
    signed_in_root_path(resource)
  end

  # Authenticates the current scope and gets the current resource from the session.
  def authenticate_scope!
    send(:"authenticate_#{resource_name}!", :force => true)
    self.resource = send(:"current_#{resource_name}")
  end

  def sign_up_params
    devise_parameter_sanitizer.sanitize(:sign_up)
  end

  def account_update_params
    devise_parameter_sanitizer.sanitize(:account_update)
  end
end

Forms

添加后端功能后,您必须使表单支持 ajax。这很简单:

Login

#app/views/devise/sessions/new.html.erb
<%= form_for(devise_resource, :as => devise_resource_name, :html => {:id => 'login_form'}, :url => user_session_path, :remote => :true, :format => :json) do |f| %>

  <%= f.email_field :email, :autofocus => true, :placeholder => "email", :id => 'login_email' %>
  <%= f.password_field :password, :placeholder => "password", :id => 'login_password' %>

  <% if devise_mapping.rememberable? -%>
    <div><%= f.check_box :remember_me %> <%= f.label :remember_me %></div>
  <% end -%>

  <div><%= image_submit_tag('modals/account/login_submit.png') %></div>
<% end %>

Register

#app/views/devise/registrations/new.html.erb
<%= form_for(devise_resource, :as => devise_resource_name, :html => {:id => 'register_form'}, :url => user_registration_path, :remote => :true, :format => :json) do |f| %>
    
    <div class="name_input_container">
        <div class="name_input_cell">
            <%= f.text_field :first_name, :autofocus => true, :class => 'first_name', :placeholder => 'first name' %>
            <div class="error"><%= devise_resource.errors[:first_name].first if devise_resource.errors[:first_name].present? %></div>
        </div>
        
        <div class="name_input_cell_right">
            <%= f.text_field :last_name, :class => 'last_name', :placeholder => 'last name' %>
            <div class="error"><%= devise_resource.errors[:last_name].first if devise_resource.errors[:last_name].present? %></div>
        </div>
    </div>
    
    <%= f.email_field :email, :placeholder => "email" %>
    <div class="error"><%= devise_resource.errors[:email].first if devise_resource.errors[:email].present? %></div>
    
    <%= f.password_field :password, :placeholder => "password", :title => "8+ characters" %>
    <div class="error"><%= devise_resource.errors[:password].first if devise_resource.errors[:password].present? %></div>
    
    <%= f.password_field :password_confirmation, :placeholder => "confirm password" %>
    <div class="error"><%= devise_resource.errors[:password_confirmation].first if devise_resource.errors[:password_confirmation].present? %></div>

    <div class="option_buttons">
        <div class="already_registered">
            <%= link_to 'already registered?', '#', :class => 'already_registered', :id => 'already_registered', :view => 'login' %>
        </div>
        <%= image_submit_tag('modals/account/register_submit.png', :class => 'go') %>
        <div class="clear"></div>
    </div>
<% end %>

JavaScript

最后,您只需要能够处理来自 Ajax 的响应:

Login

//app/assets/javscripts/application.js
$(document).on('submit', '#login_form', function(e) {
            //do stuff here
}).on('ajax:success', '#login_form', function(e, data, status, xhr) {
        //do stuff here 
}).on('ajax:error', '#login_form', function(e, data, status, xhr) {
        //do stuff here
});

Register

//app/assets/javascripts/application.js
$(document).on('submit', '#register_form', function(e){
    //do stuff here
}).on('ajax:success', '#register_form', function(e, data, status, xhr) {
    //do stuff here
}).on('ajax:error', '#register_form', function(e, data, status, xhr) {
       //do stuff here  
});
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Rails 4 将登录设计为弹出窗口 的相关文章

随机推荐

  • 在android中使用串口RS-232?

    我想在 Android 设备上使用 JavaComm API 类通过串行端口发送信号 我的想象如下 1 Android 设备为 Archos 3 2 具有 android 2 2 和 USB 主机模式 2 在我的 Android 应用程序中
  • 如何以编程方式启动本地 DynamoDB?

    我能够启动一个local通过以下命令从 bash 启动 DynamoDB 服务器 java Djava library path DynamoDBLocal lib jar DynamoDBLocal jar sharedDb 是否没有一种
  • JavaScript 操作后获取 HTML 源代码

    怎么才能满啊 网页的 HTML 源代码 在运行一些对 HTML 源代码进行操作的 JavaScript 代码之后 我正在使用 VB Net 的 WebbrowserControl 我想为我的自定义 webbrowsercontrol 创建一
  • 将参数传递给使用 chrome.tabs.executeScript() 注入的内容脚本

    如何将参数传递给使用以下方式注入的内容脚本文件中的 JavaScript chrome tabs executeScript tab id file content js 不存在 将参数传递给文件 这样的事情 你什么can要做的就是插入内容
  • 从视图检索数据,我应该使用模型绑定器吗?

    我在这里有点迷失 因为我没有真正看过模型活页夹 所以如果可能的话 如果我真的正确地考虑了我的问题 可以告诉我 如果我的代码是这样的 请建议 1 我有一个 DTO 类 其中包含 自定义字段 每个字段都有名称和其他属性 即 Public Cla
  • 如何从字节数组构造颜色?

    我正在努力完成非常简单的任务 嗯 我认为是这样 我有byte 4 表示颜色值的数组 例如byte 0 alpha byte 1 red等等 如何将此字节数组转换为实际的颜色对象 感谢您的答复 Java 中的字节是有符号的 因此正数部分只能保
  • PyCharm 中的“继承全局站点包”是什么意思?

    当创建一个新的Python项目时 为什么我要选择这个选项 如果我不选择它 我会错过什么功能 我是否无法导入某些 Python 模块 其他答案都不太准确 继承全局站点包 不会 预安装 或 添加包 到您的虚拟环境中 设置为您提供虚拟环境访问权限
  • 如何本地化关键 UIApplicationShortcutItemTitle

    我应该如何本地化密钥UIApplicationShortcutItemTitle 我知道本地化对于像这样的键是如何工作的NSLocationUsageDescription and NSLocationAlwaysUsageDescript
  • 如何在 activeadmin 下拉菜单中的 # 上显示模型标题?

    我创建了一个关联 其中项目有很多任务并且任务属于项目 我已经在 admin tasks rb 中创建了表单 form do f f inputs Details do f input title f input project end f
  • 迭代器只能迭代一次吗? [复制]

    这个问题在这里已经有答案了 考虑以下示例 def foo iterator return sum iterator max iterator 重复使用同一个迭代器两次是否安全 不 这不安全 迭代器不是序列 这就是发生的事情foo 使用生成器
  • 如何在 Spring Security 中配置资源服务器以使用 JWT 令牌中的附加信息

    我有一个 oauth2 jwt 令牌服务器 配置为设置有关用户权限的附加信息 Configuration Component public class CustomTokenEnhancer extends JwtAccessTokenCo
  • aws lambda 调用未在 POST 上填充正文

    感谢 EVK 对我之前的问题的帮助 可以使用 API GET 但不能使用 API POST https stackoverflow com questions 49665248 can use api get but not api pos
  • 如何使用army bear common lisp 创建jar?

    我想知道是否可以使用army bear common lisp 创建一个jar 文件 如果可以的话该怎么做 换句话说 我有以下代码 格式为 Hello World 我可以在armed bear common lisp中运行它 我想知道如何创
  • 停止失控的 Lua 子进程

    我使用 LuaObjCBridge 将 Lua 嵌入到 Objective C 应用程序中 我需要知道如何停止 Lua 进程 如果它花费太多时间 无限循环 在单独的线程中运行它会有帮助吗 通常的方法是使用lua sethook http w
  • Ember.js 绑定模型存储在数组中

    当模型存储在数组中时 从一个模型绑定到另一个模型的 正确 方法是什么 通常我会想象这将是控制器的content数组 但为了保持示例简单 MyApp websites MyApp websites push Ember Object crea
  • 使用 R 中函数的额外参数进行归约[重复]

    这个问题在这里已经有答案了 我正在尝试使用ReduceR 中的函数使用merge跨多个数据帧的功能 问题是 我想将合并函数与参数一起使用all T 并且似乎没有地方可以在高阶中指定这一点Reduce功能 所以我想 a lt data fra
  • 如何在 setInterval ajax Web 服务调用中阻止 ASP.net 表单身份验证/会话更新?

    我编写了一个控件 其中包含一个 javascript 组件和一个 Web 服务组件 我遇到的问题是 javascript 设置为 setInterval this checkAlertsHandler this messageCheckIn
  • 条码字体与条码打印机字体有什么区别

    有人知道条形码字体 在报告中用作字体 和直接从条形码打印机打印的字体之间的区别吗 为什么条码字体前后要加星号 据我了解 当我们使用条形码打印机时 我们不需要它 为什么不呢 星号字符是规范的一部分Code 39 http en wikiped
  • Nokogiri、open-uri 和 Unicode 字符

    我正在使用 Nokogiri 和 open uri 来获取网页上标题标签的内容 但在处理重音字符时遇到问题 处理这些问题的最佳方法是什么 这就是我正在做的 require open uri require nokogiri doc Noko
  • Rails 4 将登录设计为弹出窗口

    您好 我正在使用设备对用户进行身份验证 我已经按照各种教程在弹出窗口中登录 但我没有成功 任何人都可以详细告诉我如何做到这一点 我已经尝试了各种教程 但没有任何效果 每件事都再次重定向到登录页面 我是 Rails 的新手请帮忙 我无法在同一