如何使选择器“:checked”也与“link_to”一起使用?

时间:2015-07-29 01:08:15

标签: javascript jquery ruby-on-rails ruby ajax

当用户点击此内容时,我们如何自动重新加载页面?

<%= link_to '<span class="glyphicon glyphicon-remove"></span>'.html_safe, habit_level_days_missed_index_path({ habit_id: habit, level_id: habit.current_habit_level.id }), remote: true, method: 'post', data: { confirm: 'You missed a committed day?' }, class: 'habit-check', id: 'remove_check' %>

habit-check触发了这个:

$(document).ready(function () {
  $(".habit-check").change(function () {
    var submitUrl = $(this).parents("p").data("submit-url");
    var deleteUrl = $(this).parents("p").data("delete-url");

    if ($(this).is(":checked")) { // We'd need to fix this line?
       $.ajax({ url: submitUrl, method: "POST" }).done(location.reload)
    } else {
       $.ajax({ url: deleteUrl, method: "DELETE" }).done(location.reload)
    }
  })
})

但是这被设计为在单击复选框时起作用。如果单击link_to按钮,我们如何才能使其工作?

我设想了类似if($(this).is(":checked && :clicked"))的内容,但我对javascript几乎没有理解,但我希望你能得到这个想法:]

更新

我尝试了此页https://api.jquery.com/category/selectors/中的所有选择器,但它们没有工作,所以我做错了或者解决方案不仅仅是修复一条线。

UPDATE AMIT

$(document).ready(function() {
  $('.remove-check').on('ajax:success', function() { location.reload() })
  $(".habit-check").change(function() {
    var submitUrl = $(this).parents("p").data("submit-url");
    var deleteUrl = $(this).parents("p").data("delete-url");

    if($(this).is(":checked"))
    {
       $.ajax(
       {
         url: submitUrl,
         method: "POST"
       })
       .done(function () {
         location.reload();
       });
    }
    else
    {
       $.ajax(
       {
         url: deleteUrl,
         method: "DELETE"
       })
       .done(function () {
         location.reload();
       });
    }
  });
})

1 个答案:

答案 0 :(得分:2)

似乎.habit-check不再是复选框,因此处理更改事件的旧代码无法正常工作。

所以我假设您希望使用复选框的链接而不是来完成此工作。 我还假设您正在使用Rails jquery-ujs(不显眼的javascript与jQuery),这是现在的默认设置。

当您在链接或表单上指定remote: true时,您不需要使用jQuery手动触发Ajax请求。 ujs框架为您做到了。因此,如果在data("submit-url")(这是您的情况)中正确定义了路径,则不需要像link_to那样在标记和javascript代码之间进行通信。这也是ujs框架的责任。

因此,当用户点击链接或提交具有remote: true的表单时,ujs框架将与服务器通信,您只需在javascript中处理此处定义的Ajax事件之一: https://github.com/rails/jquery-ujs/wiki/ajax

所以在你的情况下,这样做应该有效:

$(document).ready(function() {
  $('.habit-check').on('ajax:success', function() { location.reload() })
})

或者这个(如果你的.habit-check链接有可能由Javascript呈现,例如作为对Ajax调用的响应):

$(document).ready(function() {
  $('body').on('ajax:success', '.habit-check', function() { location.reload() })
})

注意:如果您想使用ajax:success事件,请确保您的控制器返回状态200.无论出于何种原因,如果控制器执行render text: 'hi',这将无法正常工作,因此呈现JSON回来或只是render nothing: true

更新 - 使用CHECKBOX

您似乎希望根据复选框状态调用不同的控制器操作。如果是这种情况,你可以像你一样在javascript中进行,或者按照我的建议在&#34;不同的控制器操作&#34;下面。如果您正好将复选框状态发送到一个控制器操作并让控制器处理&#34;如果选中,那么...&#34;,代码将更简单:

在再培训局:

<%= form_for @habit, remote: true, class: 'habit-form' do |f| %>
  <%= f.check_box :check, class: 'habit-check' %>
<% end %>

在Javascript中:

$('.habit-check').on('change', function() { $('.habit-form').submit() })
$('.habit-form').on('ajax:success', function() { location.reload() })

在控制器中:

def update
  habit = Habit.find(params[:id])
  if params[:habit][:check] == '1'
    # Do one thing
  else
    # Do another thing
  end
  render nothing: true
end

请注意,上面的代码做出以下假设:

  • 您有一个名为Habit的类,其中包含一个名为check的属性。如果您不希望将此复选框属性作为db列,只需在attr_accessor :check类定义中使用Habit添加它,以便f.check_box :check行生效。

  • ERB模板接收数据库中已存在的类@habit的{​​{1}}对象。换句话说,Habit会返回@habit.new_record?。这将使表单与控制器中的false操作进行通信。

不同的控制器操作

如果你想根据复选框状态调用不同的控制器操作,同时避免update调用(我个人认为更干净),你可以渲染两种不同的形式并让javascript选择提交哪一种

在再培训局:

$.ajax

在javascript中:

<%= form_for @habit, url: destroy_habit_path, method: :delete, remote: true, class: 'destroy-form redirect-after-success' %>
<%= form_for Habit.new, url: habits_path, method: :post remote: true, class: 'create-form redirect-after-success' %>

请注意,您还可以将$('.habit-check').on('change', function() { var isChecked = $(this).is(':checked'); var formClass = isChecked ? '.create-form' : '.destroy-form'; $(formClass).submit() }); $('.redirect-after-success').on('ajax:success', function() { location.reload() }); 课程添加到redirect-after-success链接,这样上面的javascript代码就会支持,而不会更改我们初次讨论中的链接。