在脚本中的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的的更多信息。