Adding bootstrap-tour with some initial steps

This commit is contained in:
Tyler Renelle 2012-07-07 12:31:51 -04:00
parent 16c8ba8370
commit 7fb26ab7c5
4 changed files with 306 additions and 0 deletions

226
public/bootstrap-tour.js vendored Normal file
View file

@ -0,0 +1,226 @@
// Generated by CoffeeScript 1.3.3
/* ============================================================
# bootstrap-tour.js v0.1
# http://pushly.github.com/bootstrap-tour/
# ==============================================================
# Copyright 2012 Push.ly
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
*/
(function() {
(function($, window) {
var Tour, document;
document = window.document;
Tour = (function() {
function Tour(options) {
var _this = this;
this._options = $.extend({
afterSetState: function(key, value) {},
afterGetState: function(key, value) {}
}, options);
this._steps = [];
this.setCurrentStep();
$(document).on("click", ".popover .next", function(e) {
e.preventDefault();
return _this.next();
});
$(document).on("click", ".popover .end", function(e) {
e.preventDefault();
return _this.end();
});
}
Tour.prototype.setState = function(key, value) {
$.cookie("tour_" + key, value, {
expires: 36500,
path: '/'
});
return this._options.afterSetState(key, value);
};
Tour.prototype.getState = function(key) {
var value;
value = $.cookie("tour_" + key);
this._options.afterGetState(key, value);
return value;
};
Tour.prototype.addStep = function(step) {
return this._steps.push(step);
};
Tour.prototype.getStep = function(i) {
return $.extend({
path: "",
placement: "right",
title: "",
content: "",
next: i + 1,
end: i === this._steps.length - 1,
animation: true
}, this._steps[i]);
};
Tour.prototype.start = function(force) {
if (force == null) {
force = false;
}
if (force || !this.ended()) {
return this.showStep(this._current);
}
};
Tour.prototype.next = function() {
this.hideStep(this._current);
return this.showNextStep();
};
Tour.prototype.end = function() {
this.hideStep(this._current);
return this.setState("end", "yes");
};
Tour.prototype.ended = function() {
return !!this.getState("end");
};
Tour.prototype.restart = function() {
this.setState("current_step", null);
this.setState("end", null);
this.setCurrentStep(0);
return this.start();
};
Tour.prototype.hideStep = function(i) {
var step;
step = this.getStep(i);
if (step.onHide != null) {
step.onHide(this);
}
return $(step.element).popover("hide");
};
Tour.prototype.showStep = function(i) {
var endOnClick, step,
_this = this;
step = this.getStep(i);
if (step.element == null) {
this.end;
return;
}
this.setCurrentStep(i);
if (step.path !== "" && document.location.pathname !== step.path && document.location.pathname.replace(/^.*[\\\/]/, '') !== step.path) {
document.location.href = step.path;
return;
}
if ($(step.element).is(":hidden")) {
this.showNextStep();
return;
}
endOnClick = step.endOnClick || step.element;
$(endOnClick).one("click", function() {
return _this.endCurrentStep();
});
if (step.onShow != null) {
step.onShow(this);
}
return this._showPopover(step, i);
};
Tour.prototype.setCurrentStep = function(value) {
if (value != null) {
this._current = value;
return this.setState("current_step", value);
} else {
this._current = this.getState("current_step");
if (this._current === null || this._current === "null") {
return this._current = 0;
} else {
return this._current = parseInt(this._current);
}
}
};
Tour.prototype.endCurrentStep = function() {
var step;
this.hideStep(this._current);
step = this.getStep(this._current);
return this.setCurrentStep(step.next);
};
Tour.prototype.showNextStep = function() {
var step;
step = this.getStep(this._current);
return this.showStep(step.next);
};
Tour.prototype._showPopover = function(step, i) {
var content, tip;
content = "" + step.content + "<br /><p>";
if (step.end) {
content += "<a href='#' class='end'>End</a>";
} else {
content += "<a href='#" + step.next + "' class='next'>Next &raquo;</a> <a href='#' class='pull-right end'>End tour</a></p>";
}
$(step.element).popover({
placement: step.placement,
trigger: "manual",
title: step.title,
content: content,
animation: step.animation
}).popover("show");
tip = $(step.element).data("popover").tip();
this._reposition(tip);
return this._scrollIntoView(tip);
};
Tour.prototype._reposition = function(tip) {
var offsetBottom, offsetRight, tipOffset;
tipOffset = tip.offset();
offsetBottom = $(document).outerHeight() - tipOffset.top - $(tip).outerHeight();
if (offsetBottom < 0) {
tipOffset.top = tipOffset.top + offsetBottom;
}
offsetRight = $(document).outerWidth() - tipOffset.left - $(tip).outerWidth();
if (offsetRight < 0) {
tipOffset.left = tipOffset.left + offsetRight;
}
if (tipOffset.top < 0) {
tipOffset.top = 0;
}
if (tipOffset.left < 0) {
tipOffset.left = 0;
}
return tip.offset(tipOffset);
};
Tour.prototype._scrollIntoView = function(tip) {
var tipRect;
tipRect = tip.get(0).getBoundingClientRect();
if (!(tipRect.top > 0 && tipRect.bottom < $(window).height() && tipRect.left > 0 && tipRect.right < $(window).width())) {
return tip.get(0).scrollIntoView(true);
}
};
return Tour;
})();
return window.Tour = Tour;
})(jQuery, window);
}).call(this);

