Rails:如何在datepicker中添加工具提示事件,并在几个月内限制它们 [英] Rails: How to add tooltip events in datepicker and limit them in few months

查看:126
本文介绍了Rails:如何在datepicker中添加工具提示事件,并在几个月内限制它们的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个datepicker,我希望用户看到由admin创建的所有事件。添加功能以添加事件标题的工具提示是非常好的。



我知道允许这样的一个事情,演示/ datepicker /rel =nofollow>
我必须使用
beforeShowDay 方法。但是这里有个问题。



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

  var events = @events ; 

2)第二和最重要的问题。这种方法将导致我的应用程序获得大量的事件来处理。当事件开始得到很多时,这会减慢一切。根据今天的日期,如何限制几个月的事件?

希望清楚。任何帮助?



更新1 (第一个问题和第二个问题的一小部分被解决)
我设法传递给我的这个我的实例事件数组:

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

这样我就可以通过范围界限来简化控制器中的事情。

当我检查浏览器控制台事件数组是这样组合的:

  [[快速运动员ca.伦敦2012,2012-07-28T00:00:00Z],[AdWords API办公时间EMEA​​,2012-07-25T00:00:00Z],[数学 2012-07-22T00:00:00Z],[超人力量,2012-07-13T00:00:00Z],[Google I / O 2012主题演讲,2012-07-01T00:00 :00Z]] 

哪个是这样的数组[[title,date事件],...]

但是,如何将它们放在dateDicker之前?显示日期?



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

  $(#datepicker)。datepicker({
jQuery。每个(事件,函数(索引,事件){
beforeShowDay:function(event [0]){
return [true,,event [1]];
}
});
});


解决方案

从文档看,数组只是一个


该函数将日期作为参数,必须返回一个[0]等于的数组为true / false,表示此日期是否可选,[1]等于默认演示文稿的CSS类名称或,以及[2]此日期的可选弹出工具提示。


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


  1. 应该可以选择日期

  2. 如果你在一天添加一个课程

  3. 什么是其工具提示

以下是代码中的一个示例

  //函数应该返回
return [
(boolean)是可选的日期,
(string)添加到一天的类,
(字符串)当悬停在
上时显示的文本

更新:堆栈溢出(和我假定所有Stack Exchange站点)使用以下内容显示访问日历。我认为这种方法比我的好多了,所以我正在替换它。



实际的访问日期存储在JSON中。

  {__ YEAR__:{__MONTH__:{__DAY __:1}}} 
/ pre>

这是一个例子。

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

然后在 beforeShowDay 之前,确保 对象的键存在。这是我的代码版本。

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

hasVisited = visited [y]&&已访问[y] [m]&&访问[y] [m] [d];

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

生成需要填写的JSON是非常具体的表结构。如果您需要帮助创建JSON,我需要更多的继续。



更新2



问题是JavaScript无法调用对象中的函数,它的语法无效。另一件事是,我恐怕在数组中的所有项目中循环使用效率非常低。



您的代码的正确语法如下所示。但是正如我所说,我不会建议这样做,因为效率不高。



注意 beforeShowDay :function(__ PARAM __)。 jQuery自动传递 __ PARAM __ 。这意味着你需要确保它是你正在寻找的价值,而不是问jQuery是否是jQuery的价值。



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

  var events = ['created a新产品,30-8-2012]; 

console.log(events [0]); //创建新产品
console.log(events [1]); //30-8-2012

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

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

//确保事件的日期与jQuery的日期匹配
if(event [1] == date){
active_class =had-activity;
}

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



更改



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



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



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



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



3。
%Y 返回四位数年份。

 事件= {}#创建一个空的哈希

#获取所有的事件并将它们添加到`@ events`
CalendarEvent.select('date,title')。事件|
@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() ,//获取当天的日子
formatted_date = d +' - '+ m +' - '+ y;

hasVisited = events [formatted_date];

return [true,(hasVisited?'has-visited-class':''),hasVisited];
}
});
});
<%end%>


I have a datepicker in which I want user to see coloured all the events created by admin. It would be nice to add the functionality to add a tooltip with the title of the event.

I know that jQueryUI's datepicker allows such a thing. I have to use the beforeShowDay method. But here comes the questions.

1) How will I pass the @events array to the jquery code? I know I can access to that array in the view but am I allowed to do something like this:

var events = @events;

2) Second and most important question. This approach will lead my application to get an enormous amount of events to handle. This will slow down everything when the events start to get a lot. How can I limit the events just in few months depending on today date?
Hope to be clear. Any help??

UPDATE 1 (first problem and a small part of second are solved) ok I managed to pass to javascript my instance events array like this:

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

This way I can limit the events the way I want simply in the controller via scoping.
When I check in browser console events array is composed this way:

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

Which is an array made like this [["title", "date of the events"], ...]
But how can I put them in the datepicker with beforeShowDday??

This is my first attempt but it's not working

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

解决方案

From the documentation it looks like the array is just an order of things the jQuery UI is looking for.

The function takes a date as a parameter and must return an array with [0] equal to true/false indicating whether or not this date is selectable, [1] equal to a CSS class name(s) or "" for the default presentation, and [2] an optional popup tooltip for this date. It is called for each day in the datepicker before it is displayed.

Basically the function needs to return three items.

  1. Should the date be selectable
  2. Should you add a class to the day
  3. What is its tooltip

Here's an example in code

// 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
]

Update: Stack Overflow (and I presume all Stack Exchange sites) use the following for displaying the "visited" calendar. I think this method is much better than mine so I'm replacing it.

The actual "visited" dates are stored in JSON like so.

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

Here's an example.

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

Then inside beforeShowDay they make sure the visited object's keys exist. Here's my version of their code.

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'];        
}

To generate the JSON needed to fill this in is very specific to your table structure. If you need help with creating the JSON I'll need a little more to go on.

Update 2

The problem is JavaScript can't call a function within an object, it's invalid syntax. The other thing is that I'm afraid it would be very inefficient looping through all of the items in the array.

The correct syntax for your code would look like this. But as I mentioned, I wouldn't suggest doing this because of inefficiency.

Note: in the line beforeShowDay: function(__PARAM__). The __PARAM__ is automatically passed by jQuery. Which means you need to make sure it's the value you are looking for, rather than asking jQuery if that's the value jQuery's looking for.

The other thing is that arrays start at 0. In fact, all programming languages start at zero. Therefore, to get the value at the index you want, you would do it like so.

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

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

Here's the corrected syntax of your code, but it will not work because you can't return from the .each() function like I have below. I'm only providing this so you can see how I'm about to correct what you have written.

$("#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]];
    }
  }
});

The Changes

Inside your controller you need to pull the events out in a very specific way. I'd suggest using a Ruby Hash. A Hash is a key-value pair. Which means you can set the key to your date, and the value to your title. This will allow you to easily match the date provided by jQuery and the dates in your event list.

This is what you need to add to your controller. I used a function called strftime() that will format the date. Basically I changed it to be "day-month-year", which will be easier to match with jQuery.

1. %e returns the day of the month without zero padding. So 1 not 01.

2. %-m returns the month without zero padding.

3. %Y returns a four digit year.

@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

Then in your JavaScript you can get the @events with.

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

这篇关于Rails:如何在datepicker中添加工具提示事件,并在几个月内限制它们的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