1

我有一个日期选择器,我希望用户在其中看到管理员创建的所有事件的颜色。添加功能以添加带有事件标题的工具提示会很好。

我知道 jQueryUI 的 datepicker允许这样的事情。我必须使用beforeShowDay方法。但问题来了。

1) 我如何将@events 数组传递给jquery 代码?我知道我可以在视图中访问该数组,但我可以这样做:

var events = @events;

2)第二个也是最重要的问题。这种方法将导致我的应用程序处理大量事件。当事件开始变得很多时,这将减慢一切。如何根据今天的日期将事件限制在几个月内?
希望清楚。有什么帮助吗??

更新1(第一个问题和第二个问题的一小部分已解决)好的,我设法将我的实例事件数组传递给javascript,如下所示:

<%= javascript_tag do %>
  var events = <%= raw @calendar_events.to_json %>
<% end %>

这样,我可以通过范围限定在控制器中以我想要的方式限制事件。
当我签入浏览器控制台事件数组是这样组成的:

[[" Snap-happy athletes ca...arrival at London 2012 ", "2012-07-28T00:00:00Z"], ["AdWords API Office Hours EMEA", "2012-07-25T00:00:00Z"], ["Under the math", "2012-07-22T00:00:00Z"], ["Superman power", "2012-07-13T00:00:00Z"], ["Google I/O 2012 Keynote","2012-07-01T00:00:00Z"]]

哪个是这样制作的数组 [["title", "date of the events"], ...]
但是我怎样才能将它们放入带有 beforeShowDday 的日期选择器中?

这是我的第一次尝试,但它不起作用

$("#datepicker").datepicker({
  jQuery.each(events, function(index, event) {
    beforeShowDay: function(event[0]) {
      return [true, "", event[1]];
    }
  });
});
4

1 回答 1

2

从文档看来,数组只是 jQuery UI 正在寻找的东西的顺序。

该函数将日期作为参数,并且必须返回一个数组,其中 [0] 等于 true/false 指示此日期是否可选,[1] 等于 CSS 类名称或默认表示为 "" , 和 [2] 此日期的可选弹出工具提示。在显示之前,它会在日期选择器中的每一天被调用。

基本上该函数需要返回三个项目。

  1. 日期是否可以选择
  2. 您是否应该在当天添加课程
  3. 它的工具提示是什么

这是代码中的示例

// what the function should return
return [
  (boolean) is the date selectable,
  (string) the class to add to the day,
  (string) the text to show when hovered over
]

更新: Stack Overflow(我认为所有 Stack Exchange 站点)使用以下内容显示“已访问”日历。我认为这种方法比我的好得多,所以我正在更换它。

实际的“访问”日期像这样存储在 JSON 中。

{__YEAR__: {__MONTH__: {__DAY__:1}}}

这是一个例子。

var visited = {2012: {1: {1:1, 3:1, 4:1, 5:1, 18:1,19:1}, {3: {4:1, 5:1}}}

然后在里面beforeShowDay他们确保visited对象的键存在。这是我的他们的代码版本。

beforeShowDay: function(date) {
  var y = date.getFullYear(),
      m = date.getMonth() + 1,
      d = date.getDay(),

      hasVisited = visited[y] && visited[y][m] && visited[y][m][d];

  return [false, (hasVisited ? 'has-visited-class' : ''), 'date'];        
}

生成填充此所需的 JSON 非常特定于您的表结构。如果您在创建 JSON 方面需要帮助,我将需要更多工作。

更新 2

问题是 JavaScript 不能在对象中调用函数,这是无效的语法。另一件事是,我担心循环遍历数组中的所有项目会非常低效。

您的代码的正确语法如下所示。但正如我所提到的,由于效率低下,我不建议这样做。

注意:在行中beforeShowDay: function(__PARAM__)。__PARAM__jQuery 自动传递。这意味着您需要确保它是您正在寻找的值,而不是询问 jQuery 是否是 jQuery 正在寻找的值。

另一件事是数组从0. 事实上,所有的编程语言都是从零开始的。因此,要获得所需索引处的值,您可以这样做。

var events = ['created a new product', '30-8-2012'];

console.log(events[0]); // "created a new product"
console.log(events[1]); // "30-8-2012"

这是您的代码的更正语法,但它不起作用,因为您无法从.each()下面的函数返回。我只是提供这个,以便您可以看到我将如何更正您所写的内容。

$("#datepicker").datepicker({
  beforeShowDay: function(date) {
    jQuery.each(events, function(index, event) {
      var active_class = "no-activity";

      // make sure the event's date matches jQuery's date
      if( event[1] == date ) {
        active_class = "had-activity";
      }

      return [true, active_class, event[0]];
    }
  }
});

变化

在您的控制器内部,您需要以一种非常具体的方式提取事件。我建议使用Ruby Hash。AHash是一个键值对。这意味着您可以将 设置key为您的日期,并将 设置value为您的标题。这将允许您轻松匹配 jQuery 提供的日期和事件列表中的日期。

这是您需要添加到控制器的内容。我使用了一个名为的函数strftime()来格式化日期。基本上我把它改成了“日-月-年”,这样更容易和jQuery匹配。

1. %e返回没有零填充的月份中的日期。所以1不是01

2. %-m返回没有零填充的月份。

3. %Y返回一个四位数的年份。

@events = {} # create an empty hash

# get all the events and add them to `@events`
CalendarEvent.select('date, title').all.map do |event|
  @events[event.date.strftime('%e-%-m-%Y')] = event.title
end

然后在你的 JavaScript 中你可以得到@eventswith。

<% javascript_tag do %>
$(document).ready(function() {
  var events = <%= @events.to_json %>;

  $("#datepicker").datepicker({
    beforeShowDay: function(date) {
      var y = date.getFullYear(),
          m = date.getMonth() + 1,
          d = date.getDate(), // gets the day of the month
          formatted_date = d + '-' + m + '-' + y;

          hasVisited = events[formatted_date];

      return [true, (hasVisited ? 'has-visited-class' : ''), hasVisited];
    }
  });
});
<% end %>
于 2012-08-29T13:39:49.523 回答