2013-10-13 26 views
0

我一直在努力尋找一個很好的解決方案,以在我正在開發的網站上以列表格式顯示谷歌日曆。我碰到這段代碼,除了一些格式化問題外,其他代碼都很好。我並不是所有的人都知道jQuery,所以我在格式化方面苦苦掙扎。我儘可能地從CSS方面做了很多,但很明顯其中一部分是在腳本方面。也許如果有人可以請幫我刪除腳本中的格式,並嚴格css這將是偉大=)或另一個更好的解決方案= P谷歌日曆事件列表jQuery格式

非常感謝!

格式後,我很爲3段不同的div: 日期( '11月12日09:00')事件( '學生之夜')位置( 'Nicci海灘')

JS:

// Generated by CoffeeScript 1.4.0 
(function() { 
    var $, gCalFlow, log, methods, pad_zero, _ref; 

    $ = jQuery; 

    if ((typeof window !== "undefined" && window !== null) && (window._gCalFlow_debug != null) && (typeof console !== "undefined" && console !== null)) { 
    log = console; 
    if ((_ref = log.debug) == null) { 
     log.debug = log.log; 
    } 
    } else { 
    log = {}; 
    log.error = log.warn = log.log = log.info = log.debug = function() {}; 
    } 

    pad_zero = function(num, size) { 
    var i, ret, _i, _ref1; 
    if (size == null) { 
     size = 2; 
    } 
    if (10 * (size - 1) <= num) { 
     return num; 
    } 
    ret = ""; 
    for (i = _i = 1, _ref1 = size - ("" + num).length; 1 <= _ref1 ? _i <= _ref1 : _i >= _ref1; i = 1 <= _ref1 ? ++_i : --_i) { 
     ret = ret.concat("0"); 
    } 
    return ret.concat(num); 
    }; 

    gCalFlow = (function() { 

    gCalFlow.prototype.target = null; 

    gCalFlow.prototype.template = $("<div class=\"gCalFlow\">\n <div class=\"gcf-header-block\">\n <div class=\"gcf-title-block\">\n  <span class=\"gcf-title\"></span>\n </div>\n </div>\n <div class=\"gcf-item-container-block\">\n <div class=\"gcf-item-block\">\n  <div class=\"gcf-item-header-block\">\n  <div class=\"gcf-item-date-block\">\n   [<span class=\"gcf-item-daterange\"></span>]\n  </div>\n  <div class=\"gcf-item-title-block\">\n   <strong class=\"gcf-item-title\"></strong>\n  </div>\n  </div>\n  <div class=\"gcf-item-body-block\">\n  <div class=\"gcf-item-description\">\n  </div>\n  <div class=\"gcf-item-location\">\n  </div>\n  </div>\n </div>\n </div>\n <div class=\"gcf-last-update-block\">\n LastUpdate: <span class=\"gcf-last-update\"></span>\n </div>\n</div>"); 

    gCalFlow.prototype.opts = { 
     maxitem: 5, 
     calid: null, 
     mode: 'upcoming', 
     feed_url: null, 
     auto_scroll: false, 
     scroll_interval: 10 * 1000, 
     link_title: true, 
     link_item_title: true, 
     link_item_description: true, 
     link_target: '_blank', 
     item_description_in_html: false, 
     callback: null, 
     no_items_html: '', 
     globalize_culture: (typeof navigator !== "undefined" && navigator !== null) && (navigator.browserLanguage || navigator.language || navigator.userLanguage), 
     globalize_fmt_datetime: 'f', 
     globalize_fmt_date: 'D', 
     globalize_fmt_time: 't', 
     globalize_fmt_monthday: 'M', 
     date_formatter: function(d, allday_p) { 
     var fmtstr; 
     if ((typeof Globalize !== "undefined" && Globalize !== null) && (Globalize.format != null)) { 
      if (allday_p) { 
      fmtstr = this.globalize_fmt_date; 
      } else { 
      fmtstr = this.globalize_fmt_datetime; 
      } 
      return Globalize.format(d, fmtstr); 
     } else { 
      if (allday_p) { 
      return "" + (d.getFullYear()) + "-" + (pad_zero(d.getMonth() + 1)) + "-" + (pad_zero(d.getDate())); 
      } else { 
      return "" + (d.getFullYear()) + "-" + (pad_zero(d.getMonth() + 1)) + "-" + (pad_zero(d.getDate())) + " " + (pad_zero(d.getHours())) + ":" + (pad_zero(d.getMinutes())); 
      } 
     } 
     }, 
     daterange_formatter: function(sd, ed, allday_p) { 
     var endstr, ret; 
     ret = this.date_formatter(sd, allday_p); 
     if (allday_p) { 
      ed = new Date(ed.getTime() - 86400 * 1000); 
     } 
     endstr = ''; 
     if (sd.getDate() !== ed.getDate() || sd.getMonth() !== ed.getMonth()) { 
      if ((typeof Globalize !== "undefined" && Globalize !== null) && (Globalize.format != null)) { 
      endstr += Globalize.format(ed, this.globalize_fmt_monthday); 
      } else { 
      endstr += "" + (pad_zero(ed.getMonth() + 1)) + "-" + (pad_zero(ed.getDate())); 
      } 
     } 
     if (!allday_p && (sd.getHours() !== ed.getHours() || sd.getMinutes() !== ed.getMinutes())) { 
      if ((typeof Globalize !== "undefined" && Globalize !== null) && (Globalize.format != null)) { 
      endstr += Globalize.format(ed, this.globalize_fmt_time); 
      } else { 
      endstr += " " + (pad_zero(ed.getHours())) + ":" + (pad_zero(ed.getMinutes())); 
      } 
     } 
     if (endstr) { 
      ret += " - " + endstr; 
     } 
     return ret; 
     } 
    }; 

    function gCalFlow(target, opts) { 
     this.target = target; 
     target.addClass('gCalFlow'); 
     if (target.children().size() > 0) { 
     log.debug("Target node has children, use target element as template."); 
     this.template = target; 
     } 
     this.update_opts(opts); 
    } 

    gCalFlow.prototype.update_opts = function(new_opts) { 
     log.debug("update_opts was called"); 
     log.debug("old options:", this.opts); 
     this.opts = $.extend({}, this.opts, new_opts); 
     return log.debug("new options:", this.opts); 
    }; 

    gCalFlow.prototype.gcal_url = function() { 
     if (!this.opts.calid && !this.opts.feed_url) { 
     log.error("Option calid and feed_url are missing. Abort URL generation"); 
     this.target.text("Error: You need to set 'calid' or 'feed_url' option."); 
     throw "gCalFlow: calid and feed_url missing"; 
     } 
     if (this.opts.feed_url) { 
     return this.opts.feed_url; 
     } else if (this.opts.mode === 'updates') { 
     return "https://www.google.com/calendar/feeds/" + this.opts.calid + "/public/full?alt=json-in-script&max-results=" + this.opts.maxitem + "&orderby=lastmodified&sortorder=descending"; 
     } else { 
     return "https://www.google.com/calendar/feeds/" + this.opts.calid + "/public/full?alt=json-in-script&max-results=" + this.opts.maxitem + "&orderby=starttime&futureevents=true&sortorder=ascending&singleevents=true"; 
     } 
    }; 

    gCalFlow.prototype.fetch = function() { 
     var success_handler, 
     _this = this; 
     log.debug("Starting ajax call for " + (this.gcal_url())); 
     success_handler = function(data) { 
     log.debug("Ajax call success. Response data:", data); 
     return _this.render_data(data, _this); 
     }; 
     return $.ajax({ 
     success: success_handler, 
     dataType: "jsonp", 
     url: this.gcal_url() 
     }); 
    }; 

    gCalFlow.prototype.parse_date = function(dstr) { 
     var day, hour, m, min, mon, offset, ret, sec, year; 
     if (m = dstr.match(/^(\d{4})-(\d{2})-(\d{2})$/)) { 
     return new Date(parseInt(m[1], 10), parseInt(m[2], 10) - 1, parseInt(m[3], 10), 0, 0, 0); 
     } 
     offset = (new Date()).getTimezoneOffset() * 60 * 1000; 
     year = mon = day = null; 
     hour = min = sec = 0; 
     if (m = dstr.match(/^(\d{4})-(\d{2})-(\d{2})[T ](\d{2}):(\d{2}):(\d{2}(?:\.\d+)?)(Z|([+-])(\d{2}):(\d{2}))$/)) { 
     year = parseInt(m[1], 10); 
     mon = parseInt(m[2], 10); 
     day = parseInt(m[3], 10); 
     hour = parseInt(m[4], 10); 
     min = parseInt(m[5], 10); 
     sec = parseInt(m[6], 10); 
     if (m[7] !== "Z") { 
      offset += (m[8] === "+" ? 1 : -1) * (parseInt(m[9], 10) * 60 + parseInt(m[10], 10)) * 1000 * 60; 
     } 
     } else { 
     log.warn("Time parse error! Unknown time pattern: " + dstr); 
     return new Date(1970, 1, 1, 0, 0, 0); 
     } 
     log.debug("time parse (gap to local): " + offset); 
     ret = new Date(new Date(year, mon - 1, day, hour, min, sec).getTime() - offset); 
     log.debug("time parse: " + dstr + " -> ", ret); 
     return ret; 
    }; 

    gCalFlow.prototype.render_data = function(data) { 
     var ci, desc_body_method, ed, ent, et, etf, feed, ic, it, items, link, sd, st, stf, t, titlelink, _i, _len, _ref1, _ref2; 
     log.debug("start rendering for data:", data); 
     feed = data.feed; 
     t = this.template.clone(); 
     titlelink = (_ref1 = this.opts.titlelink) != null ? _ref1 : "http://www.google.com/calendar/embed?src=" + this.opts.calid; 
     if (this.opts.link_title) { 
     t.find('.gcf-title').html($("<a />").attr({ 
      target: this.opts.link_target, 
      href: titlelink 
     }).text(feed.title.$t)); 
     } else { 
     t.find('.gcf-title').text(feed.title.$t); 
     } 
     t.find('.gcf-link').attr({ 
     target: this.opts.link_target, 
     href: titlelink 
     }); 
     t.find('.gcf-last-update').html(this.opts.date_formatter(this.parse_date(feed.updated.$t))); 
     it = t.find('.gcf-item-block'); 
     it.detach(); 
     it = $(it[0]); 
     log.debug("item block template:", it); 
     items = $(); 
     log.debug("render entries:", feed.entry); 
     if (this.opts.item_description_as_html) { 
     desc_body_method = 'html'; 
     } else { 
     desc_body_method = 'text'; 
     } 
     if ((feed.entry != null) && feed.entry.length > 0) { 
     _ref2 = feed.entry.slice(0, +this.opts.maxitem + 1 || 9e9); 
     for (_i = 0, _len = _ref2.length; _i < _len; _i++) { 
      ent = _ref2[_i]; 
      log.debug("formatting entry:", ent); 
      ci = it.clone(); 
      if (ent.gd$when) { 
      st = ent.gd$when[0].startTime; 
      sd = this.parse_date(st); 
      stf = this.opts.date_formatter(sd, st.indexOf(':') < 0); 
      ci.find('.gcf-item-date').html(stf); 
      ci.find('.gcf-item-start-date').html(stf); 
      et = ent.gd$when[0].endTime; 
      ed = this.parse_date(et); 
      etf = this.opts.date_formatter(ed, et.indexOf(':') < 0); 
      ci.find('.gcf-item-end-date').html(etf); 
      ci.find('.gcf-item-daterange').html(this.opts.daterange_formatter(sd, ed, st.indexOf(':') < 0)); 
      } 
      ci.find('.gcf-item-update-date').html(this.opts.date_formatter(this.parse_date(ent.updated.$t), false)); 
      link = $('<a />').attr({ 
      target: this.opts.link_target, 
      href: ent.link[0].href 
      }); 
      if (this.opts.link_item_title) { 
      ci.find('.gcf-item-title').html(link.clone().text(ent.title.$t)); 
      } else { 
      ci.find('.gcf-item-title').text(ent.title.$t); 
      } 
      if (this.opts.link_item_description) { 
      ci.find('.gcf-item-description').html(link.clone()[desc_body_method](ent.content.$t)); 
      } else { 
      ci.find('.gcf-item-description')[desc_body_method](ent.content.$t); 
      } 
      ci.find('.gcf-item-location').text(ent.gd$where[0].valueString); 
      ci.find('.gcf-item-link').attr({ 
      href: ent.link[0].href 
      }); 
      log.debug("formatted item entry:", ci[0]); 
      items.push(ci[0]); 
     } 
     } else { 
     items = $('<div class=".gcf-no-items"></div>').html(this.opts.no_items_html); 
     } 
     log.debug("formatted item entry array:", items); 
     ic = t.find('.gcf-item-container-block'); 
     log.debug("item container element:", ic); 
     ic.html(items); 
     this.target.html(t.html()); 
     this.bind_scroll(); 
     if (this.opts.callback) { 
     return this.opts.callback.apply(this.target); 
     } 
    }; 

    gCalFlow.prototype.bind_scroll = function() { 
     var scroll_children, scroll_container, scroll_timer, scroller, state; 
     scroll_container = this.target.find('.gcf-item-container-block'); 
     scroll_children = scroll_container.find(".gcf-item-block"); 
     log.debug("scroll container:", scroll_container); 
     if (!this.opts.auto_scroll || scroll_container.size() < 1 || scroll_children.size() < 2) { 
     return; 
     } 
     state = { 
     idx: 0 
     }; 
     scroller = function() { 
     var scroll_to; 
     log.debug("current scroll position:", scroll_container.scrollTop()); 
     log.debug("scroll capacity:", scroll_container[0].scrollHeight - scroll_container[0].clientHeight); 
     if (typeof scroll_children[state.idx] === 'undefined' || scroll_container.scrollTop() >= scroll_container[0].scrollHeight - scroll_container[0].clientHeight) { 
      log.debug("scroll to top"); 
      state.idx = 0; 
      return scroll_container.animate({ 
      scrollTop: scroll_children[0].offsetTop 
      }); 
     } else { 
      scroll_to = scroll_children[state.idx].offsetTop; 
      log.debug("scroll to " + scroll_to + "px"); 
      scroll_container.animate({ 
      scrollTop: scroll_to 
      }); 
      return state.idx += 1; 
     } 
     }; 
     return scroll_timer = setInterval(scroller, this.opts.scroll_interval); 
    }; 

    return gCalFlow; 

    })(); 

    methods = { 
    init: function(opts) { 
     var data; 
     if (opts == null) { 
     opts = {}; 
     } 
     data = this.data('gCalFlow'); 
     if (!data) { 
     return this.data('gCalFlow', { 
      target: this, 
      obj: new gCalFlow(this, opts) 
     }); 
     } 
    }, 
    destroy: function() { 
     var data; 
     data = this.data('gCalFlow'); 
     data.obj.target = null; 
     $(window).unbind('.gCalFlow'); 
     data.gCalFlow.remove(); 
     return this.removeData('gCalFlow'); 
    }, 
    render: function() { 
     if ((typeof Globalize !== "undefined" && Globalize !== null) && (Globalize.culture != null)) { 
     Globalize.culture(this.data('gCalFlow').obj.opts.globalize_culture); 
     } 
     return this.data('gCalFlow').obj.fetch(); 
    } 
    }; 

    $.fn.gCalFlow = function(method) { 
    var orig_args; 
    orig_args = arguments; 
    if (typeof method === 'object' || !method) { 
     return this.each(function() { 
     methods.init.apply($(this), orig_args); 
     return methods.render.apply($(this), orig_args); 
     }); 
    } else if (methods[method]) { 
     return this.each(function() { 
     return methods[method].apply($(this), Array.prototype.slice.call(orig_args, 1)); 
     }); 
    } else if (method === 'version') { 
     return "1.2.5"; 
    } else { 
     return $.error("Method " + method + " does not exist on jQuery.gCalFlow"); 
    } 
    }; 

}).call(this); 

