如何使Javascript的产生复选框坚持?复选框、Javascript

2023-09-11 01:23:08 作者:电击、击不透心死つ

在脚本中的Ajax的发帖子或删除邮件服务器。 JavaScript的,它包含了ajax,就是增加了复选框。我们怎样才能使所创建的复选​​框元素持久的,因此当用户刷新页面,他们仍然存在?

The "ajax" in the script sends a post or delete message to the server. The javascript, which contains the ajax, is what adds the checkboxes. How can we make the created checkbox elements persistent so when a user refreshes the page they are still there?

习惯/ _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() {
  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);
});

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

请让我知道如果你需要任何进一步的解释,code或图片:)

Please let me know if you need any further explanation, code, or pictures :)

推荐答案

最简单的方法是使用本地存储(存储在用户的浏览器)。该功能存在于现代的浏览器,所以当你不需要支持旧版浏览器,这是最好的选择。

The simplest method is using local storage (stored in the users browser). That feature exists in modern browsers, so when you don't need to support legacy browsers, it is the best option.

用法也是令人难以置信的简单,只需要设置和读取上的localStorage的变量属性:

The usage is also unbelievable simple, just set and read attributes on the "localStorage" variable:

# Set one value
localStorage.myapp_level1_flag1 = true;

# read the value
if (localStorage.myapp_level1_flag1) {
   ...
}

您当然应该给变量有意义的名称。分配给localStorage的值将在会话被保存。还有一个变量sessionStorage节省数据只为一个会议。

You of course should give the variables meaningful names. The values assigned to localStorage will be saved across sessions. There is also a variable "sessionStorage" that saves data only for one session.

另外,根据数据通过它被设置域分离。因此域X不能访问的数据通过Y域设置。

Also the data is separated by the domains it was set. So domain X can not access data set by domain Y.

本地存储大致自IE8支撑并具有这样的优点超过饼干,该数据不被发送到每个请求的服务器。存在本地存储之前,饼干在哪里使用,附带一些性能开销。

Local Storage is supported roughly since IE8 and has the advantage over cookies, that the data is not transmitted to the server on every request. Before local storage existed, cookies where used, with some performance overhead attached.

综合

我会建议本地存储的整合在你的code两个位置(如果我没有理解你的JS大纲右):

I would recommend the integration of the local storage at two positions in your code (if I understand your JS outline right):

(,你说,你不知道JS来得多,这使得   的东西要困难得多,因为该解决方案的铰链完全   就在浏览器端的本地存储 - 但其他人则需要   从服务器端传送的所有数据(这可能是必要的   从长远来看,以prevent数据复制))

(of course, you say, that you don't understand JS to much, that makes the thing much more difficult, because the solution hinges completely on local storage at the browser side -- but else you would need to transfer all the data from your server side (which could be necessary in the long run to prevent data duplication))

第一的位置是:当您创建的复选​​框(只是一个粗略的例子这怎么可能):

First position: When you create the check boxes (just a rough example how it could be):

if (localStorage.habit_level1_flag1) {
    $(this).parent().append($('<input type="checkbox" class="habit-check" checked>'));
}
else {
    $(this).parent().append($('<input type="checkbox" class="habit-check">'));
}

另一个位置是在变化的处理程序:

The other position is at the change handler:

if ($(this).is(":checked")) {
  $.ajax({
    url: "/habits/" + habit + "/levels/" + level + "/days_missed",
    method: "POST"
  });
  localStorage.setItem("habit_"+habit+"_"+level, true);
} else {
  $.ajax({
    url: "/habits/" + habit + "/levels/" + level + "/days_missed/1",
    method: "DELETE"
  });
  localStorage.setItem("habit_"+habit+"_"+level, true);
}

在这里寻找有关 localStorage的的更多信息。