如何更新按钮点击后呈现的部分?

时间:2013-07-01 07:05:14

标签: ruby-on-rails ruby-on-rails-3

我有一个事件搜索结果页面,用户可以点击“添加到收藏夹”按钮。

单击该按钮会执行POST以将事件添加到用户的收藏夹中。如果他们再次搜索,他们现在会看到“从收藏夹中删除”按钮,而不是该事件的“添加到收藏夹”按钮。

目前在收藏夹控制器创建操作中我使用了respond_to,因此format.js允许用户留在搜索结果页面上。

但是,如何渲染“从收藏夹中删除”按钮的部分,而不是“添加到收藏夹”按钮的部分。

这样他们可以点击“从收藏夹中删除”,以获取他们最喜欢的项目。

下面的屏幕截图和代码。提前谢谢。

screenshot

--------------搜索结果项目渲染器---------------

<div id="add_remove_favorite" class="user_event_info_container">
  <% if (signed_in? && current_user && current_user.id != user_event.user_id) %>
    <%= render partial: "shared/add_remove_favorite", 
      locals: { user_event: user_event } %>
  <% end %>
</div>

------------- shared / _add_remove_favorite.html.erb ---------

<% if current_user.following?(user_event) %>
  <%= render partial: 'shared/remove_favorite', 
    locals: { user_event: user_event } %>
<% else %>
  <%= render partial: 'shared/add_favorite', 
    locals: { user_event: user_event } %>
<% end %>

-------------- shared / _add_favorite.html.erb ----------

<%= form_for(current_user.favorites.build(followed_event_id: user_event.id), remote: true) do |f| %>
  <div class="hidden"><%= f.hidden_field :followed_event_id %></div>
  <%= f.submit "Add to favorites", 
    class: "info_button_small user_event_summary_item" %>
<% end %>

-------------- shared / _remove_favorite.html.erb ------------

<%= form_for(current_user.favorites.find_by_followed_event_id(user_event),
  html: { method: :delete }, remote: true) do |f| %>
  <%= f.submit "Remove from favorites", class: "info_inline_control info_button_small user_event_summary_item" %>
<% end %>

-------------- views / create.js.erb ------------ 应该去哪里?我认为这是我执行魔术的地方。

-------------- views / destroy.js.erb ------------ 应该去哪里?我认为这是我执行魔术的地方。

2 个答案:

答案 0 :(得分:1)

你需要将uniq id分配给声明表单的add / remove部分。这可以使用event_id来完成(因为列出了事件,你将拥有uniq事件)。你可以通过表单将事件id作为隐藏字段发送,并在js.erb文件中使用它来查找部分并替换/修改它。

在js.erb中使用以下代码。语法是haml。

- if @event.favorite? #event is saved as favorite
  $('#event_number_#{event.id}').replaceWith("#{escape_javascript(render(partial: 'shared/remove_favorite', locals: {local_variable: some_variable}))}");
- unless @event.favorite? #event is not fav
  $('#event_number_#{event.id}').replaceWith("#{escape_javascript(render(partial: 'shared/add_favorite', locals: {local_variable: some_variable}))}");

在'form_for'的'html'选项中,你可以添加

html:{ id: "event_number_#{event.id}", class: 'some class'}

我更喜欢使用'link_to'和'remote'选项而不是'form',因为我只需要更改链接文本。链接url将是相同的,并且事件对象上只有2个动作'add'和'remove'。这个活动不能两次“加入”。你可以设置链接ID并在参数中传递事件id并在js.erb文件中找到id并更改链接文本而不是替换更好的部分。如果使用表单提交更多数据(我在提供的视图中看不到任何其他数据),则继续使用表单。

答案 1 :(得分:1)

我解决了这个问题,以下是我的工作解决方案,用于在单击按钮时切换按钮的部分内容。

我的场景是一个用户事件应用程序,用户可以在其中搜索符合日期,标题,场地等标准的事件。我有一个事件搜索结果页面,用户可以单击“添加到收藏夹”按钮。当他们这样做时,应该用“从收藏夹中移除”按钮替换该按钮,以防他们改变主意并且不想要那个喜欢的。

我的解决方案在控制器操作中使用带有format.js的respond_to,允许用户保留在搜索结果页面上,而不刷新页面。屏幕截图,下方只有 相关 代码。

希望这有助于其他人。谢谢大家的建议!

screenshot

----------搜索结果项目代码的一部分-----------

<div id="add_remove_favorite">
  <% if (signed_in? && current_user && current_user.id != user_event.user_id) %>
    <%= render partial: "shared/add_remove_favorite", 
      locals: { user_event: user_event } %>
  <% end %>
</div>

----部分决定是否应显示“添加到收藏夹”或“从收藏夹中删除”----

<% if current_user.following?(user_event) %>
  <%= render partial: 'shared/remove_favorite', 
    locals: { user_event: user_event } %>
<% else %>
  <%= render partial: 'shared/add_favorite', 
    locals: { user_event: user_event } %>
<% end %>

------------偏“添加到收藏夹”按钮----------------

<%= form_for(current_user.favorites.build(followed_event_id: user_event.id), 
  html: { id: "event_number_#{user_event.id}" }, remote: true) do |f| %>
  <div class="hidden"><%= f.hidden_field :followed_event_id %></div>
  <%= f.submit "Add to favorites %>
<% end %>

------------偏离“从收藏夹中删除”按钮------------

<%= form_for(current_user.favorites.find_by_followed_event_id(user_event),
  html: { id: "event_number_#{user_event.id}", method: :delete }, remote: true) do |f| %>
  <%= f.submit "Remove from favorites %>
<% end %>

--------具有创建和销毁操作的FavoritesController ---------

class FavoritesController < ApplicationController
  before_filter :signed_in_user

  def create
    @user_event = UserEvent.find(params[:favorite][:followed_event_id])
    current_user.follow!(@user_event)
    respond_to do |format|
      format.html { redirect_to user_path(current_user) }
      format.js
    end
  end

  def destroy
    @user_event = Favorite.find(params[:id]).followed_event
    current_user.unfollow!(@user_event)
    respond_to do |format|
      format.html { redirect_to user_path(current_user) }
      format.js
    end
  end
end

------------- create.js.erb -----------

<% if @current_user.following?(@user_event) %>
  $("#event_number_<%= @user_event.id %>").replaceWith('<%= escape_javascript(render(
    partial: 'shared/remove_favorite', locals: { user_event: @user_event })) %>');
<% end %>

------------- destroy.js.erb ----------

<% if !@current_user.following?(@user_event) %>
  $("#event_number_<%= @user_event.id %>").replaceWith('<%= escape_javascript(render(
    partial: 'shared/add_favorite', locals: { user_event: @user_event })) %>');
<% end %>
相关问题