HTML:

<div id="gcf-custom-template"> 
         <div class="gcf-item-container-block"> 
         <div class="gcf-item-block"> 
          <div class="gcf-item-header-block"> 
           <div class="gcf-item-title-block"> 
            <div style="float: left; width 250px;"><a class="gcf-item-link"><span class="gcf-item-daterange">2012-02-01 09:00</span>:</a></div> 
            <div style="float: left; width 250px;"><a class="gcf-item-location">1-877-346-9707 w 55586#</a></div> 
            <div style="float: left; width 250px;"><strong><a class="gcf-item-title">Item Title of Your event</a></strong></div> 
           </div> 
          </div> 
         </div> 
         </div> 
        </div> 

腳本中調用:

<script type="text/javascript"> 
     var $ = jQuery; 
     $(function() { 
     $('#gcf-custom-template').gCalFlow({ 
      calid: '[email protected]', 
      maxitem: 50, 
      mode: 'updates', 
      date_formatter: function(d, allday_p) { return (d.getMonth()+1) + "/" + d.getDate() + "/" + d.getYear().toString().substr(-2) } 
     }); 
     }); 
    </script> 

回答

0

這是我對類似問題的解決方案,使用日期格式的moment.js,使用模板的markupjs,以及使生活更簡單的jQuery。

