Skip to content
This repository has been archived by the owner on Jun 19, 2018. It is now read-only.

Commit

Permalink
fix(dayView): have day view start and end respect minutes
Browse files Browse the repository at this point in the history
BREAKING CHANGE:
The `day-view-start` and `day-view-end` now respect the minutes values. This means the `day-view-start` value must now be the end of the hour instead of the beginning of the next hour

Before:
```
day-view-end="22:00"
```

After:
```
day-view-end="22:59"
```

Closes #344
  • Loading branch information
Matt Lewis committed Jul 25, 2016
1 parent 88721a4 commit 80bdc39
Show file tree
Hide file tree
Showing 16 changed files with 153 additions and 205 deletions.
30 changes: 15 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ https://mattlewis92.github.io/angular-bootstrap-calendar/
This plugin is an AngularJS port of the original jQuery bootstrap calendar that can be found here:
http://bootstrap-calendar.azurewebsites.net/

The layout and functionality is intended to be exactly the same, but without the overhead of including jQuery just for a calendar.
The layout and functionality is intended to be exactly the same, but without the overhead of including jQuery just for a calendar.

All credits for the UI/UX and the less files of the calendar go to the original author.

Expand Down Expand Up @@ -141,27 +141,27 @@ $scope.events = [

This variable will be assigned to the calendar title. If you want to change the formatting you can use the `calendarConfig` or just override the appropriate method in the `calendarTitle` factory.

### on-event-click
### on-event-click

This expression is called when an event is clicked on the calendar. `calendarEvent` can be used in the expression and contains the calendar event that was clicked on.

### on-event-times-changed

This expression is called when an event is dragged and dropped or resized into a different date / time on the calendar. The available values that are passed to the expression are: `calendarEvent`, `calendarNewEventStart`, `calendarNewEventEnd` and `calendarDraggedFromDate` (month view only). The directive won't change the event object and leaves that up to you to implement. Please note drag and drop is only available by including the [interact.js](http://interactjs.io/) library.

### edit-event-html
### edit-event-html

If provided this piece of html will be displayed next to an event on the year and month view and will fire the function passed to edit-event-click.

### delete-event-html
### delete-event-html

If provided this piece of html will be displayed next to an event on the year and month view and will fire the function passed to delete-event-click.

### on-edit-event-click
### on-edit-event-click

This expression is called when an event edit link is clicked on the calendar. `calendarEvent` can be used in the expression and contains the calendar event that was clicked on.

### on-delete-event-click
### on-delete-event-click

This expression is called when an event delete link is clicked on the calendar. `calendarEvent` can be used in the expression and contains the calendar event that was clicked on.

Expand All @@ -183,7 +183,7 @@ An interpolated string in the form of hh:mm to start the day view at, e.g. setti

### day-view-end

An interpolated string in the form of hh:mm to end the day view at, e.g. setting it to 22:00 will end the day view at 10pm. Any minutes must be divisible by the `day-view-split` value.
An interpolated string in the form of hh:mm to end the day view at, e.g. setting it to 22:59 will end the day view at 11pm.

### day-view-split

Expand All @@ -195,7 +195,7 @@ The number of pixels to "snap" event drag and resizes to. Default: 30

### on-view-change-click

An optional expression that is evaluated when the view is changed by clicking on a date. Return false from the expression function to disable the view change. `calendarDate` can be used in the expression and contains the date that was selected. `calendarNextView` is the view that the calendar will be changed to.
An optional expression that is evaluated when the view is changed by clicking on a date. Return false from the expression function to disable the view change. `calendarDate` can be used in the expression and contains the date that was selected. `calendarNextView` is the view that the calendar will be changed to.

### cell-modifier

Expand Down Expand Up @@ -247,7 +247,7 @@ angular.module('myModule')

## Custom directive templates

All calendar template urls can be changed using the `calendarConfig` as illustrated above.
All calendar template urls can be changed using the `calendarConfig` as illustrated above.

Please note that even patch releases may change templates which could break your app, so if using a custom template it is recommended that you pin the version of this module and review all changes when updating the version.

Expand Down Expand Up @@ -288,13 +288,13 @@ You can either use angular's date filter or moment.js to format dates. The defau
```javascript
angular.module('myModule')
.config(function(calendarConfig) {

calendarConfig.dateFormatter = 'moment'; // use moment to format dates

});
```
```

Then you just need to include the appropriate locale files for your app.
Then you just need to include the appropriate locale files for your app.

If you want to dynamically change the locale for angular and not include all of the available angular locale files [try this library](https://github.com/lgalfaso/angular-dynamic-locale).

Expand All @@ -318,10 +318,10 @@ For a full list of all available formats and their defaults see [calendarConfig.
* Install local dev dependencies: `npm install` while current directory is this repo

### Development server
Run `npm start` to start a development server on port 8000 with auto reload + run tests.
Run `npm start` to start a development server on port 8000 with auto reload + run tests.

### Testing
Run `npm test` to run tests once or `npm run test:watch` to continually run tests (this is automatic when you run `npm start`).
Run `npm test` to run tests once or `npm run test:watch` to continually run tests (this is automatic when you run `npm start`).

### Build
Run `npm run build` to build the project files in the dist folder
Expand Down
2 changes: 1 addition & 1 deletion docs/examples/day-view-start-end/markup.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@
view="vm.calendarView"
view-date="vm.viewDate"
day-view-start="09:00"
day-view-end="17:00">
day-view-end="17:59">
</mwl-calendar>
</div>
2 changes: 1 addition & 1 deletion docs/examples/kitchen-sink/markup.html
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ <h2 class="text-center">{{ vm.calendarTitle }}</h2>
on-delete-event-click="vm.eventDeleted(calendarEvent)"
cell-is-open="vm.isCellOpen"
day-view-start="06:00"
day-view-end="22:00"
day-view-end="22:59"
day-view-split="30"
cell-modifier="vm.modifyCell(calendarCell)">
</mwl-calendar>
Expand Down
11 changes: 3 additions & 8 deletions src/directives/mwlCalendarDay.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,16 @@ angular
vm.dayViewSplit
);

var events = calendarHelper.getDayView(
var view = calendarHelper.getDayView(
vm.events,
vm.viewDate,
vm.dayViewStart,
vm.dayViewEnd,
vm.dayViewSplit
);

vm.allDayEvents = events.filter(function(event) {
return event.allDay;
});

vm.nonAllDayEvents = events.filter(function(event) {
return !event.allDay;
});
vm.allDayEvents = view.allDayEvents;
vm.nonAllDayEvents = view.events;

}

Expand Down
44 changes: 17 additions & 27 deletions src/directives/mwlCalendarHourList.js
Original file line number Diff line number Diff line change
@@ -1,41 +1,31 @@
'use strict';

var angular = require('angular');
var calendarUtils = require('calendar-utils');

angular
.module('mwl.calendar')
.controller('MwlCalendarHourListCtrl', function($scope, $attrs, moment, calendarConfig, calendarHelper) {
.controller('MwlCalendarHourListCtrl', function($scope, $attrs, moment, calendarHelper) {
var vm = this;
var dayViewStart, dayViewEnd;

function updateDays() {
dayViewStart = moment(vm.dayViewStart || '00:00', 'HH:mm');
dayViewEnd = moment(vm.dayViewEnd || '23:00', 'HH:mm');
vm.dayViewSplit = parseInt(vm.dayViewSplit);
vm.hours = [];
var dayCounter = moment(vm.viewDate)
.clone();

if ($attrs.dayWidth) {
dayCounter = dayCounter.startOf('week');
}
vm.dayViewSplit = parseInt(vm.dayViewSplit);
var dayStart = (vm.dayViewStart || '00:00').split(':');
var dayEnd = (vm.dayViewEnd || '23:59').split(':');
vm.hourGrid = calendarUtils.getDayViewHourGrid({
viewDate: $attrs.dayWidth ? moment(vm.viewDate).startOf('week').toDate() : moment(vm.viewDate).toDate(),
hourSegments: 60 / vm.dayViewSplit,
dayStart: {
hour: dayStart[0],
minute: dayStart[1]
},
dayEnd: {
hour: dayEnd[0],
minute: dayEnd[1]
}
});

dayCounter
.hours(dayViewStart.hours())
.minutes(dayViewStart.minutes())
.seconds(dayViewStart.seconds());

for (var i = 0; i <= dayViewEnd.diff(dayViewStart, 'hours'); i++) {
vm.hours.push({
label: calendarHelper.formatDate(dayCounter, calendarConfig.dateFormats.hour),
date: dayCounter.clone()
});
dayCounter.add(1, 'hour');
}
vm.hourChunks = [];
for (var j = 0; j < (60 / vm.dayViewSplit); j++) {
vm.hourChunks.push(j);
}
}

var originalLocale = moment.locale();
Expand Down
111 changes: 39 additions & 72 deletions src/services/calendarHelper.js
Original file line number Diff line number Diff line change
Expand Up @@ -229,81 +229,46 @@ angular

function getDayView(events, viewDate, dayViewStart, dayViewEnd, dayViewSplit) {

var dayStartHour = moment(dayViewStart || '00:00', 'HH:mm').hours();
var dayEndHour = moment(dayViewEnd || '23:00', 'HH:mm').hours();
var hourHeight = (60 / dayViewSplit) * 30;
var calendarStart = moment(viewDate).startOf('day').add(dayStartHour, 'hours');
var calendarEnd = moment(viewDate).startOf('day').add(dayEndHour + 1, 'hours');
var calendarHeight = (dayEndHour - dayStartHour + 1) * hourHeight;
var hourHeightMultiplier = hourHeight / 60;
var buckets = [];
var eventsInPeriod = filterEventsInPeriod(
events,
moment(viewDate).startOf('day').toDate(),
moment(viewDate).endOf('day').toDate()
);

return eventsInPeriod.map(function(event) {
if (moment(event.startsAt).isBefore(calendarStart)) {
event.top = 0;
} else {
event.top = (moment(event.startsAt).startOf('minute').diff(calendarStart.startOf('minute'), 'minutes') * hourHeightMultiplier) - 2;
}

if (moment(event.endsAt || event.startsAt).isAfter(calendarEnd)) {
event.height = calendarHeight - event.top;
} else {
var diffStart = event.startsAt;
if (moment(event.startsAt).isBefore(calendarStart)) {
diffStart = calendarStart.toDate();
}
if (!event.endsAt) {
event.height = 30;
} else {
event.height = moment(event.endsAt).diff(moment(diffStart), 'minutes') * hourHeightMultiplier;
}
}

if (event.top - event.height > calendarHeight) {
event.height = 0;
}

event.left = 0;

return event;
}).filter(function(event) {
return event.height > 0;
}).map(function(event) {

var cannotFitInABucket = true;
buckets.forEach(function(bucket, bucketIndex) {
var canFitInThisBucket = true;
var dayStart = (dayViewStart || '00:00').split(':');
var dayEnd = (dayViewEnd || '23:59').split(':');

bucket.filter(function(bucketItem) {
return !bucketItem.allDay;
}).forEach(function(bucketItem) {
if (eventIsInPeriod(event, bucketItem.startsAt, bucketItem.endsAt || bucketItem.startsAt) ||
eventIsInPeriod(bucketItem, event.startsAt, event.endsAt || event.startsAt)) {
canFitInThisBucket = false;
}
});
var allDayEvents = events.filter(function(event) {
return event.allDay;
});

if (canFitInThisBucket && cannotFitInABucket) {
cannotFitInABucket = false;
event.left = bucketIndex * 150;
buckets[bucketIndex].push(event);
}
var nonAllDayEvents = events.filter(function(event) {
return !event.allDay;
});

});
var view = calendarUtils.getDayView({
events: nonAllDayEvents.map(function(event) { // hack required to work with event API
event.start = event.startsAt;
event.end = event.endsAt;
return event;
}),
viewDate: viewDate,
hourSegments: 60 / dayViewSplit,
dayStart: {
hour: dayStart[0],
minute: dayStart[1]
},
dayEnd: {
hour: dayEnd[0],
minute: dayEnd[1]
},
eventWidth: 150,
segmentHeight: 30
});

if (cannotFitInABucket) {
event.left = buckets.length * 150;
buckets.push([event]);
}
// remove hack to work with new event API
nonAllDayEvents.forEach(function(event) {
delete event.start;
delete event.end;
});

return event;
view.allDayEvents = allDayEvents;

});
return view;

}

Expand All @@ -326,13 +291,15 @@ angular
dayViewStart,
dayViewEnd,
dayViewSplit
);
).events;
newEvents = newEvents.concat(newDayEvents);
});
weekView.eventRows = [{
row: newEvents.map(function(event) {
row: newEvents.map(function(dayEvent) {
var event = dayEvent.event;
return {
event: event,
top: dayEvent.top,
offset: calendarUtils.getDayOffset(
{start: event.startsAt, end: event.endsAt},
moment(viewDate).startOf('week')
Expand All @@ -345,7 +312,7 @@ angular

function getDayViewHeight(dayViewStart, dayViewEnd, dayViewSplit) {
var dayViewStartM = moment(dayViewStart || '00:00', 'HH:mm');
var dayViewEndM = moment(dayViewEnd || '23:00', 'HH:mm');
var dayViewEndM = moment(dayViewEnd || '23:59', 'HH:mm');
var hourHeight = (60 / dayViewSplit) * 30;
return ((dayViewEndM.diff(dayViewStartM, 'hours') + 1) * hourHeight) + 2;
}
Expand Down
Loading

0 comments on commit 80bdc39

Please sign in to comment.