2014-12-02 16:27:04 +00:00
|
|
|
/* Copyright (C) 2012-2013 Denver Gingerich,
|
2016-09-09 19:39:21 +00:00
|
|
|
** Copyright (C) 2013-2014 Bradley M. Kuhn,
|
|
|
|
** Copyright (C) 2016 Brett Smith.
|
2014-12-03 21:55:17 +00:00
|
|
|
** License: GPLv3-or-later
|
2014-12-02 16:27:04 +00:00
|
|
|
** Find a copy of GPL at https://sfconservancy.org/GPLv3
|
|
|
|
*/
|
|
|
|
|
2016-09-09 19:16:46 +00:00
|
|
|
var supportTypeSelector = function(supportTypeHash) {
|
|
|
|
return $(".supporter-type-selector a[href=" + supportTypeHash + "]");
|
|
|
|
};
|
|
|
|
|
|
|
|
var $window = $(window);
|
|
|
|
|
|
|
|
$window.load(function() {
|
|
|
|
var $selectorLink = supportTypeSelector(window.location.hash);
|
|
|
|
if ($selectorLink.length > 0) {
|
|
|
|
$window.scrollTop($selectorLink.offset().top);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2014-12-02 16:27:04 +00:00
|
|
|
$(document).ready(function() {
|
2015-11-27 13:42:19 +00:00
|
|
|
var siteFinalGoal = $('span#site-fundraiser-final-goal').text();
|
|
|
|
var noCommaSiteFinalGoal = parseInt(siteFinalGoal.replace(/,/g, ""));
|
|
|
|
var siteMiddleGoal = $('span#site-fundraiser-middle-goal').text();
|
|
|
|
var noCommaSiteMiddleGoal = parseInt(siteMiddleGoal.replace(/,/g, ""));
|
2016-11-29 18:29:12 +00:00
|
|
|
if (!noCommaSiteMiddleGoal) {
|
|
|
|
noCommaSiteMiddleGoal = 0;
|
|
|
|
}
|
2015-11-27 13:42:19 +00:00
|
|
|
var siteSoFar = $('span#site-fundraiser-so-far').text();
|
|
|
|
var noCommaSiteSoFar = parseInt(siteSoFar.replace(/,/g, ""));
|
|
|
|
var siteMatchCount = $('span#site-fundraiser-match-count').text();
|
|
|
|
var noCommaSiteMatchCount = parseInt(siteMatchCount.replace(/,/g, ""));
|
|
|
|
if (! noCommaSiteMatchCount) {
|
|
|
|
noCommaSiteMatchCount = "0";
|
|
|
|
}
|
|
|
|
var noCommaMatchFinalGoal = noCommaSiteFinalGoal - noCommaSiteMatchCount;
|
2014-12-09 00:15:17 +00:00
|
|
|
var goal = $('span#fundraiser-goal').text();
|
|
|
|
var soFar = $('span#fundraiser-so-far').text();
|
2015-03-12 01:10:28 +00:00
|
|
|
var donationCount = $('span#fundraiser-donation-count').text();
|
2015-03-12 01:36:01 +00:00
|
|
|
var noCommaGoal = parseFloat(goal.replace(/,/g, ""));
|
|
|
|
var noCommaSoFar = parseFloat(soFar.replace(/,/g, ""));
|
2015-03-12 01:10:28 +00:00
|
|
|
var noCommaDonationCount = parseInt(donationCount.replace(/,/g, ""));
|
2015-03-05 16:00:14 +00:00
|
|
|
var percentage = (parseFloat(noCommaSoFar) / parseFloat(noCommaGoal)) * 100;
|
2015-03-09 07:28:05 +00:00
|
|
|
var curValue = 0.00;
|
|
|
|
var incrementSoFar = 0.00;
|
2015-03-12 01:38:38 +00:00
|
|
|
var curDonationCount = 0;
|
2015-03-12 01:57:06 +00:00
|
|
|
var riseLevelPercent = 0.5;
|
2015-03-21 14:03:28 +00:00
|
|
|
var incrementDonationCount = Math.round( (riseLevelPercent / 100) * noCommaDonationCount );
|
2015-11-27 13:42:19 +00:00
|
|
|
$('#siteprogressbar').empty();
|
|
|
|
|
2016-01-19 04:18:49 +00:00
|
|
|
if (noCommaSiteSoFar >= noCommaSiteMiddleGoal) {
|
2016-01-19 03:50:08 +00:00
|
|
|
// We've got
|
2016-02-24 03:45:16 +00:00
|
|
|
var leftOver = noCommaMatchFinalGoal - noCommaSiteSoFar;
|
2016-11-29 18:13:40 +00:00
|
|
|
var supporterProgress = (noCommaSiteSoFar / noCommaSiteFinalGoal) * 100;
|
2016-11-29 18:45:44 +00:00
|
|
|
var needProgress = (leftOver / noCommaSiteFinalGoal) * 100;
|
2016-02-24 03:21:22 +00:00
|
|
|
|
2016-01-19 03:50:08 +00:00
|
|
|
$('#siteprogressbar').
|
|
|
|
multiprogressbar({ parts: [
|
2016-11-29 18:13:40 +00:00
|
|
|
{ value: supporterProgress,
|
2016-02-24 03:46:59 +00:00
|
|
|
text: noCommaSiteSoFar.toLocaleString() + " have joined!",
|
2016-01-19 03:50:08 +00:00
|
|
|
barClass: "progress", textClass: "soFarText" },
|
2016-11-29 18:13:40 +00:00
|
|
|
{ value: needProgress,
|
|
|
|
text: leftOver.toLocaleString() + " more needed",
|
2016-01-19 03:50:08 +00:00
|
|
|
barClass: "final-goal", textClass: "goalText" },
|
2016-11-29 18:13:40 +00:00
|
|
|
{ value: 100,
|
|
|
|
text: noCommaSiteMatchCount.toLocaleString() + " matched!",
|
|
|
|
barClass: "progress", textClass: "soFarText" },
|
2016-01-19 03:50:08 +00:00
|
|
|
]});
|
|
|
|
} else {
|
|
|
|
$('#siteprogressbar').
|
|
|
|
multiprogressbar({ parts: [
|
|
|
|
{ value: (noCommaSiteSoFar / noCommaSiteFinalGoal) * 100,
|
|
|
|
text: siteSoFar + " joined!",
|
|
|
|
barClass: "progress", textClass: "soFarText" },
|
|
|
|
{ value: ((noCommaSiteMiddleGoal - noCommaSiteSoFar) / noCommaSiteFinalGoal) * 100,
|
|
|
|
text: siteMiddleGoal + " will save our basic work",
|
|
|
|
barClass: "middle-goal", textClass: "goalText" },
|
|
|
|
{ value:
|
|
|
|
((noCommaMatchFinalGoal - noCommaSiteMiddleGoal) / noCommaSiteFinalGoal) * 100,
|
|
|
|
text: noCommaMatchFinalGoal.toLocaleString() + " will save license compliance",
|
|
|
|
barClass: "final-goal", textClass: "goalText" },
|
|
|
|
{ value: 100,
|
|
|
|
text: siteMatchCount + " matched!",
|
|
|
|
barClass: "progress", textClass: "soFarText" },
|
|
|
|
]});
|
|
|
|
}
|
2015-03-09 06:48:57 +00:00
|
|
|
$('span#fundraiser-percentage').css({ 'color' : 'green',
|
|
|
|
'font-weight' : 'bold',
|
|
|
|
'float' : 'right',
|
|
|
|
'margin-right' : '40%',
|
|
|
|
'margin-top' : '2.5%',
|
2015-03-09 06:51:32 +00:00
|
|
|
'text-align' : 'inherit'});
|
2015-03-12 01:10:28 +00:00
|
|
|
function riseDonationProgressBar() {
|
2015-03-09 07:28:05 +00:00
|
|
|
if (curValue >= percentage) {
|
|
|
|
$('span#fundraiser-so-far').text(soFar);
|
|
|
|
$("#progressbar").progressbar({ value : percentage });
|
|
|
|
$('span#fundraiser-percentage').text(percentage.toFixed(1) + "%");
|
|
|
|
} else {
|
|
|
|
var newVal = (curValue / 100.00) * noCommaGoal;
|
|
|
|
$("#progressbar").progressbar({ value: curValue });
|
|
|
|
$('span#fundraiser-so-far').text(newVal.toLocaleString());
|
2015-03-12 01:57:06 +00:00
|
|
|
curValue += riseLevelPercent;
|
2015-03-12 01:10:28 +00:00
|
|
|
setTimeout(riseDonationProgressBar, 50);
|
2015-03-09 07:28:05 +00:00
|
|
|
}
|
|
|
|
}
|
2015-03-12 01:10:28 +00:00
|
|
|
function riseDonationCount() {
|
2015-03-12 01:38:38 +00:00
|
|
|
if (curDonationCount >= noCommaDonationCount) {
|
2015-03-12 01:10:28 +00:00
|
|
|
$('span#fundraiser-donation-count').text(donationCount);
|
|
|
|
} else {
|
2015-03-12 01:38:38 +00:00
|
|
|
$('span#fundraiser-donation-count').text(curDonationCount.toLocaleString());
|
2015-03-12 01:42:40 +00:00
|
|
|
curDonationCount += incrementDonationCount;
|
2015-03-12 01:10:28 +00:00
|
|
|
setTimeout(riseDonationCount, 50);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (noCommaDonationCount > 0) {
|
2015-03-12 01:42:40 +00:00
|
|
|
$('span#fundraiser-donation-count').text("");
|
2015-03-12 01:10:28 +00:00
|
|
|
riseDonationCount();
|
|
|
|
}
|
2015-03-12 01:41:24 +00:00
|
|
|
if (noCommaSoFar > 0.00 && noCommaGoal > 0.00) {
|
2015-03-12 01:36:01 +00:00
|
|
|
$('span#fundraiser-percentage').text("");
|
|
|
|
$("#progressbar").progressbar({ value: curValue });
|
|
|
|
riseDonationProgressBar();
|
|
|
|
}
|
2014-12-08 20:45:58 +00:00
|
|
|
|
2014-12-02 16:27:04 +00:00
|
|
|
$('.toggle-content').hide();
|
|
|
|
|
|
|
|
$('.toggle-control')
|
|
|
|
.addClass('clickable')
|
|
|
|
.bind('click', function() {
|
|
|
|
var $control = $(this);
|
|
|
|
var $parent = $control.parents('.toggle-unit');
|
|
|
|
|
|
|
|
$parent.toggleClass('expanded');
|
|
|
|
$parent.find('.toggle-content').slideToggle();
|
|
|
|
|
|
|
|
// if control has HTML5 data attributes, use to update text
|
|
|
|
if ($parent.hasClass('expanded')) {
|
|
|
|
$control.html($control.attr('data-expanded-text'));
|
|
|
|
} else {
|
|
|
|
$control.html($control.attr('data-text'));
|
|
|
|
}
|
|
|
|
});
|
|
|
|
$('a.donate-now')
|
|
|
|
.addClass('clickable')
|
|
|
|
.bind('click', function() {
|
|
|
|
var $control = $('#donate-box');
|
2015-03-09 15:46:16 +00:00
|
|
|
var $otherTextControl = $('.donate-sidebar');
|
2014-12-02 16:27:04 +00:00
|
|
|
|
2015-03-09 15:46:16 +00:00
|
|
|
setTimeout(function() { $control.find('.toggle-content').slideUp(100);
|
|
|
|
$control.toggleClass('expanded');
|
|
|
|
$control.find('.toggle-content').slideDown(800).fadeOut(10);
|
|
|
|
$otherTextControl.find('.donate-box-highlight').fadeOut(100);
|
|
|
|
}, 300);
|
|
|
|
setTimeout(function() { $control.find('.toggle-content').fadeIn(2000);
|
|
|
|
$otherTextControl.find('.donate-box-highlight')
|
|
|
|
.css({'font-weight': 'bold', 'font-size' : '110%' });
|
|
|
|
$otherTextControl.find('.donate-box-highlight').fadeIn(10000);
|
|
|
|
}, 500);
|
2014-12-02 16:27:04 +00:00
|
|
|
});
|
2014-12-03 21:20:57 +00:00
|
|
|
$(".t-shirt-size-selector").hide();
|
2015-01-03 18:14:17 +00:00
|
|
|
$('input[name=on0]:radio').change(function() {
|
2014-12-03 18:33:26 +00:00
|
|
|
var input=$(this);
|
2014-12-04 02:09:25 +00:00
|
|
|
var tShirtSelector = input.parent().children('.t-shirt-size-selector')
|
|
|
|
var noShippingSelector = input.parent().children('input#no_shipping');
|
2014-12-03 18:33:26 +00:00
|
|
|
var value = input.val();
|
2015-01-03 18:14:17 +00:00
|
|
|
if (value == "wantGiftYes") {
|
2014-12-04 02:09:25 +00:00
|
|
|
tShirtSelector.show();
|
|
|
|
noShippingSelector.val("2");
|
2014-12-03 18:33:26 +00:00
|
|
|
} else {
|
2014-12-04 02:09:25 +00:00
|
|
|
tShirtSelector.hide();
|
|
|
|
noShippingSelector.val("0");
|
2014-12-03 18:33:26 +00:00
|
|
|
}
|
|
|
|
});
|
Start errors in shown state for non-Javascript.
Since the error messages have important information, and since the
Javascript code is the only "enforcer" of the minimum donation, the
errors really should be displayed by default if the browser is not
Javascript-capable. This change does that, but also toggles the state
back so that errors are not shown until needed in Javascript-capable
browsers.
I believe this still fits graceful degradation, since browsers without
Javascript and CSS were already showing the errors anyway, so now the
only real change is that everyone sees the errors by default.
It *might* make sense to not show the errors in red in non-Javascript
browsers (i.e., make the default CSS color black for the form-error-show
class, and then change it to red in the Javascript). I didn't make that
so, because it's not clear to me that's right, and we *do* want to draw
attention to the errors lest people become a supporter below the
minimum (which has happened once already -- that precipitated this
change).
I'm still annoyed that PayPal doesn't provide a "minimum but no maximum"
variable donation box of its own, which would solve this problem
outright.
2014-12-05 15:07:27 +00:00
|
|
|
|
|
|
|
// Forms start in "invalid" form, with the errors shown, so that
|
|
|
|
// non-Javascript users see the errors by default and know what they must
|
|
|
|
// enter. The following two lines correct that.
|
2014-12-04 01:40:41 +00:00
|
|
|
$('*#amount').addClass("valid");
|
Start errors in shown state for non-Javascript.
Since the error messages have important information, and since the
Javascript code is the only "enforcer" of the minimum donation, the
errors really should be displayed by default if the browser is not
Javascript-capable. This change does that, but also toggles the state
back so that errors are not shown until needed in Javascript-capable
browsers.
I believe this still fits graceful degradation, since browsers without
Javascript and CSS were already showing the errors anyway, so now the
only real change is that everyone sees the errors by default.
It *might* make sense to not show the errors in red in non-Javascript
browsers (i.e., make the default CSS color black for the form-error-show
class, and then change it to red in the Javascript). I didn't make that
so, because it's not clear to me that's right, and we *do* want to draw
attention to the errors lest people become a supporter below the
minimum (which has happened once already -- that precipitated this
change).
I'm still annoyed that PayPal doesn't provide a "minimum but no maximum"
variable donation box of its own, which would solve this problem
outright.
2014-12-05 15:07:27 +00:00
|
|
|
$('.supporter-form-inputs .form-error-show')
|
|
|
|
.removeClass('form-error-show').addClass('form-error');
|
2015-01-20 21:07:19 +00:00
|
|
|
$('.dinner-form-inputs .form-error-show')
|
|
|
|
.removeClass('form-error-show').addClass('form-error');
|
Start errors in shown state for non-Javascript.
Since the error messages have important information, and since the
Javascript code is the only "enforcer" of the minimum donation, the
errors really should be displayed by default if the browser is not
Javascript-capable. This change does that, but also toggles the state
back so that errors are not shown until needed in Javascript-capable
browsers.
I believe this still fits graceful degradation, since browsers without
Javascript and CSS were already showing the errors anyway, so now the
only real change is that everyone sees the errors by default.
It *might* make sense to not show the errors in red in non-Javascript
browsers (i.e., make the default CSS color black for the form-error-show
class, and then change it to red in the Javascript). I didn't make that
so, because it's not clear to me that's right, and we *do* want to draw
attention to the errors lest people become a supporter below the
minimum (which has happened once already -- that precipitated this
change).
I'm still annoyed that PayPal doesn't provide a "minimum but no maximum"
variable donation box of its own, which would solve this problem
outright.
2014-12-05 15:07:27 +00:00
|
|
|
|
2014-12-04 01:40:41 +00:00
|
|
|
$('*#amount').on('input', function() {
|
2014-12-02 16:31:43 +00:00
|
|
|
var input=$(this);
|
|
|
|
var value = input.val();
|
2014-12-04 01:40:41 +00:00
|
|
|
var errorElement=$("span#error", input.parent());
|
2014-12-02 22:04:05 +00:00
|
|
|
var noCommaValue = value;
|
|
|
|
noCommaValue = value.replace(/,/g, "");
|
|
|
|
var re = /^((\d{1,3}(,?\d{3})*?(\.\d{0,2})?)|\d+(\.\d{0,2})?)$/;
|
2014-12-03 23:10:45 +00:00
|
|
|
var isValid = ( re.test(value) &&
|
|
|
|
parseInt(noCommaValue) >= parseInt(input.attr("minimum")));
|
2014-12-02 16:31:43 +00:00
|
|
|
if (isValid) {
|
|
|
|
input.removeClass("invalid").addClass("valid");
|
|
|
|
errorElement.removeClass("form-error-show").addClass("form-error");
|
2014-12-02 22:26:55 +00:00
|
|
|
$("#form-correction-needed").removeClass("form-error-show").addClass("form-error");
|
2014-12-02 16:31:43 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
input.removeClass("valid").addClass("invalid");
|
|
|
|
errorElement.removeClass("form-error").addClass("form-error-show");
|
|
|
|
}
|
2014-12-02 18:30:18 +00:00
|
|
|
});
|
2014-12-04 01:44:15 +00:00
|
|
|
var validateFormAtSubmission = function(element, event) {
|
|
|
|
var valid = element.hasClass("valid");
|
|
|
|
if (! valid) {
|
|
|
|
$("#form-correction-needed").removeClass("form-error").addClass("form-error-show")
|
2014-12-02 22:26:55 +00:00
|
|
|
.css("font-weight", "bold").css("font-size", "150%");
|
2014-12-04 01:44:15 +00:00
|
|
|
event.preventDefault();
|
|
|
|
} else {
|
|
|
|
$("#form-correction-needed").removeClass("form-error-show").addClass("form-error");
|
|
|
|
}
|
|
|
|
};
|
|
|
|
$(".supporter-form-submit#monthly").click(function (event) {
|
|
|
|
validateFormAtSubmission($(".supporter-form#monthly input#amount"), event);
|
|
|
|
});
|
|
|
|
$(".supporter-form-submit#annual").click(function (event) {
|
|
|
|
validateFormAtSubmission($(".supporter-form#annual input#amount"), event);
|
2014-12-02 22:26:55 +00:00
|
|
|
});
|
2015-12-21 17:25:04 +00:00
|
|
|
$(".supporter-form-submit#renewal").click(function (event) {
|
|
|
|
validateFormAtSubmission($(".supporter-form#renewal input#amount"), event);
|
|
|
|
});
|
2015-01-20 21:07:19 +00:00
|
|
|
$(".dinner-form-submit").click(function (event) {
|
|
|
|
validateFormAtSubmission($(".dinner-form input#amount"), event);
|
|
|
|
});
|
2014-12-02 18:30:18 +00:00
|
|
|
|
2016-09-09 16:10:41 +00:00
|
|
|
var selectSupportType = function(event) {
|
|
|
|
var $selectedLink = $(event.target);
|
|
|
|
$(".supporter-type-selector a").removeClass("supporter-type-selector-selected");
|
|
|
|
$selectedLink.addClass("supporter-type-selector-selected");
|
|
|
|
$(".supporter-type-selection").each(function(index, element) {
|
|
|
|
var $element = $(element);
|
|
|
|
if (event.target.href.endsWith("#" + element.id)) {
|
|
|
|
$element.show();
|
|
|
|
} else {
|
|
|
|
$element.hide();
|
|
|
|
}
|
|
|
|
});
|
2014-12-02 23:02:32 +00:00
|
|
|
$("#form-correction-needed").removeClass("form-error-show").addClass("form-error");
|
2016-09-09 18:35:15 +00:00
|
|
|
return false;
|
2016-09-09 16:10:41 +00:00
|
|
|
};
|
|
|
|
$(".supporter-type-selector a").bind("click", selectSupportType);
|
|
|
|
|
|
|
|
var selectSupportTypeFromHash = function() {
|
2016-09-09 18:35:15 +00:00
|
|
|
return supportTypeSelector(window.location.hash).click();
|
2016-09-09 16:10:41 +00:00
|
|
|
};
|
2016-09-09 18:35:15 +00:00
|
|
|
$window.bind("hashchange", selectSupportTypeFromHash);
|
|
|
|
var $selectorLink = selectSupportTypeFromHash();
|
|
|
|
if ($selectorLink.length === 0) {
|
|
|
|
supportTypeSelector("#annual").click();
|
|
|
|
}
|
2016-09-09 16:10:41 +00:00
|
|
|
|
2014-12-02 23:25:42 +00:00
|
|
|
$( ".footnote-mark" ).tooltip({
|
|
|
|
items: "a",
|
|
|
|
hide: { duration: 5000 },
|
|
|
|
position: {
|
|
|
|
my: "center bottom-20",
|
|
|
|
at: "center left",
|
|
|
|
using: function( position, feedback ) {
|
|
|
|
$( this ).css( position );
|
|
|
|
$( "<div>" )
|
|
|
|
.addClass( "arrow" )
|
|
|
|
.addClass( feedback.vertical )
|
|
|
|
.addClass( feedback.horizontal )
|
|
|
|
.appendTo( this );
|
|
|
|
}
|
|
|
|
},
|
|
|
|
content: function() {
|
|
|
|
return $('.footnote-1-text').text();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|