// a markup.js pipe which calls on moment.js for formatting 
Mark.pipes.moment = function (date, format) { 
    return moment(new Date(date)).format(format); 
}; 

// a markup.js pipe that tests if two dates are in the same month (difference between "1st-2nd december" and "30 november - 2 december") 
Mark.pipes.diffmonth = function (date1, date2) { 
    moment1 = moment(new Date(date1)); 
    moment2 = moment(new Date(date2)); 
    var ret= moment1.month()!=moment2.month(); 
    return ret; 
}; 

// a markup.js pipe to filter an array 
Mark.pipes.sift = function (arr, prop, val) { 
    return $.grep(arr,function(item) { 
    return item[prop] == val; 
    }); 
}; 

$(document).ready(loadCalendarData); 

// this is a google calendar public full json feed (to have complete date and location information) 
calendarURL = "http://www.google.com/calendar/feeds/[email protected]/public/full?alt=json-in-script&orderby=starttime&singleevents=true&sortorder=ascending&futureevents=true&callback=?"; 

function loadCalendarData() { 
    $.getJSON(calendarURL, applyTemplate); 
} 

function applyTemplate(cal_data) { 

    // format dates in french 
    moment.lang("fr"); 

    // take cal_data, a google calendar json full feed. and extract VCALENDAR fields. Also extract a type field that distinguishes single day events from multiple day events. 
    var events = $.map(cal_data["feed"]["entry"], function (event) { 
    var url= $.grep(event["link"], function(link) { 
     return link["rel"]=="related"; 
    }); 
    return { 
     "summary": event["title"]["$t"], 
     "dtstart": event["gd$when"][0]["startTime"], 
     "dtend": event["gd$when"][0]["endTime"], 
     "url": url[0]?url[0]["href"]:"", 
     "location": event["gd$where"][0]["valueString"], 
     "type": (moment.duration(new Date(event["gd$when"][0]["endTime"])-new Date(event["gd$when"][0]["startTime"])).as("hours")<18)?"single":"multi" 
    }; 

    }); 

    // summary with url link if exists 
    Mark.includes.linked_summary = "{{if url}}<a href='{{url}}'>{{/if}}{{summary}}{{if url}}</a>{{/if}}"; 
    // location in brackets if exists 
    Mark.includes.optional_location = "{{if location}}&nbsp;({{location}}){{/if}}" 

    // separate list of evenings and multiple day/weeked events 
    var template = 
    "Les soir&eacute;es &agrave; venir :<ul>{{events|sift>type>single}}"+ 
    "<li>{{dtstart|moment>dddd|capcase}} {{dtstart|moment>D/M}}: {{linked_summary}}{{optional_location}}</li>"+ 
    "{{/events}}</ul>"+ 
    "<br>"+ 
    "Les stages et weekends &agrave; venir (2013/2014):<ul>{{events|sift>type>multi}}"+ 
    "<li>{{dtstart|moment>D}}{{if dtstart|diffmonth>`dtend`}}{{dtstart|moment>/M}}{{/if}}-{{dtend|moment>D/M}}: {{linked_summary}}{{optional_location}}</li>"+ 
    "{{/events}}</ul>"; 

    $("#web").html(Mark.up(template, {"events":events})); 
} 
+0

請注意,Google日曆中的全天事件在第二天的00:00:00結束。因此,整天的事件將被一個抵消。 – Tirno