样式化CLNDR.js日历多日事件的第一天和最后几天

时间:2016-06-17 09:53:32

标签: javascript jquery calendar underscore.js momentjs

我正在使用clndr.js(http://kylestetz.github.io/CLNDR/)来显示假日小屋预订的日期。这些始终使用多日活动系统显示,因为最低预订为3天。我现在需要以不同的方式设计活动的第一天和最后一天,以显示它们是转换日。理想情况下,我会通过向td添加一个类来实现此目的。这就是我到目前为止所做的:

JS

$('#calendar').clndr({
          template: $('#calendar-template').html(),
          weekOffset: 1,
           daysOfTheWeek: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
           targets: {
               nextButton: 'clndr-next',
               previousButton: 'clndr-previous'
           },
           multiDayEvents: {
               startDate: 'start',
               endDate: 'end'
           },
           events: events,
           clickEvents: {
               click: function(target) {
                   //alert(target);
               }
           }
      });

示例JSON

var events = [
  {start:'2016-05-29T00:00:00+00:00',
  end:'2016-06-01T00:00:00+00:00',
  title:'Mrs A N Human',},
  {start:'2016-08-10T00:00:00+00:00',
  end:'2016-08-17T00:00:00+00:00',
  title:'Mr A Person',}
];

HTML /下划线

 <div id="calendar">
  <script type="text/template" id="calendar-template">
   <table class="table">
    <thead>
     <tr>
      <th class='clndr-previous'>&lt;</th>
      <th colspan="5"><%= month %> <%= year %></th>
      <th class='clndr-next'>&gt;</th>
     </tr>
     <tr>
      <% _.each(daysOfTheWeek, function(day) { %>
      <th class="header-day"><%= day %></th>
      <% }); %>
     </tr>
    </thead>
    <tbody>
      <tr class="days"><% _.each(days, function(day, index) { %>
      <td class="<%= day.classes %>" id="<%= day.id %>">
       <span class="day-number">
       <%= day.day %>
       </span>
     </td>
      <% if ((index + 1) % 7 == 0) { 
           %> </tr><tr> <% 
           } %><% }); %>
     </tr>
    </tbody>
   </table>
  </script>
</div>

我正在努力研究如何针对那些第一天和最后几天来应用一些不同的造型。我正在使用moment.js,如果可以使用的话。非常感谢!

2 个答案:

答案 0 :(得分:6)

所以最终我花了一些时间看着使用Underscore和Moment来实现我的目标。下面是我更新的代码,使用Underscore中的条件来使用Moment检查日期,并在必要时向import React, {Component} from 'react'; import { AppRegistry, View, ListView, Text, TextInput, StyleSheet, TouchableOpacity } from 'react-native'; const FILTERS = [ { tag: "clever", active: false }, { tag: "scary", active: false }, { tag: "friendly", active: false }, { tag: "obedient", active: false } ]; const FIELDS = [ { title:"Dog", subtitle: "Bulldog", tags: [ { tag: "clever" }, { tag: "scary" } ] }, { title:"Cat", subtitle:"Persian cat", tags: [ { tag: "friendly" }, { tag: "obedient" } ] }, { title:"Dog", subtitle:"Poodle", tags: [ { tag: "obedient" } ] } ]; class SampleApp extends Component { constructor(props) { super(props); var ds = new ListView.DataSource({ rowHasChanged: (row1, row2) => row1 !== row2, }); var ds2 = new ListView.DataSource({ rowHasChanged: (row1, row2) => row1.active !== row2.active, }); this.state = { dataSource: ds.cloneWithRows(FIELDS), dataSource2: ds2.cloneWithRows(FILTERS), filters: FILTERS, }; } renderFilter(filter) { return ( <TouchableOpacity onPress={this.handleClick.bind(this, filter)}> <Text style={{fontSize: 24, backgroundColor:(filter.active)?'red':'grey', margin:5}}>{filter.tag}</Text> </TouchableOpacity> ); } renderField(field) { return ( <View style={{flexDirection:'column', borderWidth: 3, borderColor: 'yellow'}}> <Text style={{fontSize: 24}}>{field.title}</Text> <Text style={{fontSize: 24}}>{field.subtitle}</Text> {field.tags.map((tagField) => { return ( <View style={{backgroundColor:'blue'}}> <Text style={{fontSize: 24}}>{tagField.tag}</Text> </View> ); })} </View> ); } handleClick(filter) { const newFilters = this.state.filters.map(a => { let copyA = {...a}; if (copyA.tag === filter.tag) { copyA.active = !filter.active; } return copyA; }); this.setState({ dataSource2: this.state.dataSource2.cloneWithRows(newFilters), filters: newFilters }); } setSearchText(event) { let searchText = event.nativeEvent.text; this.setState({searchText}); } render() { return ( <View> <TextInput style={styles.searchBar} value={this.state.searchText} onChange={this.setSearchText.bind(this)} placeholder="Search" /> <ListView style={{flexDirection:'row', flex:1, flexWrap:'wrap'}} horizontal={true} dataSource={this.state.dataSource2} renderRow={this.renderFilter.bind(this)} /> <ListView dataSource={this.state.dataSource} renderRow={this.renderField.bind(this)} /> </View> ); } } const styles = StyleSheet.create({ searchBar: { marginTop: 30, fontSize: 40, height: 50, flex: .1, borderWidth: 3, borderColor: 'red', }, }); AppRegistry.registerComponent('SampleApp', () => SampleApp); 添加一个类。这与我在JSON数组中表示事件的方式相结合:

HTML /下划线

<td>

<强> JSON

<div id="calendar">
  <script type="text/template" id="calendar-template">
    <table class="table">
      <thead>
        <tr>
          <th class='clndr-previous'>&lt;</th>
          <th colspan="5"><%= month %> <%= year %></th>
          <th class='clndr-next'>&gt;</th>
        </tr>
        <tr>
          <% _.each(daysOfTheWeek, function(day) { %>
          <th class="header-day"><%= day %></th>
          <% }); %>
        </tr>
      </thead>
      <tbody>
        <tr class="days">
          <% _.each(days, function(day, index) { %>
            <td class="<%= day.classes %> <% _.each(day.events, function(event) { %><% if( moment(event.start).isSame( day.date ) ){ %>start<% } %><% }); %> <% _.each(day.events, function(event) { %><% if( moment(event.end).isSame( day.date ) ){ %>end<% } %><% }); %>">
              <span class="day-number"><%= day.day %></span>
            </td>
          <% if ((index + 1) % 7 == 0) { %> </tr><tr>  <% } %>
          <% }); %>
         </tr>
       </tbody>
    </table>
  </script>
</div>

答案 1 :(得分:1)

好的,所以我希望你能找到一些有用的东西,因为我花了很长时间才能让它发挥作用。您可能需要为模板等修改一些位,但应该给您一个好主意。请注意<% _.each部分,因为这使得该类在多事件JSON

中起作用

这是我的CLNDR模板代码:

<div id="mini-clndr">
  <script id="mini-clndr-template" type="text/template">
    <div class="controls">
      <div class="clndr-previous-button"><img src="/assets/local/img/calendar-left-arrow.png"></div>
      <div class="month">
        <%= month %>
          <%= year %>
      </div>
      <div class="clndr-next-button"><img src="/assets/local/img/calendar-right-arrow.png"></div>
    </div>

    <div class="days-container">
      <div class="days">
        <div class="headers">
          <% _.each(daysOfTheWeek, function(day) { %>
            <div class="day-header">
              <%= day %>
            </div>
            <% }); %>
        </div>
        <% _.each(days, function(day) {
                    var classes = '';
                    if( day.events.length ){
                        for( var i = 0; i < day.events.length; i++ ){
                            classes += ' ' + day.events[i].class;
                        }
                    }
                %>
          <div class="<%= day.classes %><%= classes %>" id="<%= day.id %>">
            <%= day.day %>
          </div>
          <% }); %>
      </div>
      <div class="events">
        <div class="headers">
          <div class="x-button">x</div>
          <div class="event-header">EVENTS</div>
        </div>
        <div class="events-list">
          <% _.each(eventsThisMonth, function(event) { %>
            <div class="event">
              <a target="blank" href="<%= event.url %>">
                <%= moment(event.date).format('MMMM Do') %>:
                  <%= event.title %>
              </a>
            </div>
            <% }); %>
        </div>
      </div>
    </div>
  </script>
</div>

这是我的CLNDR.js代码:

  var clndr = {};

  $(function() {

    var currentMonth = moment().format('YYYY-MM');
    var nextMonth = moment().add(1, 'month').format('YYYY-MM');

    var events = [
      // Multiday Event Code
      {
        start: '2016-05-17',
        end: '2016-05-19',
        title: 'Monday to Friday Event',
        class: 'long-event'
      },
    ];

    $('#mini-clndr').clndr({
      template: $('#mini-clndr-template').html(),
      weekOffset: 1,
      events: events,
      multiDayEvents: {
        endDate: 'end',
        singleDay: 'date',
        startDate: 'start'
      },
      clickEvents: {
        click: function(target) {
          if (target.events.length) {
            var daysContainer = $('#mini-clndr').find('.days-container');
            daysContainer.toggleClass('show-events', true);
            $('#mini-clndr').find('.x-button').click(function() {
              daysContainer.toggleClass('show-events', false);
            });
          }
        }
      },
      adjacentDaysChangeMonth: true,
      forceSixRows: false,
      showAdjacentMonths: false,
    });
  });

然后是我的CSS代码:

  .long-event {
    background: orange;
  }

  :not(.long-event) + .long-event, .long-event:first-child {
    background: orange;
    border-radius: 50% 0 0 50%;
  }

  .last {
    border-radius: 0 50% 50% 0;
  }

然后最后,一些jQuery使这些类工作。您还需要在日历上的每个日期添加.date课程:

$('.long-event + .date:not(.long-event)').prev().addClass('last');

虽然这个jsFiddle没有使用CLNDR.js,但你可以看到造型工作:)

https://jsfiddle.net/andyjh07/ke0euh5m/