Rails:如何在datepicker中添加工具提示事件并在几个月内限制它们

我有一个datepicker,我希望用户在其中看到由admin创建的所有事件。 添加function以添加带有事件标题的工具提示会很不错。

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

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

var events = @events; 

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

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

  var events =   

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

 [[" 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"]] 

这是一个像这[[“标题”,“事件的日期”],…]的数组
但是如何将它们放在带有beforeShowDday的datepicker中呢?

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

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

从文档中看,数组只是jQuery UI正在寻找的事物的顺序。

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

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

  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 ] 

更新:堆栈溢出(我假设所有堆栈交换站点)使用以下内容显示“已访问”日历。 我认为这种方法比我好得多,所以我要更换它。

实际的“访问”日期存储在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 。 Hash是键值对。 这意味着您可以设置日期的key以及标题的value 。 这将允许您轻松匹配jQuery提供的日期和事件列表中的日期。

这是您需要添加到控制器的内容。 我使用了一个名为strftime()的函数来格式化日期。 基本上我将它改为“day-month-year”,这将更容易与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中,您可以获得@events

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