然后,如果检查了这些新框,则会显示该级别的另外3个复选框。
习惯/ _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
谢谢!
答案 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>
修改强>
我在原始剧本中改变了一些内容
改进格式
更改了找到level-id和habit-id的方式,以降低复杂性。
我已将on change函数移动到命名处理函数中,以便可以将其应用于新复选框。
在onchange事件捕获中添加了上述逻辑。
我已经包含了如何添加新复选框的基本示例,您需要更改html并添加逻辑以确定属性应该是什么。
$(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);
});