ruby - How to make Javascript generated checkboxes persist? -
the "ajax" in script sends post or delete message server. javascript, contains ajax, adds checkboxes. how can make created checkbox elements persistent when user refreshes page still there?
habits/_form.html.erb
<label id="<%= @habit.id %>" class="habit-id"> missed: </label> <% @habit.levels.each_with_index |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) { /* example, have ammend */ $(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 @ 0 end def current_level return 0 unless date_started def committed_wdays committed.map |day| date::daynames.index(day.titleize) end end def n_days ((date_started.to_date)..date.today).count |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 # returns empty response 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 # returns empty response 200 success status code end end
here's gist of it: https://gist.github.com/rallywithgalli/c66dee6dfb9ab5d338c2
please let me know if need further explanation, code, or pictures :)
the simplest method using local storage (stored in users browser). feature exists in modern browsers, when don't need support legacy browsers, best option.
the usage unbelievable simple, set , read attributes on "localstorage" variable:
# set 1 value localstorage.myapp_level1_flag1 = true; # read value if (localstorage.myapp_level1_flag1) { ... }
you of course should give variables meaningful names. values assigned localstorage saved across sessions. there variable "sessionstorage" saves data 1 session.
also data separated domains set. domain x can not access data set domain y.
local storage supported since ie8 , has advantage on cookies, data not transmitted server on every request. before local storage existed, cookies used, performance overhead attached.
integration
i recommend integration of local storage @ 2 positions in code (if understand js outline right):
(of course, say, don't understand js much, makes thing more difficult, because solution hinges on local storage @ browser side -- else need transfer data server side (which necessary in long run prevent data duplication))
first position: when create check boxes (just rough example how 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 @ 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); }
look here more information localstorage.
Comments
Post a Comment