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

时间:2012-08-29 12:49:40

标签: jquery ruby-on-rails jquery-ui events datepicker

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

我知道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]];
    }
  });
});

1 个答案:

答案 0 :(得分:2)

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

  

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

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

  1. 日期应该可以选择
  2. 您应该在当天添加课程
  3. 什么是工具提示
  4. 以下是代码

    中的示例
    // 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 HashHash是键值对。这意味着您可以将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 %>