如何使用带有复选框的AJAX来创建&破坏?

时间:2015-04-13 19:52:23

标签: jquery ruby-on-rails ruby checkbox erb

我在想,当用户选中一个复选框时,页面会自动触发AJAX调用并更新Level模型(调用create或destroy操作)。用户无需手动提交表单。

class Level < ActiveRecord::Base
  belongs_to :habit
end

关键是,如果用户错过了一天做好习惯,他们应该检查错过的盒子。对于他们错过的每一天,他们必须弥补它,然后才能在积极的习惯形成过程中进入下一个阶段。

class Habit < ActiveRecord::Base
    belongs_to :user
    has_many :comments, as: :commentable
    has_many :levels
    serialize :committed, Array
    validates :date_started, presence: true
    before_save :current_level
    acts_as_taggable
    scope :private_submit, -> { where(private_submit: true) }
    scope :public_submit, -> { where(private_submit: false) }

    attr_accessor :missed_one, :missed_two, :missed_three

    def save_with_current_level
        self.levels.build
        self.levels.build
        self.levels.build
        self.levels.build
        self.levels.build
        self.save
    end

    def self.committed_for_today
    today_name = Date::DAYNAMES[Date.today.wday].downcase
    ids = all.select { |h| h.committed.include? today_name }.map(&:id)
    where(id: ids)
  end 

    def current_level
            return 0 unless date_started
            committed_wdays = committed.map { |day| Date::DAYNAMES.index(day.titleize) }
            n_days = ((date_started.to_date)..Date.today).count { |date| committed_wdays.include? date.wday }
            actual_days = n_days - self.missed_days

      case n_days     
          when 0..9
            1
          when 10..24
            2
          when 25..44
            3
          when 45..69
            4
          when 70..99
            5
          else
            "Mastery"
        end
    end
end

你可以在这里看到+1增量,以便错过一天。我们如何通过AJAX保存这个?

class DaysMissedController < ApplicationController
before_action :logged_in_user, only: [:create, :destroy]

def create
  level = Habit.find(params[:habit_id]).levels.find(params[:level_id])
  level.missed_days = level.missed_days + 1
  level.save
  head :ok # this returns an empty response with a 200 success status code
end

def destroy
  level = Habit.find(params[:habit_id]).levels.find(params[:level_id])
  level.missed_days = level.missed_days - 1
  level.save
  head :ok # this returns an empty response with a 200 success status code
end
end

配置文件

resources :habits do
  resources :comments
  resources :levels do
    # we'll use this route to increment and decrement the missed days
    resources :days_missed, only: [:create, :destroy]
  end
end

以下是来自 habit _form 的视觉效果:

enter image description here

习惯_形成

  <label> Missed: </label>
  <% @habit.levels.each_with_index do |level, index| %>
    <p>
      <label> Level <%= index + 1 %>: </label>
      <%= f.check_box :missed_one, checked: (level.missed_days > 0) %>
      <%= f.check_box :missed_two, checked: (level.missed_days > 1) %>
      <%= f.check_box :missed_three, checked: (level.missed_days > 2) %>
    </p>
  <% end %>

感谢您的专业知识!

1 个答案:

答案 0 :(得分:1)

不太难。在你的习惯形式:

<label id="<%= @habit.id %>" class="habit-id"> Missed: </label>
  <% @habit.levels.each_with_index do |level, index| %>
    <p>
      <label id="<%= level.id %>" class="level-id"> Level <%= index + 1 %>: </label>
      <%= check_box_tag nil, true, level.missed_days > 0, {class: "habit-check"} %>
      <%= check_box_tag nil, true, level.missed_days > 1, {class: "habit-check"} %>
      <%= check_box_tag nil, true, level.missed_days > 2, {class: "habit-check"} %>
    </p>
  <% end %>

javascript文件中:

$(document).ready(function()
{
  $(".habit-check").change(function()
  {
    habit = $(this).parent().siblings(".habit-id").first().attr("id");
    level = $(this).siblings(".level-id").first().attr("id");
    if($(this).is(":checked"))
    {
       $.ajax(
       {
         url: "/habits/" + habit + "/levels/" + level + "/days_missed",
         method: "POST"
       });
    }
    else
    {
       $.ajax(
       {
         url: "/habits/" + habit + "/levels/" + level + "/days_missed/1",
         method: "DELETE"
       });
    }
  });
});

您的destroy方法似乎不需要id,这就是为什么我传递1的原因;只是给它一个id