如何在检查3岁复选框调用3个新的复选框?复选框、如何在

2023-09-10 21:58:43 作者:东亚小醋王!

那么,如果这些新的复选框被选中另外3复选框会显示该水平。

习惯/ _form.html.erb

 <标签ID =<%= @ habit.id%>中类=习惯-ID>错过:其中; /标签>
<%@ habit.levels.each_with_index办|水平,指数| %>
  <%@如果habit.current_level> =(索引+ 1)%>
    &其中p为H.;
      <标签ID =<%= level.id%>中类=级ID>平<%=指数+ 1%计算值:< /标签>
      <%= check_box_tag为零,真正的,level.missed_days> 0,{类:习惯检查}%>
      <%= check_box_tag为零,真正的,level.missed_days> 1,{类:习惯检查}%>
      <%= check_box_tag为零,真正的,level.missed_days> 2,{类:习惯检查}%>
   &所述; / P>
  <%结束%GT;
<%结束%GT;
 

habit.js

  $(文件)。就绪(函数()
{
  $(习惯检查)。改变(函数()
  {
    习惯= $(本).parent()兄弟(习惯-ID。)(第)ATTR(ID)。;
    级= $(本).siblings(电平-ID)的第一()ATTR(ID)。;
    如果($(本)。是(:选中))
    {
       $阿贾克斯(
       {
         网址:/习惯/+习惯+/级别/+等级+/ days_missed
         方法:POST
       });
    }
    其他
    {
       $阿贾克斯(
       {
         网址:/习惯/+习惯+/级别/+等级+/ days_missed / 1,
         方法:DELETE
       });
    }
  });
});
 

habit.rb

 类习性<的ActiveRecord :: Base的
    belongs_to的:用户
    的has_many:意见为::commentable
    的has_many:水平
    连载:承诺,阵列
    验证:date_started,presence:真
    before_save:current_level
    acts_as_taggable
    适用范围:private_submit, - > {其中,(private_submit:真)}
    适用范围:public_submit, - > {其中,(private_submit:假)}

attr_accessor:missed_one,:missed_two,:missed_three

    高清save_with_current_level
        self.levels.build
        self.levels.build
        self.levels.build
        self.levels.build
        self.levels.build
        self.save
    结束

    高清self.committed_for_today
    today_name =日期:: DayNames中[Date.today.wday] .downcase
    IDS = all.select {| H | h.committed.include? today_name} .MAP(安培;:ID)
    其中,(ID:IDS)
  结束

    高清current_level_strike
      各级[current_level  -  1]#记得数组索引从0开始
    结束

    高清current_level
            返回0,除非date_started
          高清committed_wdays
            committed.map做|天|
              日期:: DAYNAMES.index(day.titleize)
            结束
          结束

          高清n_days
            ((date_started.to_date).. Date.today).Count之间做|日期|
              committed_wdays.include? date.wday
            结束 -  self.missed_days  -  self.days_lost
          结束

      案例n_days
          当0..9
            1
          当10..24
            2
          当25..44
            3
          当45..69
            4
          当70..99
            五
          其他
            6
        结束
    结束
  结束
 
C CheckBox复选框

days_missed_controller

 类DaysMissedController<的ApplicationController
  before_action:LOGGED_IN_USER,只有:[:创建:摧毁]

  DEF创建
    习惯= Habit.find(PARAMS [:habit_id])
    habit.missed_days = habit.missed_days + 1
    habit.save!
    水平= habit.levels.find(PARAMS [:level_id])
    level.missed_days = level.missed_days + 1
    level.save!
    头:OK#此方法返回一个200成功状态code空响应
    如果missed_days == 3
      missed_days = 0
      days_lost + = pending_days
      pending_days + = 1
      pending_days = 0
    结束
  结束

  DEF破坏
    习惯= Habit.find(PARAMS [:habit_id])
    habit.missed_days = habit.missed_days  -  1
    habit.save
    水平= habit.levels.find(PARAMS [:level_id])
    level.missed_days = level.missed_days  -  1
    level.save!
    头:OK#此方法返回一个200成功状态code空响应
  结束
结束
 

