如何使用LocalStorage使复选框保持不变?

时间:2015-05-13 18:04:21

标签: javascript jquery ruby-on-rails ajax checkbox

即使重新加载页面,我们如何才能让用户保留复选框?

如果您拥有Javascript专业知识,请帮助我完成相关的AJAX调用,或者给我一些进一步的指导,以便我自己寻求答案。

每三个框用户检查一组新的三个框将显示。我们怎样才能让这些AJAX诱导的盒子消失?

enter image description here

习惯/ _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"
      });
      localStorage.setItem("habit_"+habit+"_"+level, true);
    } else {
      $.ajax({
        url: "/habits/" + habit + "/levels/" + level + "/days_missed/1",
        method: "DELETE"
      });
      localStorage.setItem("habit_"+habit+"_"+level, true);
    }
    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

如果您需要任何进一步的说明,代码或图片,请与我们联系。 谢谢这么多你的时间!

1 个答案:

答案 0 :(得分:1)

查看你的代码,其中一个setItem调用localstorage set checkbox值为false

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, false);//<--- ? ?
    }

我做了一个快速的小提示,展示了如何将对象传递给localStorage,并在以后加载它们。

首次加载页面时,检查用户是否保存了某些内容,如果是,请跳过ajax请求等,然后根据localStorage上的信息创建行。

http://jsfiddle.net/rainerpl/s39c9fws/18/

<div id="container">
<div class="row" id="row_1">
    <span class="label">Row 1:</span>
   <input type="checkbox" name="test" id="check_1" value="1" />
   <input type="checkbox" name="test" id="check_2" value="1" />
   <input type="checkbox" name="test" id="check_3" value="1" />
</div>
</div>

<input type="button" value="clear saved values" onclick="localStorage.setItem('checkbox_rows', false)"/>

<input type="button" value="add new row" onclick="addNewRow()"/>


var saveChecks = function() {
    var rows = $(".row"), saveObj = [], alreadySavedRows = localStorage.getItem("checkbox_rows");
    if ( alreadySavedRows ) {alreadySavedRows = JSON.parse(alreadySavedRows);}
    console.log("saveChecks", rows.length);
    if ( alreadySavedRows && alreadySavedRows.length ) {saveObj = alreadySavedRows;}
    var replacePreviousRow = function(row_obj) {
        var i;
        for ( i = 0; i < saveObj.length; i++ ) {
            if ( saveObj[i].row_id == row_obj.row_id ) {
               // console.log("replaced previous", row_obj);
                saveObj[i] = row_obj;return true;
            }
        }
        return false;
    }
    $.each(rows, function( key, val ) {
        var 
            checks = $(val).find("input[type='checkbox']"),
            rowObj = {"row_id": $(val).attr("id"), "checkboxes": []};
        ;
        rowObj.label = $(val).find(".label").text();
        $.each(checks, function( key, check ) {
            check= $(check);
            rowObj.checkboxes.push({
                check_id: check.attr("id"), 
                checked: check.prop('checked'),
                value: check.attr("value")
            });
        });
        // console.log("rowObj before", rowObj);
        if ( !replacePreviousRow(rowObj ) ) { saveObj.push(rowObj);}


    });
    //console.log("saveObj", saveObj);
    localStorage.setItem( "checkbox_rows",  JSON.stringify(saveObj) );
}
var container = $("#container");
var loadChecks = function() {
    var rows = localStorage.getItem("checkbox_rows"), i, j, row, check, rowElem, checkElem;
    if ( !rows ) {return false;}
    rows = JSON.parse(rows);
    if ( !rows || !rows.length ) {return false;}
    //console.log("rows:", rows);

    for ( i = 0; i < rows.length; i++ ) {
        row = rows[i];
        //remove any previously existing rows
        $("#" + row.row_id).remove();
        rowElem = $("<div class='row'></div>");
        rowElem.attr("id", row.row_id);
        container.append(rowElem);
        rowElem = $("#" + row.row_id );
        rowElem.append("<span class='label'>"+row.label+"</span>");
        for ( j = 0; j < row.checkboxes.length; j++ ) {
            check = row.checkboxes[j];
            checkElem = $("<input type='checkbox' name='test'/>");
            checkElem.attr("id", check.check_id);
            rowElem.append(checkElem);
            checkElem = $("#" + check.check_id);
            checkElem.attr("id", check.check_id);
            checkElem.attr("value", check.value);
            checkElem.prop("checked", check.checked);

        }
    }
}

window.addNewRow = function() {
    var rowElem = $("<div class='row'></div>"), i, row_id, checkElem;
    row_id = Math.round(1000*Math.random());
    rowElem.attr("id", "row_" + row_id );
    rowElem.append("<span class='label'>Row id:" + row_id +"</span>");
    for (i = 0; i < Math.ceil( Math.random() * 10 ); i++ ) {
        checkElem = $("<input type='checkbox' name='test' />");
        checkElem.attr("id", "check_" + row_id + "_" + i );
        checkElem.val(i);
        rowElem.append(checkElem);
    }
    container.append(rowElem);
    setTimeout(saveChecks, 100);
}

$().ready(function() {
    console.log("ready");
    setTimeout( loadChecks, 30);
    $("body").on("click", ".row", function(evt) {
        var row = $(evt.currentTarget), notChecked = row.find("input:not(:checked)").length, id;
        console.log("evt",notChecked);
        if ( !notChecked ) {
            id = Math.ceil( 1000 * Math.random() );
            row.append("<input type='checkbox' name='test' id='check_"+id+"' value='1' />");
        }
        saveChecks();
    });

});