47
public/jquery.cookie.js Normal file
View file

@ -0,0 +1,47 @@
/*!
* jQuery Cookie Plugin
* https://github.com/carhartl/jquery-cookie
*
* Copyright 2011, Klaus Hartl
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://www.opensource.org/licenses/mit-license.php
* http://www.opensource.org/licenses/GPL-2.0
*/
(function($) {
$.cookie = function(key, value, options) {
// key and at least value given, set cookie...
if (arguments.length > 1 && (!/Object/.test(Object.prototype.toString.call(value)) || value === null || value === undefined)) {
options = $.extend({}, options);
if (value === null || value === undefined) {
options.expires = -1;
}
if (typeof options.expires === 'number') {
var days = options.expires, t = options.expires = new Date();
t.setDate(t.getDate() + days);
}
value = String(value);
return (document.cookie = [
encodeURIComponent(key), '=', options.raw ? value : encodeURIComponent(value),
options.expires ? '; expires=' + options.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE
options.path ? '; path=' + options.path : '',
options.domain ? '; domain=' + options.domain : '',
options.secure ? '; secure' : ''
].join(''));
}
// key and possibly options given, get cookie...
options = value || {};
var decode = options.raw ? function(s) { return s; } : decodeURIComponent;
var pairs = document.cookie.split('; ');
for (var i = 0, pair; pair = pairs[i] && pairs[i].split('='); i++) {
if (decode(pair[0]) === key) return decode(pair[1] || ''); // IE saves cookies with empty string as "c; ", e.g. without "=" as opposed to EOMB, thus pair[1] may be undefined
}
return null;
};
})(jQuery);

View file

@ -174,6 +174,37 @@ ready (model) ->
# or the item's id property
model.at("_#{type}List").pass(ignore: domId).move {id}, to
setupSortable(type) for type in ['habit', 'daily', 'todo', 'reward']
tour = new Tour()
tour.addStep
element: "#avatar"
title: "Welcome to HabitRPG"
content: "A habit-tracker which treats your goals like a Role Playing Game."
tour.addStep
element: "#bars"
title: "Acheive goals and level up"
content: "As you accomplish goals, you level up and earn gold to spend on rewards. If you fail your goals, you lose hit points. Lose all your HP and you die."
tour.addStep
element: "ul.habits"
title: "Habits"
content: "Habits are goals that you constantly monitor."
placement: "bottom"
tour.addStep
element: "ul.dailys"
title: "Dailies"
content: "Dailies are goals that you want to complete once a day."
placement: "bottom"
tour.addStep
element: "ul.todos"
title: "Todos"
content: "Todos are one-off goals which need to be completed eventually."
placement: "bottom"
tour.addStep
element: "ul.rewards"
title: "Rewards"
content: "As you complete goals, you earn gold. Buy rewards, and buy them liberally - rewards are integral in forming good habits."
placement: "bottom"
tour.start()
#TODO: implement this for completed tab
# clearCompleted: ->

View file

@ -206,6 +206,8 @@
<script src=/jquery-ui.min.js></script>
<script src=/bootstrap.min.js></script>
<script src=/underscore-min.js></script>
<script src=/jquery.cookie.js></script>
<script src=/bootstrap-tour.js></script>
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript">
google.load("visualization", "1", {packages:["corechart"]});