检查3个旧复选框后如何调用3个新复选框?

时间:2015-05-07 19:04:58

标签: ruby ajax checkbox

enter image description here

然后,如果检查了这些新框,则会显示该级别的另外3个复选框。

enter image description here

习惯/ _form.html.erb

<label id="<%= @habit.id %>" class="habit-id"> Missed: </label>
<% @habit.levels.each_with_index do |level, index| %>
  <% if @habit.current_level >= (index + 1) %>
    <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 %>
<% end %>

habit.js

$(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"
       });
    }
  });
});

habit.rb

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_strike
      levels[current_level - 1] # remember arrays indexes start at 0
    end

    def current_level
            return 0 unless date_started
          def committed_wdays
            committed.map do |day|    
              Date::DAYNAMES.index(day.titleize)
            end
          end

          def n_days
            ((date_started.to_date)..Date.today).count do |date| 
              committed_wdays.include? date.wday
            end - self.missed_days - self.days_lost
          end     

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

days_missed_controller

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

  def create
    habit = Habit.find(params[:habit_id])
    habit.missed_days = habit.missed_days + 1
    habit.save!
    level = habit.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
    if missed_days == 3
      missed_days = 0
      days_lost += pending_days
      pending_days += 1
      pending_days = 0
    end
  end

  def destroy
    habit = Habit.find(params[:habit_id])
    habit.missed_days = habit.missed_days - 1
    habit.save
    level = habit.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

如果您需要进一步的说明,代码或图片,请不要犹豫,您也可以在此处自行决定我的附加代码:https://gist.github.com/RallyWithGalli/c66dee6dfb9ab5d338c2

谢谢!

1 个答案:

答案 0 :(得分:1)

change事件的处理程序附加到每个复选框,该复选框计算具有type="checkbox"属性:not(:checked)的输入元素的数量。如果没有未选中的框,请添加三个框并将相同的单击事件处理程序附加到每个新框。每次填充所有方框时,都会添加三个新方框。

这是脚本的相关逻辑部分

if(!element.querySelectorAll('input[type="checkbox"]:not(:checked)').length) {
  /* add three checkboxes */
}

如果没有类型复选框的输入字段没有选中状态,则length属性将不确定并解析为false。如果输入字段与先前声明的标准匹配,则length属性将为1或更高的数字值,并将解析为true。

示例

var boxWrap = document.querySelector('.boxes');

var handleChange = function() {
  if (!boxWrap.querySelectorAll('input[type="checkbox"]:not(:checked)').length) {
    addBoxes(3);
  }
};

var addBoxes = function(n) {
  for (i = 0; i < n; i++) {
    var box = document.createElement('input');
    box.type = 'checkbox';
    box.addEventListener('change', handleChange, false);
    boxWrap.appendChild(box);
  }
};

boxes = boxWrap.querySelectorAll('input[type="checkbox"]');
for (var i = 0; i < boxes.length; i++) {
  boxes[i].addEventListener('change', handleChange, false);
}
<div class="boxes">
  <input type="checkbox">
  <input type="checkbox">
  <input type="checkbox">
</div>

修改

我在原始剧本中改变了一些内容

  1. 改进格式

  2. 更改了找到level-id和habit-id的方式,以降低复杂性。

  3. 我已将on change函数移动到命名处理函数中,以便可以将其应用于新复选框。

  4. 在onchange事件捕获中添加了上述逻辑。

  5. 我已经包含了如何添加新复选框的基本示例,您需要更改html并添加逻辑以确定属性应该是什么。

  6. $(document).ready(function() {
      var handleChange = function() {
        habit = $(this).parent().prev().attr("id");
        level = $('label', $(this).parent()).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"
          });
        }
        if (!$('input[type="checkbox"]:not(:checked)', $(this).parent()).length) {
          /* this is just an example, you will have to ammend this */
          $(this).parent().append($('<input type="checkbox" class="habit-check">'));
          $(this).parent().append($('<input type="checkbox" class="habit-check">'));
          $(this).parent().append($('<input type="checkbox" class="habit-check">'));
          $(".habit-check").on('change',handleChange);
        }
      }
      $(".habit-check").on('change',handleChange);
    });