如果您需要进一步的解释,code或照片,请不要犹豫,问,你也可以在这里找到你的自由裁量权我额外的code:的 https://gist.github.com/RallyWithGalli/c66dee6dfb9ab5d338c2

谢谢!

解决方案

附加的处理程序变更事件,这与属性计算有多少投入要素的每个复选框类型=复选框这是:没有(:选中)有。如果没有选中框下添加三箱和相同的Click事件处理程序附加到每一个新的对话框。每次所有的箱子都装满它会增加三个新的。

这是脚本的相关逻辑部分

 如果(element.querySelectorAll(!'输入[类型=复选框]:没有(:选中)。)长){
  / *新增三个复选框* /
}
 

如果有型复选框不具有任何输入字段的状态检查,length属性将是未定义和解决为false。如果有输入字段相匹配的previously陈述的标准,length属性将是1或更高的数字值,将解析为真。

示例

VAR boxWrap = document.querySelector('盒子'); VAR handleChange =功能(){   如果(boxWrap.querySelectorAll('输入[类型=复选框]:没有(:选中)!。)长){     addBoxes(3);   } }; VAR addBoxes =功能(N){   对于(I = 0; I&n种;我++){     VAR箱= document.createElement方法(输入);     box.type =复选框;     box.addEventListener('变',handleChange,假);     boxWrap.appendChild(箱);   } }; 盒= boxWrap.querySelectorAll('输入[类型=复选框]'); 对于(VAR I = 0; I< boxes.length;我++){   盒[I] .addEventListener('改变',handleChange,假); }

< D​​IV CLASS =盒子>   <输入类型=复选框>   <输入类型=复选框>   <输入类型=复选框> < / DIV>

修改

我已经改变了一些东西,你的原剧本

改进格式

改,你觉得水平-id和习惯-id来降低复杂性的方式。

我搬到了上改变功能到一个名为处理函数,以便它可以被应用到新的复选框。

补充上述逻辑在onchange事件捕获。

我已经包括了如何添加新的复选框一个基本的例子,你将需要更改HTML并添加逻辑,以确定哪些属性应该是。

$(文件)。就绪(函数(){   VAR handleChange =功能(){     习惯= $(本).parent()preV()ATTR(ID)。;     水平= $('标签',$(本).parent())ATTR(ID)。     如果($(本)。是(:选中)){       $阿贾克斯({         网址:/习惯/+习惯+/级别/+等级+/ days_missed         方法:POST       });     } 其他 {       $阿贾克斯({         网址:/习惯/+习惯+/级别/+等级+/ days_missed / 1,         方法:DELETE       });     }     如果($('输入[类型=复选框]:没有(:选中)!,$(本).parent())长。){       / *这只是一个例子,你将不得不ammend这个* /       $(本).parent()追加($('<输入类型=复选框级=习惯检查>'));       $(本).parent()追加($('<输入类型=复选框级=习惯检查>'));       $(本).parent()追加($('<输入类型=复选框级=习惯检查>'));       $(习惯检查。)对('改变',handleChange)。     }   }   $(习惯检查。)对('改变',handleChange)。 });

Then if those new boxes are checked another 3 checkboxes would show for that level.

habits/_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

If you need further explanation, code, or pictures please don't hesitate to ask, you can also find at your discretion my additional code here: https://gist.github.com/RallyWithGalli/c66dee6dfb9ab5d338c2

Thank you!

解决方案

Attach a handler for the change event to each check box which counts how many input elements with the attribute type="checkbox" which are :not(:checked) there are. If there are no unchecked boxes, add three boxes and attach the same click event handler to each new box. Every time all of the boxes are filled it will add three new ones.

This is the relevant logic part of the script

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

If there are no input fields of type checkbox which do not have the status checked, the length property will be undefined and resolve to false. If there are input field which match the previously stated criteria, the length property will be a number value of 1 or higher and will resolve to true.

Example

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>

EDIT

I've changed a couple of things in your original script

Improved formatting

Changed the way that you find the level-id and habit-id to reduce complexity.

I've moved the on change function into a named handler function so that it can be applied to the new checkboxes.

Added the logic described above to your onchange event capture.

I've included a basic example of how to add the new checkboxes, you will need to change the html and add logic to determine what the attributes should be.

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