diff --git a/JavaScript/horizontal_timeline.2.0.js b/JavaScript/horizontal_timeline.2.0.js
index 707e49d..fe2829d 100644
--- a/JavaScript/horizontal_timeline.2.0.js
+++ b/JavaScript/horizontal_timeline.2.0.js
@@ -1,7 +1,7 @@
/* --------------------------------
Horizontal Timeline 2.0
- by Studocwho @ yCodeTech
+by Studocwho @ yCodeTech
Original Horizontal Timeline by CodyHouse
@@ -38,6 +38,7 @@ Docs at http://horizontal-timeline.ycodetech.co.uk
minimalFirstDateInterval: true,
dateDisplay: "dateTime", // dateTime, date, time, dayMonth, monthYear, year
+ dateOrder: "normal", // normal, reverse
autoplay: false,
autoplaySpeed: 8, // Sec
@@ -50,12 +51,12 @@ Docs at http://horizontal-timeline.ycodetech.co.uk
useFontAwesomeIcons: true,
useNavBtns: true,
useScrollBtns: true,
-
- iconBaseClass: "fas fa-3x",
+
+ iconBaseClass: "fas fa-3x",
scrollLeft_iconClass: "fa-chevron-circle-left",
- scrollRight_iconClass: "fa-chevron-circle-right",
- prev_iconClass: "fa-arrow-circle-left",
- next_iconClass: "fa-arrow-circle-right",
+ scrollRight_iconClass: "fa-chevron-circle-right",
+ prev_iconClass: "fa-arrow-circle-left",
+ next_iconClass: "fa-arrow-circle-right",
pause_iconClass: "fa-pause-circle",
play_iconClass: "fa-play-circle"
};
@@ -73,9 +74,8 @@ Docs at http://horizontal-timeline.ycodetech.co.uk
this._defaults = defaults;
this._name = pluginName;
+ this.$element = $(element);
- this.$element = $(element),
-
this.init();
}
Timeline.prototype.init = function () {
@@ -85,73 +85,101 @@ Docs at http://horizontal-timeline.ycodetech.co.uk
var self = this,
contentList = this.$element.find('li');
if(contentList.length == 0) this.$element.css('opacity', 1).html('
There are no events at this point in time.
Please add some content.
');
-
- var url = "https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.8.2/css/all.min.css";
-
- // Function to load the file
- // (url, type)
- this._addFile(url, 'css');
-
+ if (this.settings.useFontAwesomeIcons == true) {
+ var url = "https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.8.2/css/all.min.css";
+
+ // Function to load the file
+ // (url, type)
+ this._addFile(url, 'css');
+ }
this._create();
- timelineComponents = {};
- this._timelineComponents(timelineComponents);
-
- this.init.addIdsAndClasses = addIdsAndClasses;
- this.init.addIdsAndClasses();
-
- function addIdsAndClasses() {
- //** Adding IDs and Classes **//
- if (timelineComponents['eventsContentList'].length == 1) {
- timelineComponents['eventsContentList'].first().attr('id', 'first');
- timelineComponents['timelineEvents'].first().addClass("first");
+ // Wait about 300s to make sure the all elements are created properly.
+ // Otherwise the width of the timeline would report as bigger than it actually is.
+ window.setTimeout($.proxy(function(){
+ timelineComponents = {};
+ this._timelineComponents(timelineComponents);
+
+ this.init.addIdsAndClasses = addIdsAndClasses;
+ this.init.addIdsAndClasses(this);
+
+ function addIdsAndClasses(self) {
+ //** Adding IDs and Classes **//
+ if (timelineComponents['eventsContentList'].length == 1) {
+ timelineComponents['eventsContentList'].first().attr('id', 'first');
+ timelineComponents['timelineEvents'].first().addClass("first");
+ }
+ else {
+ // Adds id to the first and last li of the event-content list respectively.
+ timelineComponents['eventsContentList']
+ .first().attr('id', 'first').end()
+ .last().attr('id', 'last');
+
+ // Adds class to the first and last timeline event dates respectively.
+ timelineComponents['timelineEvents']
+ .first().addClass("first").end()
+ .last().addClass("last");
+ }
}
- else {
- // Adds id to the first and last li of the event-content list respectively.
- timelineComponents['eventsContentList']
- .first().attr('id', 'first').end()
- .last().attr('id', 'last');
-
- // Adds class to the first and last timeline event dates respectively.
- timelineComponents['timelineEvents']
- .first().addClass("first").end()
- .last().addClass("last");
+ //** Select the correct event **//
+
+ // If any events-content has .selected class...
+ if (timelineComponents['eventsContentList'].hasClass('selected')) {
+ // Get date from data-date attribute
+ var date = timelineComponents['eventsContentSelected'].data('date'),
+ // Find the event date matching the data-date
+ selectedDate = timelineComponents['eventsWrapper'].find('a[data-date="'+date+'"]');
+
+ // Add .selected class to the matched element
+ selectedDate.addClass('selected');
+ // Update all previous dates for styling.
+ this._updateOlderEvents(selectedDate);
+ }
+ // If no class found at all...
+ else {
+ // If dateOrder is normal (Ascending)... start from the left.
+ if (this.settings.dateOrder == "normal") {
+ // Add .selected class to the first event.
+ timelineComponents['eventsWrapper'].find('a.first').addClass('selected');
+
+ // Find the selected event
+ var selectedEvent = timelineComponents['eventsWrapper'].find('a.selected'),
+ // Get the selected event's date.
+ selectedDate = selectedEvent.data('date');
+
+ // Find the selected event's content using the date and add selected class to the content.
+ timelineComponents['eventsContent'].find('li[data-date="'+selectedDate+'"]').addClass('selected');
+ }
+ // Else dateOrder is reverse (Descending)... start from the right.
+ else if (this.settings.dateOrder == "reverse") {
+ // Add .selected class to the last event.
+ timelineComponents['eventsWrapper'].find('a.last').addClass('selected');
+
+ // Find the selected event
+ var selectedEvent = timelineComponents['eventsWrapper'].find('a.selected'),
+ // Get the selected event's date.
+ selectedDate = selectedEvent.data('date');
+
+ // Find the selected event's content using the date and add selected class to the content.
+ timelineComponents['eventsContent'].find('li[data-date="'+selectedDate+'"]').addClass('selected');
+
+ this._updateOlderEvents(selectedEvent);
+ }
}
- }
- //** Select the correct event **//
- // If any events-content has .selected class...
- if (timelineComponents['eventsContentList'].hasClass('selected')) {
- // Get date from data-date attribute
- var date = timelineComponents['eventsContentSelected'].data('date'),
- // Find the event date matching the data-date
- selectedDate = timelineComponents['eventsWrapper'].find('a[data-date="'+date+'"]');
-
- // Add .selected class to the matched element
- selectedDate.addClass('selected');
- // Update all previous dates for styling.
- this._updateOlderEvents(selectedDate);
- }
- // If no class found at all...
- else {
- // Add .selected class to the first events-content and first event date respectively.
- timelineComponents['eventsContent']
- .find('li#first').addClass('selected').end()
- .siblings('.timeline').find('.events').find('a.first').addClass('selected');
- }
-
-
- // Assign a left postion to the single events along the timeline
- this._setDatePosition(timelineComponents);
- // Assign a width to the timeline
- var timelineTotalWidth = this._setTimelineWidth(timelineComponents);
- // Set the filling line to the selected event
- this._updateFilling(timelineComponents['eventsWrapper']
- .find('a.selected'), timelineComponents['fillingLine'], timelineTotalWidth);
- // The timeline has been initialised - show it
- this.$element.addClass('loaded');
-
- this._setup(self, timelineComponents, timelineTotalWidth);
+
+ // Assign a left postion to the single events along the timeline
+ this._setDatePosition(timelineComponents);
+ // Assign a width to the timeline
+ var timelineTotalWidth = this._setTimelineWidth(timelineComponents);
+ // Set the filling line to the selected event
+ this._updateFilling(timelineComponents['eventsWrapper']
+ .find('a.selected'), timelineComponents['fillingLine'], timelineTotalWidth);
+ // The timeline has been initialised - show it
+ this.$element.addClass('loaded');
+
+ this._setup(self, timelineComponents, timelineTotalWidth);
+ }, this), 300);
};
/* Dynamically creates the timeline according to the amount of events. */
Timeline.prototype._create = function () {
@@ -180,7 +208,7 @@ Docs at http://horizontal-timeline.ycodetech.co.uk
//** Create the timeline HTML **//
// Create the timeline element.
- this.$element.prepend($timelineWrapper)
+ this.$element.prepend($timelineWrapper);
// Find the timeline element that was just created
var $timeline = this.$element.find('.timeline');
@@ -213,7 +241,12 @@ Docs at http://horizontal-timeline.ycodetech.co.uk
.find("#rightNav").append($nextButton).append($scrollRightButton);
}
// Otherwise, both button sets are disabled and we just need to add the timelineEventsWrapper.
- else $timeline.append($timelineEventsWrapper);
+ else {
+ $timeline.append($timelineEventsWrapper);
+ // Add a 100% min-width to the events-wrapper if the buttons are disabled.
+ // Stops the timeline from disappearing due to apparent no width.
+ $timeline.find('.events-wrapper').css("min-width", "100%");
+ }
// Autoplay buttons
// If autoplay is true, create the pause button
@@ -227,39 +260,50 @@ Docs at http://horizontal-timeline.ycodetech.co.uk
this._create.date(this, 'append');
// (instance, insertMethod (append, before, after [last 2 for addEvent method]), date to insert before/after [from addEvent method])
function createDate(self, insertMethod, arrangementDate) {
+
+ // If dateOrder is normal (starting from the left).
+ if (self.settings.dateOrder == "normal") {
+ // Find the event content.
+ var $element = self.$element.children('.events-content').find('li');
+ }
+ // Else if dateOrder is reverse (starting from the right).
+ else if (self.settings.dateOrder == "reverse") {
+ var $element = $(self.$element.children('.events-content').find('li').get().reverse());
+ }
+
/* dateTime = the date and time */
if(self.settings.dateDisplay == "dateTime") {
- self.$element.children('.events-content').find('li').each(function() {
+ $element.each(function() {
self._create.eventDateDisplay(self, $(this), "dateTime", insertMethod, arrangementDate);
});
}
/* date = the date only */
else if (self.settings.dateDisplay == "date") {
- self.$element.children('.events-content').find('li').each(function() {
+ $element.each(function() {
self._create.eventDateDisplay(self, $(this), "date", insertMethod, arrangementDate);
});
}
/* time = the time only */
else if (self.settings.dateDisplay == "time") {
- self.$element.children('.events-content').find('li').each(function() {
+ $element.each(function() {
self._create.eventDateDisplay(self, $(this), "time", insertMethod, arrangementDate);
});
}
/* dayMonth = the day and monthName only */
else if (self.settings.dateDisplay == "dayMonth") {
- self.$element.children('.events-content').find('li').each(function() {
+ $element.each(function() {
self._create.eventDateDisplay(self, $(this), "dayMonth", insertMethod, arrangementDate);
});
}
/* monthYear = the monthName and year only */
else if (self.settings.dateDisplay == "monthYear") {
- self.$element.children('.events-content').find('li').each(function() {
+ $element.each(function() {
self._create.eventDateDisplay(self, $(this), "monthYear", insertMethod, arrangementDate);
});
}
/* year = the year only */
else if (self.settings.dateDisplay == "year") {
- self.$element.children('.events-content').find('li').each(function() {
+ $element.each(function() {
self._create.eventDateDisplay(self, $(this), "year", insertMethod, arrangementDate);
});
}
@@ -282,16 +326,13 @@ Docs at http://horizontal-timeline.ycodetech.co.uk
yearDisplay = display == "year",
// Find .events for the date display
$eventDateDisplay = self.$element.find('.events'),
- // Create an array of the months, with the index 0 = null,
- // so that we can get the month by its corresponding index number.
- months = [null, 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
- monthName = months,
dateLink = '',
// For use with the addEvent plublic method
// Finds the event with the specific date.
$arrangementEvent = $eventDateDisplay.find('a[data-date="'+ arrangementDate +'"]');
// Function to add the number suffix st, nd, rd, th (eg: 1st, 2nd, 3rd, 4th)
+ // Part of answer on StackOverflow: https://stackoverflow.com/a/15397495/2358222
function numSuffix(num) {
if (num > 3 && num < 21) return 'th';
switch (num % 10) {
@@ -301,6 +342,16 @@ Docs at http://horizontal-timeline.ycodetech.co.uk
default: return "th";
}
}
+ // Function to get the month name according to a number supplied.
+ // Answer on StackOverflow: https://stackoverflow.com/a/10996297/2358222
+ function getMonthName(num) {
+ // Create an array of the months, with the index 0 = null,
+ // so that we can get the month by its corresponding index number.
+ var monthNames = [null, "January", "February", "March", "April", "May", "June",
+ "July", "August", "September", "October", "November", "December" ];
+ return monthNames[num];
+ }
+
var dateExists = $eventDateDisplay.children('a').map(function() {
return $(this).data('date');
}).get();
@@ -356,16 +407,16 @@ Docs at http://horizontal-timeline.ycodetech.co.uk
else $arrangementEvent.before(dateLink + time +'');
}
else if(dayMonthDisplay) {
- if (insertMethod == 'append') $eventDateDisplay.append(dateLink + dayPart + numSuffix(dayPart) + '
' + monthName[monthPart]+'');
+ if (insertMethod == 'append') $eventDateDisplay.append(dateLink + dayPart + numSuffix(dayPart) + '
' + getMonthName(monthPart) +'');
// For use with the addEvent method... creates new timeline events and places them where specified.
- else if (insertMethod == 'after') $arrangementEvent.after(dateLink + dayPart + numSuffix(dayPart) + '
' + monthName[monthPart]+'');
- else $arrangementEvent.before(dateLink + dayPart + numSuffix(dayPart) + '
' + monthName[monthPart]+'');
+ else if (insertMethod == 'after') $arrangementEvent.after(dateLink + dayPart + numSuffix(dayPart) + '
' + getMonthName(monthPart) +'');
+ else $arrangementEvent.before(dateLink + dayPart + numSuffix(dayPart) + '
' + getMonthName(monthPart) +'');
}
else if(monthYearDisplay) {
- if (insertMethod == 'append') $eventDateDisplay.append(dateLink + monthName[monthPart] + '
' + yearPart +'');
+ if (insertMethod == 'append') $eventDateDisplay.append(dateLink + getMonthName(monthPart) + '
' + yearPart +'');
// For use with the addEvent method... creates new timeline events and places them where specified.
- else if (insertMethod == 'after') $arrangementEvent.after(dateLink + monthName[monthPart] + '
' + yearPart +'');
- else $arrangementEvent.before(dateLink + monthName[monthPart] + '
' + yearPart +'');
+ else if (insertMethod == 'after') $arrangementEvent.after(dateLink + getMonthName(monthPart) + '
' + yearPart +'');
+ else $arrangementEvent.before(dateLink + getMonthName(monthPart) + '
' + yearPart +'');
}
else if(yearDisplay) {
if (insertMethod == 'append') $eventDateDisplay.append(dateLink + yearPart +'');
@@ -432,16 +483,16 @@ Docs at http://horizontal-timeline.ycodetech.co.uk
else $arrangementEvent.before(dateLink + date +'');
}
else if(dayMonthDisplay) {
- if (insertMethod == 'append') $eventDateDisplay.append(dateLink + dayPart + numSuffix(dayPart) + '
' + monthName[monthPart]+'');
+ if (insertMethod == 'append') $eventDateDisplay.append(dateLink + dayPart + numSuffix(dayPart) + '
' + getMonthName(monthPart) +'');
// For use with the addEvent method... creates new timeline events and places them where specified.
- else if (insertMethod == 'after') $arrangementEvent.after(dateLink + dayPart + numSuffix(dayPart) + '
' + monthName[monthPart]+'');
- else $arrangementEvent.before(dateLink + dayPart + numSuffix(dayPart) + '
' + monthName[monthPart]+'');
+ else if (insertMethod == 'after') $arrangementEvent.after(dateLink + dayPart + numSuffix(dayPart) + '
' + getMonthName(monthPart) +'');
+ else $arrangementEvent.before(dateLink + dayPart + numSuffix(dayPart) + '
' + getMonthName(monthPart) +'');
}
else if(monthYearDisplay) {
- if (insertMethod == 'append') $eventDateDisplay.append(dateLink + monthName[monthPart] + '
' + yearPart +'');
+ if (insertMethod == 'append') $eventDateDisplay.append(dateLink + getMonthName(monthPart) + '
' + yearPart +'');
// For use with the addEvent method... creates new timeline events and places them where specified.
- else if (insertMethod == 'after') $arrangementEvent.after(dateLink + monthName[monthPart] + '
' + yearPart +'');
- else $arrangementEvent.before(dateLink + monthName[monthPart] + '
' + yearPart +'');
+ else if (insertMethod == 'after') $arrangementEvent.after(dateLink + getMonthName(monthPart) + '
' + yearPart +'');
+ else $arrangementEvent.before(dateLink + getMonthName(monthPart) + '
' + yearPart +'');
}
else if(yearDisplay) {
if (insertMethod == 'append') $eventDateDisplay.append(dateLink + yearPart +'');
@@ -520,6 +571,7 @@ Docs at http://horizontal-timeline.ycodetech.co.uk
event.preventDefault();
var $this = $(event.target);
+ this._timelineComponents(timelineComponents);
timelineTotalWidth = this._setTimelineWidth(timelineComponents);
// If next button clicked, shows next content
if($this.is('.next')) this._showNewContent(timelineComponents, timelineTotalWidth, 'next');
@@ -536,6 +588,7 @@ Docs at http://horizontal-timeline.ycodetech.co.uk
event.preventDefault();
var $this = $(event.target);
+ this._timelineComponents(timelineComponents);
// Remove selected class from all dates.
this.$element.find('.events').find('a').removeClass('selected');
// Add class to the event date clicked.
@@ -549,7 +602,7 @@ Docs at http://horizontal-timeline.ycodetech.co.uk
// Change the event content to match the selected event.
this._updateVisibleContent($this, timelineComponents['eventsContent']);
// Translate (scroll) the timeline left or right according to the position of the targeted event date
- this._updateTimelinePosition($this, timelineComponents);
+ this._updateTimelinePosition($this, timelineComponents, timelineTotalWidth);
}, this));
//** Autoplay **//
@@ -651,19 +704,26 @@ Docs at http://horizontal-timeline.ycodetech.co.uk
//if percentTime is equal or greater than 100
if(percentTime >= 100){
- // If the current index is equal to the total number of events
- if(current == this._setup.autoplay.countEvents()) {
+ // If dateOrder is normal AND the current index is equal to the total number of events
+ // OR dateOrder is reverse AND current index is equal to 1 ...
+ if((this.settings.dateOrder == "normal" && current == this._setup.autoplay.countEvents()) || (this.settings.dateOrder == "reverse" && current == 1)) {
// Go back to the start of the cycle.
this._showNewContent(timelineComponents, autoplayTimelineTotalWidth, 'start');
// Recalculate the current index to make sure it's reset back to 1 (the start).
- current = timelineComponents['eventsWrapper'].find('.selected').index();
+ current = timelineComponents['eventsWrapper'].find('.selected').index();
}
else {
- // Go to next event content.
- this._showNewContent(timelineComponents, autoplayTimelineTotalWidth, 'next');
+ // If dateOrder is normal.
+ if (this.settings.dateOrder == "normal") {
+ // Go to next event content.
+ this._showNewContent(timelineComponents, autoplayTimelineTotalWidth, 'next');
+ }
+ // Else if dateOrder is reverse.
+ else if (this.settings.dateOrder == "reverse") {
+ // Go to next event content.
+ this._showNewContent(timelineComponents, autoplayTimelineTotalWidth, 'prev');
+ }
}
- // Add 1 to the current index
- current++;
}
} // End isPaused if statement
} // End Interval function
@@ -878,7 +938,7 @@ Docs at http://horizontal-timeline.ycodetech.co.uk
// Find the targeted event date using the date
selectedDate = timelineComponents['eventsWrapper'].find(eventDate),
// Get the width value of the events (previously set)
- timelineTotalWidth = timelineComponents['eventsWrapper'].width();
+ timelineTotalWidth = this._setTimelineWidth(timelineComponents);
// If a link is targetting the timeline it sits in (itself), then execute the function to translate the timeline
if(targetSelf) translate_gotoTimeline(this);
// If not, then use a smooth scroll and then execute the function afterwards.
@@ -914,7 +974,7 @@ Docs at http://horizontal-timeline.ycodetech.co.uk
pluginRef._updateVisibleContent(selectedDate, timelineComponents['eventsContent']);
}
// Translate (scroll) the timeline left or right according to the position of the targeted event date
- pluginRef._updateTimelinePosition(selectedDate, timelineComponents);
+ pluginRef._updateTimelinePosition(selectedDate, timelineComponents, timelineTotalWidth);
} // End translate_gotoTimeline() translate function
} // End gotoTimeline function
} // End if goToTimelineLink exists
@@ -972,15 +1032,12 @@ Docs at http://horizontal-timeline.ycodetech.co.uk
// Swipe right to go left (previous)
swipeRight:$.proxy(function(event, direction, distance, duration, fingerCount) {
// Show previous content on swipeRight
-
- this._setup.swipe(this, 'prev');
- //this._showNewContent(timelineComponents, this._setTimelineWidth(timelineComponents), 'prev');
+ this._setup.swipe(this, 'prev');
}, this),
// Swipe left to go right (next)
swipeLeft:$.proxy(function(event, direction, distance, duration, fingerCount) {
// Show next content on swipeLeft
- this._setup.swipe(this, 'next');
-
+ this._setup.swipe(this, 'next');
}, this),
// Swipe distance... 0 = any distance in px
threshold:75,
@@ -1066,26 +1123,18 @@ Docs at http://horizontal-timeline.ycodetech.co.uk
Timeline.prototype.refresh = function () {
this._timelineComponents(timelineComponents);
+ // Removes first and last id attributes of the event-content list.
timelineComponents['eventsContent']
- // Removes first and last id attributes of the event-content list.
.find('#first').removeAttr('id').end()
.find('#last').removeAttr('id').end();
- // Adds id to the first li of the event-content list.
- //.find('li').first().attr('id', 'first').end()
- // Adds id to the last li of the event-content list.
- //.last().attr('id', 'last');
-
+
+ // Removes first and last classes from the timeline event date
timelineComponents['eventsWrapper']
- // Removes first and last classes from the timeline event date
.find('.first').removeClass('first').end()
- .find('.last').removeClass('last').end();
- // Adds class to the first timeline event date.
- //.find('a').first().addClass("first").end()
- // Adds class to the last timeline event date.
- //.last().addClass("last");
-
-
- this.init.addIdsAndClasses();
+ .find('.last').removeClass('last').end();
+
+ // Adds classes and IDs.
+ this.init.addIdsAndClasses(this);
this._setDatePosition(timelineComponents);
timelineTotalWidth = this._setTimelineWidth(timelineComponents);
@@ -1227,36 +1276,63 @@ Docs at http://horizontal-timeline.ycodetech.co.uk
Timeline.prototype._showNewContent = function (timelineComponents, timelineTotalWidth, string) {
// Show prev/next content
// Find the .selected content
- var visibleContent = timelineComponents['eventsContent'].find('.selected'),
- // Find the prev/next content
- newContent = (string == 'next') ? visibleContent.next() : visibleContent.prev();
- // If a prev/next content exists...
- if (newContent.length > 0) {
+ var visibleContent = timelineComponents['eventsContent'].find('.selected');
+
+ // If dateOrder is normal...
+ if (this.settings.dateOrder == "normal")
+ // Find the prev/next content for detection later.
+ var newContent = (string == 'next') ? visibleContent.next() : visibleContent.prev();
+
+ // If dateOrder is reverse
+ else if (this.settings.dateOrder == "reverse")
+ // Find the prev/next content in reverse fore detection later.
+ var newContent = (string == 'next') ? visibleContent.prev() : visibleContent.next();
+
+ // If a prev/next content exists
+ // OR dateOrder is reverse AND string is start (for Autoplay)...
+ // This determines whether we can navigate prev or next.
+ if (newContent.length > 0 || (this.settings.dateOrder == "reverse" && string == 'start')) {
// Find the .selected event
var selectedDate = timelineComponents['eventsWrapper'].find('.selected'),
newEvent;
+
// If start... (For Autoplay), find the first event
- if(string == 'start') newEvent = timelineComponents['eventsWrapper'].find('.first');
+ if(string == 'start') {
+
+ // If the dateOrder is normal (starting from the left)...
+ if (this.settings.dateOrder == "normal") {
+ // Find the first event.
+ newEvent = timelineComponents['eventsWrapper'].find('.first');
+ }
+ // Else if the dateOrder is reverse (starting from the right)...
+ else if (this.settings.dateOrder == "reverse") {
+ // Find the last event.
+ newEvent = timelineComponents['eventsWrapper'].find('.last');
+ }
+ }
// If next, find the next event from the current selected event
- else if (string == 'next') newEvent = selectedDate.next('a');
+ else if (string == 'next')
+ newEvent = selectedDate.next('a');
+
// If prev, find the prev event from the current selected event
- else if (string == 'prev') newEvent = selectedDate.prev('a');
+ else if (string == 'prev')
+ newEvent = selectedDate.prev('a');
+
this._updateVisibleContent(newEvent, timelineComponents['eventsContent']);
newEvent.addClass('selected');
selectedDate.removeClass('selected');
this._updateFilling(newEvent, timelineComponents['fillingLine'], timelineTotalWidth);
this._updateOlderEvents(newEvent);
- this._updateTimelinePosition(newEvent, timelineComponents);
+ this._updateTimelinePosition(newEvent, timelineComponents, timelineTotalWidth);
}
}
- Timeline.prototype._updateTimelinePosition = function (event, timelineComponents) {
+ Timeline.prototype._updateTimelinePosition = function (event, timelineComponents, timelineTotalWidth) {
// Get the css left value of the targeted event date
var eventLeft = Number(event.css('left').replace('px', '')),
// Get the width value of the .events-wrapper
- timelineWidth = timelineComponents['timelineWrapper'].width(),
- // Get the width value of the events (previously set)
- timelineTotalWidth = timelineComponents['eventsWrapper'].width();
+ timelineWidth = timelineComponents['timelineWrapper'].width();
+
this._translateTimeline(timelineComponents, - eventLeft + timelineWidth/2, timelineWidth - timelineTotalWidth);
}
@@ -1268,7 +1344,7 @@ Docs at http://horizontal-timeline.ycodetech.co.uk
this._setTransformValue(timelineComponents['eventsWrapper'], 'translateX', value+'px');
// Disable the buttons if necessary
- this._buttonDisable(timelineComponents, value, totalTranslateValue);
+ this._buttonStates(timelineComponents, value, totalTranslateValue);
}
Timeline.prototype._updateFilling = function (selectedEvent, filling, totalTranslateValue) {
@@ -1298,7 +1374,7 @@ Docs at http://horizontal-timeline.ycodetech.co.uk
timelineComponents['timelineEvents'].first().css({'left': '0px','padding-left': '10px'});
startingNum = 1;
}
- // i start at 1, meaning starts at 2nd date.
+ // When i starts at 1, it means starts at 2nd date.
for (i = startingNum; i < timelineComponents['timelineEvents'].length; i++) {
distnew = distprev + dateIntervals;
timelineComponents['timelineEvents'].eq(i).css('left', distnew + 'px');
@@ -1314,15 +1390,17 @@ Docs at http://horizontal-timeline.ycodetech.co.uk
// Get the css left value of the last event date, remove the px unit and add 100 to it.
lastEventLeft = Number(timelineComponents['timelineEvents'].last().css('left').replace('px', '')) + 100;
- // Set the timeline width
- totalWidth = lastEventLeft;
-
- // Set a fail-safe, if totalWidth is less than the wrapperWidth then use the wrapperWidth as width.
+ // Set a fail-safe, if lastEventLeft is less than the wrapperWidth then use the wrapperWidth as totalWidth.
// Stops the timeline width from being too small.
- if (totalWidth < wrapperWidth) totalWidth = wrapperWidth;
+ if (lastEventLeft < wrapperWidth) {
+ totalWidth = wrapperWidth;
+ }
+ else {
+ totalWidth = lastEventLeft;
+ }
timelineComponents['eventsWrapper'].css('width', totalWidth+'px');
- this._updateTimelinePosition(timelineComponents['eventsWrapper'].find('a.selected'), timelineComponents);
+ this._updateTimelinePosition(timelineComponents['eventsWrapper'].find('a.selected'), timelineComponents, totalWidth);
return totalWidth;
}
@@ -1432,8 +1510,10 @@ Docs at http://horizontal-timeline.ycodetech.co.uk
return window.getComputedStyle(this.element,':before').content.replace(/'/g, "").replace(/"/g, "");
}
- // Function to add or remove disabled class to next button depending on whether the last item is selected or not
- Timeline.prototype._buttonDisable = function (timelineComponents, translateValue, totalTranslateValue){
+ //** Button States **//
+
+ // Function to add or remove inactive class.
+ Timeline.prototype._buttonStates = function (timelineComponents, translateValue, totalTranslateValue){
var nextButton = timelineComponents['timelineNavigation'].find('.next'),
prevButton = timelineComponents['timelineNavigation'].find('.prev'),
@@ -1484,7 +1564,7 @@ Docs at http://horizontal-timeline.ycodetech.co.uk
if (translateValue == totalTranslateValue) rightButton.addClass('inactive');
// If not, then enable the scroll right button
else rightButton.removeClass('inactive');
- } // End buttonDisable() function
+ } // End _buttonStates() function
// Function to add required js and css files dynamically
// (CDN URL of the plugin, file type JS or CSS, callback function)
@@ -1592,10 +1672,10 @@ Docs at http://horizontal-timeline.ycodetech.co.uk
// e.g. $(element).defaultPluginName('functionName', arg1, arg2)
$.fn[pluginName] = function ( options ) {
var args = arguments,
- windowWidth = $(window).width(),
- dateExists = $(this).find('.events-content').find('li').map(function() {
- return $(this).data('date');
- }).get();
+ windowWidth = $(window).width(),
+ dateExists = $(this).find('.events-content').find('li').map(function() {
+ return $(this).data('date');
+ }).get();
// Is the first parameter an object (options), or was omitted,
// instantiate a new instance of the plugin.
@@ -1610,7 +1690,12 @@ Docs at http://horizontal-timeline.ycodetech.co.uk
// pass options to our plugin constructor,
// and store the plugin instance
// in the elements jQuery data object.
- $.data(this, 'plugin_' + pluginName, {'originalEventsContent': $(this).find('.events-content').clone()[0], 'windowWidth': windowWidth, 'existingDates': dateExists, 'Timeline': new Timeline( this, options )});
+ $.data(this, 'plugin_' + pluginName, {
+ 'originalEventsContent': $(this).find('.events-content').clone()[0],
+ 'windowWidth': windowWidth,
+ 'existingDates': dateExists,
+ 'Timeline': new Timeline(this, options)
+ });
}
});
diff --git a/README.md b/README.md
index 4c85261..be47e7d 100644
--- a/README.md
+++ b/README.md
@@ -24,6 +24,7 @@ Version 2.0 adds functionality that has been previously requested for the origin
- Added new options for the button icons.
- Added new options to disable the buttons.
- Added an option for custom date display text.
+ - Added an option, dateOrder, allowing the use of reversing the date display.
For full documentation please check out the [Horizontal Timeline 2.0 website](http://horizontal-timeline.ycodetech.co.uk/)
@@ -89,6 +90,7 @@ $('#example').horizontalTimeline({
minimalFirstDateInterval: true,
dateDisplay: "dateTime", // dateTime, date, time, dayMonth, monthYear, year
+ dateOrder: "normal", // normal, reverse
autoplay: false,
autoplaySpeed: 8, // Sec
diff --git a/To Do.md b/To Do.md
new file mode 100644
index 0000000..327e5cb
--- /dev/null
+++ b/To Do.md
@@ -0,0 +1,8 @@
+##### To do:
+
+- Add support for custom slide animations/transitions using Animate.css
+- Implement a namespaced object data attribute to accomodate the data-date and possibly the custom animations.
+- Add method to dynamically change existing dates and reposition them to reflect their new date order.
+- ~~Add support for Right-to-Left.~~ (In the form of `dateOrder: reverse`.)
+- ~~Rename the disableButton to reflect the docs name of Inactive Button States.~~
+- Rework Autoplay to allow multiple autoplaying timelines per page.
diff --git a/css/horizontal_timeline.2.0.css b/css/horizontal_timeline.2.0.css
index 412d782..bd907f1 100644
--- a/css/horizontal_timeline.2.0.css
+++ b/css/horizontal_timeline.2.0.css
@@ -10,11 +10,10 @@ Licensed under the MIT license
Docs at http://horizontal-timeline.ycodetech.co.uk
-------------------------------- */
-html, body {
- /* Stop horizontal scrollbar from appearing/disappearing when the content slides across and changes.
- Also fixes the fixed flexbox elements from moving along with the transforms.*/
- height: auto;
- overflow: auto;
+html,
+body {
+ /* Stop horizontal scrollbar from appearing/disappearing when the content slides across and changes.*/
+ overflow-x: hidden;
}
.horizontal-timeline {
opacity: 0;
@@ -43,7 +42,7 @@ html, body {
/* Timeline */
.horizontal-timeline .timeline {
position: relative;
- height: 100px;
+ height: auto;
margin: 0 auto;
display: flex;
-ms-flex-wrap: wrap;
@@ -138,11 +137,11 @@ html, body {
.timeline-navigation {
position: relative;
top: 3px;
- -webkit-transform: translateY(-50%);
- -moz-transform: translateY(-50%);
- -ms-transform: translateY(-50%);
- -o-transform: translateY(-50%);
- transform: translateY(-50%);
+ -webkit-transform: translateY(50%);
+ -moz-transform: translateY(50%);
+ -ms-transform: translateY(50%);
+ -o-transform: translateY(50%);
+ transform: translateY(50%);
z-index: 2;
}
.timeline-navigation#leftNav {
@@ -170,7 +169,7 @@ html, body {
/* Autoplay Pause/Play button */
.timeline-navigation#pausePlay {
width: 100%;
- top: 10px;
+ top: -10px;
text-align: center;
}
/* Event content */
@@ -207,6 +206,9 @@ html, body {
border-radius: 20px;
opacity: 0;
+ font-size: 16pt;
+ text-align: center;
+
-webkit-touch-callout: none; /* iOS Safari */
-webkit-user-select: none; /* Safari */
-khtml-user-select: none; /* Konqueror HTML */