我有一个日期选择器,我希望用户可以看到管理员创建的所有事件。添加功能以添加带有事件标题的工具提示会很不错。
我知道jQueryUI's 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"]]
这是一个像这样[[“标题”,“事件的日期”],......]的数组
但是如何将它们放在带有beforeShowDday的日期选择器中?
这是我的第一次尝试,但它不起作用
$("#datepicker").datepicker({
jQuery.each(events, function(index, event) {
beforeShowDay: function(event[0]) {
return [true, "", event[1]];
}
});
});
答案 0 :(得分:2)
从文档中看,数组只是jQuery UI正在寻找的事物的顺序。
该函数将日期作为参数,并且必须返回一个数组,其中[0]等于true / false,表示此日期是否可选,[1]等于CSS类名称或“”表示默认演示文稿,[2]此日期的可选弹出工具提示。在显示之前,会在datepicker中调用它。
基本上该功能需要返回三个项目。
以下是代码
中的示例// 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的帮助,我还需要更多信息。
问题是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 %>