如何为每个复选标记保存复选框并增加整数?

Posted

技术标签:

【中文标题】如何为每个复选标记保存复选框并增加整数?【英文标题】:How to SAVE checkbox & INCREASE integer for each checkmark? 【发布时间】:2015-02-25 17:42:31 【问题描述】:

如果用户勾选了一个框,我们如何保存它?

现在,如果发生这种情况,复选标记会在刷新时消失,并且在索引 <%= habit.missed %> 中它仍然显示 0 而不是 1(我不知道 true 或 false 布尔值是否适用于此)。

有 15 个复选框,对于用户选中的每个复选框,我们如何为 t.integer :missed 添加 +1?

换句话说,如果单击复选框,则表示 1,如果未单击,则表示 0。

布局外观EX

        Missed:
Level 1: [ ] [ ] [ ]
Level 2: [√] [√] [ ]
Level 3: [√] [ ] [ ]
Level 4: [√] [√] [√] [ ]
Level 5: [ ] [ ] [ ]

最终目标

+1 将为:level 添加 1 天,因为如果您不这样做,您将不会将一天视为已完成。 我们如何为每个点击的框添加 +1 到 :level

在上面的示例中,用户需要多花 2 天才能进入第 3 级,再需要 1 天才能进入第 4 级,等等。

如果您在某个关卡中错过了三天,我们如何强制用户重新开始该关卡? 例如,如果我在第 66 天并在如上所示的第 4 行,我们如何重新计算一天为 45?

此时,对于第 4 级,需要在通过 AJAX 进行的每个复选标记后出现一个额外的框,以防他在第二次尝试时错过了一天。我们可以只刷新我认为不需要的那个级别中显示的框,因为我们仍然需要计算他还剩下多少天。

class Habit < ActiveRecord::Base
belongs_to :user
before_save :set_level
acts_as_taggable
serialize :committed, Array

scope :missed, ->  where(missed: 1) 

def levels
		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 

  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

protected
def set_level
 self.level = levels
end	
end
end

<%= simple_form_for(@habit) do |f| %>
  <%= f.error_notification %>

<div class="america">
<form>

  <div class="committed">
  <%= f.label "Committed to:" %>&nbsp;
  <%= f.collection_check_boxes :committed, Date::DAYNAMES, :downcase, :to_s %>
  </div>

  <p><div class="date-group">
    <label> Started: </label>
    <%= f.date_select :date_started, :order => [:month, :day, :year], class: 'date-select' %>
  </div></p>

  <p><%= f.text_field :trigger, class: 'form-control', placeholder: 'Enter Trigger' %></p>
  <p><%= f.text_field :tag_list, habit: @habit.tag_list.to_s.titleize, class: 'form-control', placeholder: 'Enter Action' %></p>
  <p><%= f.text_field :target, class: 'form-control', placeholder: 'Enter Target' %></p>
  <p><%= f.text_field :positive, class: 'form-control', placeholder: 'Enter Reward' %></p>
  <%= f.text_field :negative, class: 'form-control', placeholder: 'Enter Penalty' %>
<% 5.times do |n| %>
  <%= f.label "Level #n+1:" %>
  <%= check_box_tag 'missed[]', value: n+1 %>
<% end %>

<div class="america2">
  <%= button_tag(type: 'submit', class: "btn") do %>
  <span class="glyphicon glyphicon-plus"></span>
  <% end %>

  <%= link_to habits_path, class: 'btn' do %>
  <span class="glyphicon glyphicon-chevron-left"></span>
  <% end %>

  <%= link_to @habit, method: :delete, data:  confirm: 'Are you sure?' , class: 'btn' do %>
  <span class="glyphicon glyphicon-trash"></span>
  <% end %>
</div>
  
</form>
</div>
<% end %>

class HabitsController < ApplicationController
  before_action :set_habit, only: [:show, :edit, :update, :destroy]
  before_action :logged_in_user, only: [:create, :destroy]

  def index
    if params[:tag]
      @habits = Habit.tagged_with(params[:tag])
    else
      @habits = Habit.all.order("date_started DESC")
      @habits = current_user.habits
    end
  end

  def show
  end

  def new
    @habit = current_user.habits.build
  end

  def edit
  end

  def create
    @habit = current_user.habits.build(habit_params)
    if  @habit.save
        redirect_to @habit, notice: 'Habit was successfully created.'
    else
        @feed_items = []
        render 'pages/home'
    end
  end

  def update
    if @habit.update(habit_params)
      redirect_to @habit, notice: 'Habit was successfully updated.'
    else
      render action: 'edit'
    end
  end

  def destroy
    @habit.destroy
    redirect_to habits_url
  end

  private
    def set_habit
      @habit = Habit.find(params[:id])
    end

    def correct_user
      @habit = current_user.habits.find_by(id: params[:id])
      redirect_to habits_path, notice: "Not authorized to edit this habit" if @habit.nil?
    end

    def habit_params
      params.require(:habit).permit(:missed, :left, :level, :date_started, :trigger, :target, :positive, :negative, :tag_list, :committed => [])
    end
end

谢谢你=]

附:只要能完成工作,就可以使用选择框、复选框、collection_boxes 等。

【问题讨论】:

您要添加到布尔列?那里的各种常量都相同的目的是什么? @tadman 我想要 :missed,它是一个表示 1 的整数,这样当用户点击其框时,索引将累加点击了多少框,因此代表用户的天数:错过了 仍然完全不清楚为什么你有这么多内容相同的常量,更令人困惑的是它们都只包含值1,没有明显的原因重复了三遍。请记住,列的名称中不应包含 ?。布尔列在文字列名中没有,但会自动创建一个以?结尾的便捷方法。 很抱歉给您带来了困惑。我只是把它留在那里以提供一些背景信息,但我想它最终只会造成混乱。我只是想保存复选框并表示是否通过增加索引中:missed 上的整数来检查它们。 对不起?是句子的一部分而不是代码。 【参考方案1】:

如果你想要一堆复选框,只需这样做:

<%- 5.times do |n| %->
  <%= f.label "Level #n+1:" %>
  <%= check_box_tag 'missed[]', value: n+1 %>
<%- end -%>

然后您应该收到一个missed 参数,其中包含一系列数字,每个数字对应于当天是否被选中。如果您想知道错过了多少天:

[params[:missed]].flatten.length

这处理params[:missed] 未定义的情况。

【讨论】:

Tadman 我认为您在执行此操作后错过了一部分:...非常感谢您的帮助! 哦,它就在那里,只是看不见。代码格式问题,现已修复。 谢谢!我更新了代码,但它仍然没有保存在 _form 中。有什么想法吗? “保存表单”是什么意思?如果您有一个有效的&lt;form&gt; 标签,那么它应该将请求发送到服务器。您还没有深入了解控制器代码。 对于像这样的非标准控件,您需要将传入的:missed 参数转换为模型可以接受的东西。控制器的工作是在 Web 请求接口和它需要存储和检索数据的各种模型之间进行中介。此责任的一部分包括映射传入参数。从您的代码中确实不清楚您要在这里做什么,最终目标是什么。

以上是关于如何为每个复选标记保存复选框并增加整数?的主要内容,如果未能解决你的问题,请参考以下文章

如何为asp.net中的每个项目添加复选框列表的工具提示

如何为每个复选框添加新输入? - Codeigniter

无论如何用数组填充 UITableView 但保留复选标记?

验证线性布局中的多个复选框

如何为javascript复选框提供onchange事件?

如何为复选框设置对齐对齐?