Template References¶
This document contains reference material for the ActionKit Original Templateset and Custom Templateset Fields, Javascripts, and Cascading Style Sheets.
Templateset Reference¶
The following template code is provided for the Original templateset. This templateset supercedes the Original (before Fall 2016) templateset.
It uses a selection of custom templateset fields to customize the design via a point-and-click interface.
For detailed instructions as well as examples on how to modify your templates, see Customizing Pages with Templates.
- Call Page
- Country select
- Date picker
- Donate
- Event attend
- Event attendee details
- Event attendee tell-a-friend message
- Event attendee tools
- Event chooser
- Event contact
- Event create
- Event created
- Event email attendee removed
- Event email cancelled
- Event email created
- Event email approved
- Event email from admin
- Event email from attendee
- Event email from host
- Event email role changed
- Event host details
- Event host tell-a-friend message
- Event host tools
- Event invite
- Event roster
- Event search
- Event search results
- Inline tell-a-friend
- Language picker
- Letter
- Letter to the editor (lte)
- Login
- Logout
- Password
- Petition
- Petition download
- Progress meter
- Recurring cancel
- Recurring info
- Recurring update
- Reset
- Reset password email
- Signup
- Site 404
- Site 500
- Site root
- Social plugins
- State select
- Survey
- Thanks
- Unsubscribe
- User form
- User form intl
- User form wrapper
- User merge
- User update
- User update form
- User view
- Whipcount
- Whipcount results
- Wrapper
Call Page¶
Call page layout.
{% extends "./wrapper.html" %}
{% block content %}
<div class="ak-grid-row">
<div class="ak-grid-col ak-grid-col-12-of-12">
<h2>{{ page.title }}</h2>
</div>
</div>
<form class="ak-form ak-styled-fields" name="act" method="POST" action="/act/" accept-charset="utf-8">
<input type="hidden" name="page" value="{{ page.name }}">
<div class="ak-grid-row">
<div>
<div class="ak-grid-col ak-grid-col-8-of-12">
<div id="call-story" class="ak-text-expander">
{% include_tmpl form.introduction_text %}
</div>
<a href="#" class="ak-read-more ak-mobile">Read more</a>
</div>
<div class="ak-grid-col ak-grid-col-4-of-12">
{% if page.custom_fields.featured_image %}
<img class="ak-featured-img" src="{{page.custom_fields.featured_image}}">
{% endif %}
{% include "./progress_meter.html" %}
<div id="call-form" class="ak-styled-fields {{templateset.custom_fields.field_labels_class|default:"ak-labels-overlaid"}} {{templateset.custom_fields.field_errors_class|default:"ak-errs-below"}}">
<div id="ak-need-contact-info"></div>
<script type="text/ak-template" for="ak-need-contact-info">
[% if (incomplete) { %]
<div class="ak-instructions ak-faded-text">
{% filter ak_text:"call_needs_contact_info" %}
Fill out the form below so we can find the number for you to call.
{% endfilter %}
</div>
[% } %]
</script>
{% include "./user_form_wrapper.html" %}
</div>
</div>
</div>
<div class="ak-steps-area">
<div class="ak-grid-col ak-grid-col-4-of-12">
<div id="what_to_say"></div>
<script type="text/ak-template" for="what_to_say">
[% if (!incomplete) { %]
<h3>
<label class="ak-step-label">
<div class="ak-step-number">1</div>
Review Script
</label>
<span class="ak-arrow-holder"><span class="ak-arrow"></span></span>
</h3>
<div class="ak-field-box ak-field-box-borderless">{% include_tmpl form.script_text %}</div>
[% }
%]
<style>
[% if (incomplete) { %]
#what_to_say { display: none; }
[% } else { %]
.ak-steps-area { clear: both; }
[% } %]
</style>
</script>
</div>
<div class="ak-grid-col ak-grid-col-4-of-12">
<div id="who_called"></div>
<script type="text/ak-template" for="who_called">
[% if (!incomplete) { %]
<h3>
<label class="ak-step-label">
<div class="ak-step-number">2</div>
Make the Call
</label>
<span class="ak-arrow-holder"><span class="ak-arrow"></span></span>
</h3>
<div class="ak-margin-top-1">Who did you call?</div>
[% } %]
</script>
<div id="target_checkboxes" class="ak-margin-bottom-1"></div>
</div>
<div class="ak-grid-col ak-grid-col-4-of-12">
<div id="ak-survey_question"></div>
{% if form.survey_question_text %}
<script type="text/ak-template" for="ak-survey_question">
[% if (!incomplete) { %]
<h3 id="ak-report-call">
<label class="ak-step-label">
<div class="ak-step-number">3</div>
Report the Call
</label>
<span class="ak-arrow-holder"><span class="ak-arrow"></span></span>
</h3>
<div class="ak-labels-overlaid ak-margin-top-1">
<label for="id_action_survey">{% include_tmpl form.survey_question_text %}</label>
<textarea id="id_action_survey" name="action_survey" class="ak-large-message"></textarea>
</div>
[% } %]
</script>
{% endif %}
</div>
</div>
<div class="ak-grid-col ak-grid-col-4-of-12 ak-pull-right">
<button type="submit" class="ak-submit-button">Submit</button>
</div>
</div>
</form>
{% endblock %}
{% block script_additions %}
<script type="text/javascript">
$(window).load(function() {
$('#target_checkboxes').appendTo('div#who_called');
var $window = $(window);
function call_page_steps_mobile() {
var windowSize = $window.width();
if (windowSize < 480) {
$('.ak-steps-area h3').addClass('clickable');
} else {
$('.ak-steps-area h3').removeClass('clickable');
$('.ak-steps-area h3').each( function () {
$(this).siblings('div').show();
});
}
}
$('.ak-steps-area').on('click', 'h3.clickable', function(e) {
e.stopPropagation();
$(this).toggleClass('active');
$(this).siblings('div').stop().slideToggle('fast');
});
$(window).on('resize', call_page_steps_mobile);
call_page_steps_mobile();
});
</script>
{% endblock %}
Country Select¶
Country list used in donate.html if you're accepting international donations on the page.
<select name="{{ input_name_prefix }}country" id="id_{{ input_name_prefix }}country" {% if onchange %}onchange="{{ onchange }}" onblur="{{ onchange }}"{% endif %}>
{% if page.lang_or_en.country_names_us_first %}
{% for std_name,name in page.lang_or_en.country_names_us_first %}
<option value="{{ std_name|escapeall }}">{{ name|escapeall }}</option>
{% endfor %}
{% else %}
<option selected value="United States">United States</option>
{% for std_name,name in page.lang_or_en.country_names %}
<option value="{{ std_name|escapeall }}">{{ name|escapeall }}</option>
{% endfor %}
{% endif %}
</select>
{% if not input_name_prefix %}
{% if filename != "event_search.html" and filename != "recurring_update.html" and filename != "event_search_moderator.html" %}
<!-- Canada explicit opt-in box -->
<div id="ak-fieldbox-subscription_consent">
<input type="hidden" id="id_suppress_subscribe" name="suppress_subscribe" value="">
<input class="no-overlay" type="checkbox" id="id_subscription_consent" name="subscription_consent" value="1">
<label for="id_subscription_consent">Subscribe me to email updates</label>
<span id="id_subscription_consent_more_lnk">(<a href="#">details</a>)</span>
<div id="id_subscription_consent_more">
If you don't subscribe, you might miss news on this campaign
or future opportunities to act. (If you're already subscribed,
leaving this box unchecked won't remove you.)
</div>
<script>
$('#id_subscription_consent_more_lnk a').click(function() {
$('#id_subscription_consent_more_lnk').hide();
$('#id_subscription_consent_more').show();
return false;
})
$('#id_subscription_consent').change(function() {
$('#id_suppress_subscribe').val(this.checked ? '' : '1')}
);
$('#id_{{ input_name_prefix }}country').change(function() {
var country = $(this).val();
if (country == 'Canada') {
$('#id_suppress_subscribe').val('1')
$('#id_subscription_consent').attr('checked', false)
$('#ak-fieldbox-subscription_consent').show()
}
else {
$('#id_suppress_subscribe').val('')
$('#ak-fieldbox-subscription_consent').hide()
}
});
</script>
<!-- With JavaScript off, we can't show a consent box -->
<noscript><input type="hidden" name="suppress_subscribe_in" value="Canada"></noscript>
</div>
{% endif %}
{% endif %}
Date Picker¶
Calendar display widget used in event_create.html to allow hosts to pick dates.
<span class="ak-datetime">
{% if date_field.hidden_date %}
<input type="hidden" name="{{ date_field.name }}_date" id="id_{{ date_field.name }}_date" value="{{ date_field.default_date }}">
{% else %}
{% if date_field.static_date %}
<input type="hidden" name="{{ date_field.name }}_date" id="id_{{ date_field.name }}_date" value="{{ date_field.default_date }}">
<span class="ak-datepicker-static-date">{{ date_field.default_date }}</span>
{% else %}
<input type="text" placeholder="mm/dd/yyyy" size="10" name="{{ date_field.name }}_date" id="id_{{ date_field.name }}_date" value="{{ date_field.default_date }}" format="date">
{% endif %}
{% if not date_field.hidden_time %}
at
{% endif %}
{% endif %}
{% if date_field.hidden_time %}
<input type="hidden" name="{{ date_field.name }}_time" id="id_{{ date_field.name }}_time" value="{{ date_field.default_time }}">
{% else %}
{% if date_field.static_time %}
<input type="hidden" name="{{ date_field.name }}_time" id="id_{{ date_field.name }}_time" format="time" value="{{ date_field.default_time }}">
<input type="hidden" name="{{ date_field.name }}_ampm" id="id_{{ date_field.name }}_ampm" value="{{ date_field.default_ampm }}">
<span class="ak-datepicker-static-time">{{ date_field.default_time }} {{ date_field.default_ampm }}</span>
{% else %}
<input type="text" placeholder="hh:mm" size="8" name="{{ date_field.name }}_time" id="id_{{ date_field.name }}_time" value="{{ date_field.default_time }}" format="time">
<select name="{{ date_field.name }}_ampm" id="id_{{ date_field.name }}_ampm">
<option {% if date_field.default_ampm == 'AM' %}selected{% endif %} value="AM">AM</option>
<option {% if date_field.default_ampm == 'PM' %}selected{% endif %} value="PM">PM</option>
</select>
{% endif %}
{% endif %}
</span>
Donate¶
Donation page layout including contact form fields and layout.
{% extends "./wrapper.html" %}
{% block body_extra_classes %}{% if page.payment_processor_information.is_oneclick %}actionkit-donate-fa {% endif %}{{ block.super }}{% endblock %}
{% block content %}
<form id="act" name="act" class="{{ templateset.custom_fields.donation_steps }}" method="POST" action="/act/" accept-charset="utf-8">
<input type="hidden" name="page" value="{{ page.name }}">
<input type="hidden" name="orig_akid" value="{{ akid }}">
<div class="ak-grid-row">
<div class="ak-grid-col ak-grid-col-12-of-12">
<h2>{{ page.title }}</h2>
</div>
</div>
<div class="ak-grid-row">
<div class="ak-grid-col ak-grid-col-4-of-12">
{% if page.custom_fields.featured_image %}
<img class="ak-featured-img" src="{{page.custom_fields.featured_image}}">
{% endif %}
<div>{% include "./progress_meter.html" %}</div>
{% include_tmpl form.ask_text %}
</div>
<div class="ak-grid-col ak-grid-col-8-of-12">
<div class="ak-field-box">
<!--Add .ak-donate-three-step for three-step-->
<div class="ak-donate-menu ak-donate-three-step-visible">
<label class="ak-donate-step ak-donate-step-1">
<span>Amount</span>
<input type="radio" id="ak-donate-step-1" name="ak-donate-step" value="1" checked="checked">
<div class="ak-step-number">1</div>
</label>
<label class="ak-donate-step ak-donate-step-2">
<span>Name</span>
<input type="radio" id="ak-donate-step-2" name="ak-donate-step" value="2">
<div class="ak-step-number">2</div>
</label>
<label class="ak-donate-step ak-donate-step-3">
<span>Finish</span>
<input type="radio" id="ak-donate-step-3" name="ak-donate-step" value="3">
<div class="ak-step-number">3</div>
</label>
</div>
<div id="ak-donation-details" class="xak-errs-below">
<div id="ak-product-list" class="ak-donate-area-step-1 ak-errs-below">
{% if has_products %}
<table class="ak-margin-bottom-1">
<thead>
<tr>
<th class="ak-product-details-header ak-small-header">Product</th>
<th class="ak-product-amount-header ak-small-header">Price</th>
<th class="ak-product-quantity-header ak-small-header">Quantity</th>
<th class="ak-product-quantity-header ak-small-header">Total</th>
</tr>
</thead>
<tbody>
{% for product in products %}
<tr>
<td class="ak-product-details">
<div class="ak-product-name">{{ product.name }}</div>
{% if product.desc %}<div class="ak-product-description">{{ product.desc }}</div>{% endif %}
</td>
<td class="ak-product-amount">
<span id="product_{{ product.id }}_price" data-price="{{ product.price }}">
{% if product.price == 0 %}
FREE!
{% else %}
<span class="ak-currency-sym">{{ page.currency_sym }}</span>{{ product.price|commify }}
{% endif %}
</span>
</td>
<td class="ak-product-quantity">
{% if product.max == 1 %}
<input type="checkbox" value="1" name="product_{{ product.id }}" id="product_{{ product.id }}" data-product="{{ product.id }}" class="ak_product_inputs">
{% else %}
<input type="number" min="0" max="{{ product.max }}" onvalidate="return validate_product_count(this)" name="product_{{ product.id }}" id="product_{{ product.id }}" size="2" data-product="{{ product.id }}" class="ak_product_inputs">
{% endif %}
</td>
<td class="ak-product-subtotal">
<span class="ak-currency-sym">{{ page.currency_sym }}</span><span class="ak_product_subtotal_{{ product.id }}"></span>
</td>
</tr>
{% endfor %}
</tbody>
</table>
<p class="ak-donation-subtotal ak-align-right">
<label class="ak-small-header">Product Total</label>
<strong><span class="ak-currency-sym">{{ page.currency_sym }}</span></strong>
<span id="ak-donation-subtotal-amount"></span>
</label>
</p>
{% endif %}
</div><!--product-list-->
<div id="ak-candidate-list" class="ak-donate-area-step-1 ak-errs-below">
{% if has_candidates %}
<table>
<thead>
<tr>
<th id="ak-candidate-details-header">Candidate</th>
<th> </th>
<th id="ak-candidate-amount-header">Donation</th>
</tr>
</thead>
<tbody>
{% for candidate in candidates %}
<tr>
<td class="ak-candidate-details">
{% if candidate.portrait_url %}
<img class="ak-candidate-portrait" src="{{ candidate.portrait_url }}">
{% endif %}
</td>
<td class="ak-candidate-name">
<div>{{ candidate.name }}</div>
<p>{{ candidate.desc|safe }}</p>
</td>
<td class="ak-candidate-amount ak-align-right">
<span class="ak-currency-sym">{{ page.currency_sym }}</span><input type="text" name="candidate_{{ candidate.id }}" id="candidate_{{ candidate.id }}" size="2" class="ak_candidate_inputs">
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endif %}
</div>
{% if has_products %}
<h4 class="ak-donate-area-step-1">Donation (Optional)</h4>
{% endif %}
<div id="ak-amount-list" class="ak-err-above ak-donate-area-step-1">
{% if show_currency_select %}
{% comment %}
Only English currency names are currently available from
ActionKit.
When translating your templatesets, you could partly or
entirely translate the list and include that as plain
HTML here, or remove the ' - {{currency.name}}' so only
the ISO abbreviation shows.
{% endcomment %}
<div class="ak-currency">
<label>
<select name="currency">
{% for code in "USD,GBP,CAD,AUD,EUR"|split:"," %}
{% with currency_info|get:code as currency %}
<option value="{{code}}">{{code}} - {{currency.name}}</option>
{% endwith %}
{% endfor %}
<option value="" disabled>──────────</option>
{% for code, currency in currency_info.items %}
<option value="{{code}}">{{code}} - {{currency.name}}</option>
{% endfor %}
</select>
</label>
</div>
{% elif page.derived.use_account_switcher %}
<div id="ak-multi-currency">
<label class="ak-label-above ak-margin-none" for="amount">Secure Donation:</label>
<span class="ak-currencies">
{% for currency, account_name in page.derived.currency_accounts %}
<span class="ak-currency">
<input type="radio" {% if forloop.first %}checked{% endif %} name="payment_account" id="id_currency_{{currency}}" value="{{account_name}}">
<label for="id_currency_{{currency}}">{{currency}}</label>
</span>
{% endfor %}
</span>
</div>
{% endif %}
<div class="ak-amount-wrapper">
{% for row in amounts|columns:3 %}
<ul class="ak-unstyled">
{% for amount in row %}
{% if amount == "other" %}
<li id="ak-other-amount-container">
<noscript><input type="radio" value="" class="ak-amount-radio-button" name="amount"></noscript>
<label for="ak-other-amount-field" class="ak-btn">
<span class="ak-currency-sym">{{ page.currency_sym }}</span> <input type="text" id="ak-other-amount-field" name="amount_other" size="3" >
</label>
</li>
{% else %}
<li>
<label for="id_amount_{{amount}}" class="ak-btn">
<span class="ak-currency-sym"></span><input type="radio" id="id_amount_{{amount}}" value="{{ amount }}" class="ak-amount-radio-button" name="amount" {% if not args.amount_other and amount == default_amount %}checked{% endif %}>{{ page.currency_sym }}{{ amount|commify }}
</label>
</li>
{% endif %}
{% endfor %}
</ul>
{% endfor %}
</div>
</div>
<div id="ak-donation-total-div"></div>
<script type="text/ak-template" for="ak-donation-total-div">
[% if (has_products || has_candidates) { %]
<p class="ak-donation-total ak-donate-area-step-1">
<label for="amount">
Total Amount
</label>
<span class="ak-currency-sym">{{ page.currency_sym }}</span><span class="ak-donation-total-amount"></span>
</p>
[% }
setTimeout(update_total, 0);
%]
</script>
{% if not has_products %}
{% if allow_monthly %}
<div id="ak-recurring-type" class="ak-donate-area-step-1">
<span>
<input type="radio" name="donation_type" id="id_donation_type_single" value="single" checked>
<label for="id_donation_type_single"> One-Time</label>
</span>
<span>
<input type="radio" name="donation_type" id="id_donation_type_recurring" value="recurring">
<label for="id_donation_type_recurring"> Monthly</label>
</span>
</div>
{% else %}
<div id="ak-recurring-type"></div>
<input type="hidden" name="donation_type" value="single">
{% endif %}
{% endif %}
<div id="ak-donation-contact" class="ak-styled-fields ak-donate-area-step-2 ak-errs-below ak-margin-top-1">
<ul id="ak-errors"></ul>
<div style="display: none"><div id="known_user">
Not <span id="known_user_name"></span>? <a href="?" onclick="return actionkit.forms.logOut()">Click here.</a>
</div></div>
<div id="unknown_user"></div>
<h4 class="{% if not has_shippable_products %}ak-donate-three-step-hidden{% endif %}">Billing Address</h4>
<div class="ak-labels-overlaid ak-errs-below test2">
{% if page.accept_ach %}
<div>
<label for="id_first_name">First Name</label>
<input id="id_first_name" type="text" name="first_name">
<input type="hidden" name="required" value="first_name">
</div>
<div>
<label for="id_last_name">Last Name</label>
<input id="id_last_name" type="text" name="last_name">
<input type="hidden" name="required" value="last_name">
</div>
{% else %}
<div>
<label for="id_name">Name</label>
<input id="id_name" type="text" name="name">
</div>
{% endif %}
<div>
<label class="required" for="id_email">Email</label>
<input id="id_email" type="text" name="email">
</div>
{% if has_shippable_products %}
<div>
<label for="id_address1">Billing address line 1</label>
<input id="id_address1" type="text" name="address1">
</div>
<div>
<label for="id_address2">Billing address line 2 (optional)</label>
<input id="id_address2" type="text" name="address2">
</div>
{% else %}
<div>
<label for="id_address1">Billing address</label>
<input id="id_address1" type="text" name="address1">
</div>
<div>
<label for="id_address2">Billing address line 2 (optional)</label>
<input id="id_address2" type="text" name="address2">
</div>
{% endif %}
<div>
<label for="id_city">City</label>
<input id="id_city" type="text" name="city">
</div>
<div class="ak-errs-below">
<div class="ak-us-billing-fields">
<input type="hidden" name="required" value="state">
<label for="id_state">State</label>
{% include "./state_select.html" %}
</div>
<div class="ak-us-billing-fields">
<input type="hidden" name="required" value="zip">
<label for="id_zip">Zip</label>
<input id="id_zip" type="text" name="zip" maxlength="5" size="5">
</div>
</div>
{% if page.allow_international %}
<div class="ak-errs-below" class="ak-intl-billing-fields">
<div>
<label for="id_region">Region</label>
<input id="id_region" type="text" name="region" size="20">
</div>
<div>
<label for="id_postal">Postal Code</label>
<input id="id_postal" type="text" name="postal" size="10">
</div>
</div>
<div>
<label for="id_country">Country</label>
{% include "./country_select.html" %}
</div>
{% include "./privacy.html" %}
{% else %}
<input type="hidden" name="country" value="United States">
{% endif %}
</div> <!-- labels overlaid (billing address) -->
{% if has_candidates %}
<p class="ak-label-above" id="ak-occ-emp-why">
For political donations, we're required to ask for your employer and occupation:
</p>
<div class="ak-labels-overlaid ak-errs-below">
<div>
<label for="action_employer">Employer</label>
<input id="action_employer" type="text" name="action_employer" size="20">
<input type="hidden" name="required" value="action_employer">
</div>
<div>
<label for="action_occupation">Occupation</label>
<input id="action_occupation" type="text" name="action_occupation" size="20">
<input type="hidden" name="required" value="action_occupation">
</div>
</div>
{% endif %}
{% if has_shippable_products %}
<div id="ak-shipping-address">
<h4>Shipping Address</h4>
{% with "shipping_" as input_name_prefix %}
<div class="ak-margin-1">
<label for="ak-shipping-same" class="ak-small">
<input id="ak-shipping-same" type="checkbox" name="shipping_same" value="1" checked>
Ship to billing address
</label>
</div>
<div id="ak-shipping-fields" class="ak-labels-overlaid ak-errs-below" style="display: none">
<div>
<label for="id_shipping_address1">Shipping address line 1</label>
<input id="id_shipping_address1" type="text" name="shipping_address1">
</div>
<div>
<label for="id_shipping_address2">Shipping address line 2 (optional)</label>
<input id="id_shipping_address2" type="text" name="shipping_address2">
</div>
<div>
<label for="id_shipping_city">Shipping city</label>
<input id="id_shipping_city" type="text" name="shipping_city">
</div>
<div class="ak-us-shipping-fields">
<div>
<label for="id_shipping_state">Shipping state</label>
{% include "./state_select.html" %}
</div>
<div>
<label for="id_shipping_zip">Shipping ZIP</label>
<input id="id_shipping_zip" type="text" name="shipping_zip" maxlength="5" size="5">
</div>
</div>
{% if page.allow_international %}
<div class="ak-intl-shipping-fields">
<div>
<label for="id_shipping_region">Shipping region</label>
<input id="id_shipping_region" type="text" name="shipping_region" size="20">
</div>
<div>
<label for="id_shipping_postal">Shipping postal Code</label>
<input id="id_shipping_postal" type="text" name="shipping_postal" size="10">
</div>
</div>
<div>
<label for="id_shipping_country">Shipping country</label>
{% include "./country_select.html" %}
</div>
{% endif %}
</div> <!-- labels overlaid -->
{% endwith %}
</div> <!-- shipping address -->
{% endif %}
</div> <!-- donation contact -->
<div class="ak-labels-above ak-styled-fields ak-donate-area-step-3 ak-errs-below">
<h4>Payment Information</h4>
{% if page.accept_ach %}
<div id="ak-accept-ach-payement">
<div id="ak-fieldbox-payment_method">
<input type="radio" id="ak_payment_method_cc" name="payment_method" value="cc" checked>
<label for="ak_payment_method_cc">Credit Card</label>
<br>
<input type="radio" id="ak_payment_method_ach" name="payment_method" value="ach">
<label for="ak_payment_method_ach">US Bank Transfer</label>
</div>
{% endif %}
<div class="cc_payment_options">
<div id="ak-fieldbox-card_num" class="">
<label for="ak-card_num">Credit Card #</label>
<input type="hidden" name="required" value="card_num" id="ak-card_num-required">
<div id="ak-card_num-hosted" class="hosted-field"></div>
<input id="ak-card_num" type="text" name="card_num">
</div>
<div class="ak-err-below">
<div id="ak-fieldbox-exp_date">
<input type="hidden" name="required" value="exp_date_month" id="ak-exp_date_month-required">
<label for="ak-exp_date_month">Expiration Date</label>
<div id="ak-exp_date-hosted" class="hosted-field"></div>
<select id="ak-exp_date_month" type="text" name="exp_date_month">
<option value="">MM</option>
<option value="01">01</option>
<option value="02">02</option>
<option value="03">03</option>
<option value="04">04</option>
<option value="05">05</option>
<option value="06">06</option>
<option value="07">07</option>
<option value="08">08</option>
<option value="09">09</option>
<option value="10">10</option>
<option value="11">11</option>
<option value="12">12</option>
</select>
<input type="hidden" name="required" value="exp_date_year" id="ak-exp_date_year-required">
<select id="ak-exp_date_year" type="text" name="exp_date_year">
<option value="">YYYY</option>
{% for year in exp_years %}
<option value="{{ year.two }}">{{ year.four }}</option>
{% endfor %}
</select>
</div>
</div>
<div class="ak-err-below">
<div id="ak-fieldbox-card_code">
<input type="hidden" name="required" value="card_code" id="ak-card_code-required">
<label for="ak-card_code">Verification Code</label>
<div id="ak-card_code-hosted" class="hosted-field"></div>
<input id="ak-card_code" type="text" name="card_code" size="4">
</div>
</div>
</div>
{% if page.accept_ach %}
<div class="ach_payment_options">
<div id="ak-fieldbox-ach_method">
<hr>
<h4>US Bank Transfer</h4>
<input type="radio" id="ak_ach_method_account_number" name="ach_method" value="account_number" checked>
<label for="ak_ach_method_account_number">Account Number</label>
<br>
<input type="radio" id="ak_ach_method_bank_login" name="ach_method" value="bank_login">
<label for="ak_ach_method_bank_login">Bank Login</label>
</div>
<div class="account_number_options">
<div class="ak-err-below">
<div id="ak-fieldbox-routing_number">
<label for="ak-routing_number">Routing Number</label>
<input id="ak-routing_number" type="text" name="routing_number" size="9">
</div>
</div>
<div class="ak-err-below">
<div id="ak-fieldbox-bank_account">
<label for="ak-bank_account">Bank Account</label>
<input id="ak-bank_account" type="text" name="bank_account" size="17">
</div>
</div>
<div class="ak-err-below">
<div id="ak-fieldbox-account_type">
<label for="ak-account_type">Account Type</label>
<select id="ak-account_type" type="text" name="account_type">
<option value="checking">checking</option>
<option value="savings">savings</option>
</select>
</div>
</div>
</div>
<div class="ak-err-below">
<div id="ak-fieldbox-ownership_type">
<label for="ak-ownership_type">Ownership Type</label>
<select id="ak-ownership_type" type="text" name="ownership_type">
<option value="personal">personal</option>
<option value="business">business</option>
</select>
</div>
</div>
<div class="ak-err-below">
<div id="ak-fieldbox-business_name">
<label for="ak-business_name">Business Name</label>
<input id="ak-business_name" type="text" name="business_name">
</div>
</div>
<div id="ak-fieldbox-mandate">
<div id="ak-mandate">By clicking "Donate", I authorize Braintree, a service of PayPal, on behalf of <span id="ak-client-name">{% filter ak_text:"org_name" %}{% client_name %}{% endfilter %}</span> (i) to verify my bank account information using bank information and consumer reports and (ii) to debit my bank account.</div>
</div>
</div>
</div>
{% endif %}
</div><!--ak-styled-fields-->
<button class="ak-donate-three-step-visible" id="ak-continue-button" type="button">Continue</button>
{% if page.payment_processor_information.init_submit_disabled %}
{% comment %}
For pages that use Braintree, the submit button will be enabled by javascript.
{% endcomment %}
<button disabled="true" type="submit" class="ak-submit-button ak-donate-area-step-3">Donate <span class="ak-currency-sym">{{ page.currency_sym }}</span><span class="ak-donation-total-amount"></span></button>
<noscript>
<p>
<b>JavaScript is required</b> so this page
can securely submit your donation.
</p>
</noscript>
{% else %}
<button type="submit" class="ak-submit-button ak-donate-area-step-3">Donate <span class="ak-currency-sym">{{ page.currency_sym }}</span><span class="ak-donation-total-amount"></span></button>
{% endif %}
{% if show_paypal %}
<div class="ak-payment-options ak-margin-bottom-1 ak-donate-area-step-2">
<input type="hidden" name="paypal" value="0" id="ak-pay-by-paypal">
Or check out with
<button type="submit" id="ak-paypal-button" class="ak-inline ak-paypal-button"><img src="/media/modern/paypal-logo-1.svg"></button>
</div>
{% endif %}
{% fastaction %}
</div>
</div>
</div>
</div>
</form>
{% endblock %}
{% block script_additions %}
<script language="javascript">
//<!--
function clear_radio_buttons() {
$('input.ak-amount-radio-button').prop('checked', false);
}
function clear_other() {
$('#ak-other-amount-field').val("");
}
function product_info(id) {
var product_element = $("#product_" + id),
quantity = 0,
price = parseFloat($("#product_" + id + "_price").data("price"));
if (product_element.is(':checkbox')) {
if (product_element.is(':checked')) {
quantity = 1;
}
} else if (product_element.val() != "") {
quantity = parseInt(product_element.val());
}
return {
'id': id,
'price': price,
'quantity': quantity,
'subtotal': (price * quantity)
}
}
function update_total() {
var total = 0.0;
product_infos().forEach(function(info) {
total += info.subtotal;
});
$('.ak_candidate_inputs').each(function (i) {
// check that amount is a valid amount
var amount = this.value;
if (amount.length == 0 || ! /^[\d,]*(\.\d{1,2})?$/.test(amount)) {
return;
}
total += parseFloat(amount.replace(',', ''));
});
// look for checked off donation amounts
var amount_checked = $('input:radio[name=amount]:checked').val();
if (amount_checked) {
total += parseFloat(amount_checked);
} else {
// or other amounts
var other = $('#ak-other-amount-field').val();
if (typeof other !== "undefined" &&
other.length && /^[\d,]*(\.\d{1,2})?$/.test(other))
total += parseFloat(other.replace(',', ''));
}
var new_total = total == 0 ? "" : "" + total.toFixed(2);
$('.ak-donation-total-amount').html(new_total);
return total;
}
$(function() {
$('.ak_product_inputs').on('change blur', update_total);
$('.ak_candidate_inputs').on('change blur', update_total);
$('.ak-amount-radio-button').on('change blur', update_total)
.on('click', clear_other)
.on('click', update_total);
$('#ak-other-amount-field').on('change blur', update_total)
.on('click keyup', clear_radio_buttons)
.on('click', update_total);
$('input[type=radio][name=payment_method]').change(function() {
if (this.value == 'ach') {
$('.ach_payment_options').show();
$('.cc_payment_options').hide();
} else {
$('.ach_payment_options').hide();
$('.cc_payment_options').show();
}
});
$('input[type=radio][name=ach_method]').change(function() {
if (this.value == 'account_number') {
$('.account_number_options').show();
} else {
$('.account_number_options').hide();
}
});
$('#ak-ownership_type').change(function() {
if (this.value == 'business') {
$('#ak-fieldbox-business_name').show();
} else {
$('#ak-fieldbox-business_name').hide();
}
});
});
/* Amount buttons */
function highlight_selected_amount_button() {
$('label.ak-radio-checked').removeClass('ak-radio-checked');
$(this).closest('label').addClass('ak-radio-checked');
}
$(function() {
$('input[name="amount"]').on(
'click', highlight_selected_amount_button);
$('input[name="amount_other"]').on(
'click change', highlight_selected_amount_button);
// Make sure label is highlighted if an amount is pre-selected
highlight_selected_amount_button.call(
$('input[name="amount"]:checked').get(0) //||
//$('input[name="amount_other"]').get(0)
);
});
/* Currency symbols */
function redraw_currency_symbol() {
var id = $('input[id^=id_currency_]:checked, option[id^=id_currency_]:selected').attr('id');
var iso_code_match = /([A-Z][A-Z][A-Z])$/.exec(id);
if ( ! iso_code_match ) {
return
}
var iso_code = iso_code_match[1];
var currency_sym = actionkit.utils.currencySymbols[iso_code];
$('.ak-currency-sym').text( currency_sym || '' );
}
$(function() {
$('input[id^=id_currency_], select[name="currency"], select[name="payment_account"]').on('change', redraw_currency_symbol);
redraw_currency_symbol();
});
var address_fields = [
'address1', 'address2', 'city', 'state', 'zip'
{% if page.allow_international %}, 'postal', 'region', 'country'{% endif %}
];
{% if page.allow_international %}
function country_change() {
if ( $('#id_country').val() == 'United States' ) {
$('.ak-us-billing-fields').show();
$('.ak-intl-billing-fields').hide();
} else {
$('.ak-us-billing-fields').hide();
$('.ak-intl-billing-fields').show();
}
sync_to_shipping();
}
function shipping_country_change() {
if ( $('#id_shipping_country').val() == 'United States' ) {
$('.ak-us-shipping-fields').show();
$('.ak-intl-shipping-fields').hide();
} else {
$('.ak-us-shipping-fields').hide();
$('.ak-intl-shipping-fields').show();
}
}
$( function () {
$('#id_country').on('change blur', country_change);
$('#id_shipping_country').on('change blur', shipping_country_change);
country_change();
shipping_country_change();
} );
{% endif %}
function toggle_shipping() {
if ( $('#ak-shipping-same').prop("checked") ) {
sync_to_shipping();
$('#ak-shipping-fields').slideUp();
if($('.ak-shipping-required').length)
$('.ak-shipping-required').remove();
} else {
clear_shipping();
$('#ak-shipping-fields').slideDown();
$('#ak-shipping-fields').append(
"<input type='hidden' name='required' value='shipping_address1' class='ak-shipping-required'>");
$('#ak-shipping-fields').append(
"<input type='hidden' name='required' value='shipping_city' class='ak-shipping-required'>");
$('#ak-shipping-fields').append(
"<input type='hidden' name='required' value='shipping_state' class='ak-shipping-required'>");
$('#ak-shipping-fields').append(
"<input type='hidden' name='required' value='shipping_zip' class='ak-shipping-required'>");
}
}
function clear_shipping(e) {
var i, field, ship_field;
for (i in address_fields) {
field = address_fields[i];
ship_field = $('#id_shipping_' + field);
ship_field.val("").change().prop("readonly", false);
}
{% if page.allow_international %}
shipping_country_change();
{% endif %}
}
function sync_to_shipping(e) {
if ( ! $('#ak-shipping-same').prop("checked") ) {
return;
}
var i, field, ship_field, bill_value;
for (i in address_fields) {
field = address_fields[i];
ship_field = $('#id_shipping_' + field);
bill_value = $('#id_' + field).val();
ship_field.val(bill_value).change().prop("readonly", true);
}
{% if page.allow_international %}
shipping_country_change();
{% endif %}
}
$( function () {
$('#ak-shipping-same').on('change', toggle_shipping);
toggle_shipping();
$('#id_address1, #id_address2, #id_city, #id_state, #id_zip, ' +
'#id_region, #id_postal').on('change blur', sync_to_shipping);
} );
var three_step_initialized = 0;
function three_step_reveal() {
var current_step = $('input[name="ak-donate-step"]:checked').val();
if ( current_step != "2" && current_step != "3" ) {
current_step = "1"
}
var speed = three_step_initialized ? 1 : 400;
if ( current_step == "1" ) {
$('.ak-donate-area-step-2, .ak-donate-area-step-3').hide();
$('.ak-donate-area-step-1, #ak-continue-button').fadeIn( speed );
} else if ( current_step == "2" ) {
$('.ak-donate-area-step-1, .ak-donate-area-step-3').hide();
$('.ak-donate-area-step-2, #ak-continue-button').fadeIn( speed,
focus_field_if_blank( $('#id_name') )
);
} else if ( current_step == "3" ) {
$('.ak-donate-area-step-1, .ak-donate-area-step-2, #ak-continue-button').hide();
$('.ak-donate-area-step-3').fadeIn( speed,
focus_field_if_blank( $('#ak-card_num') )
);
}
}
function focus_field_if_blank ( field_elt ) {
return ( function () {
if ( ! field_elt.val() ) {
field_elt.focus()
}
} )
}
var step_has_errors = false;
function three_step_advance() {
// trigger validation on the step we're leaving
var current_step = $('input[name="ak-donate-step"]:checked').val();
// hitting "back" after donating confuses our step navigation.
// User gets dropped on first step, then browser autocomplete sets our step tracker field without us knowing.
// So, check what step the UI's on, and if step tracker and UI disagree give precedence to the UI.
var currentStepUI = $('div.ak-donate-area-step-1,div.ak-donate-area-step-2,div.ak-donate-area-step-3').filter(':visible');
if(currentStepUI.length){
var uiStepNum = currentStepUI.attr('class')
.match(/ak-donate-area-step-[0-9]/g)[0]
.slice(-1);
if(uiStepNum != current_step){
$('input[name=ak-donate-step][value=' + uiStepNum + ']').prop('checked', true);
current_step = uiStepNum;
}
}
validate_step(current_step);
if (!step_has_errors) {
$('input[name="ak-donate-step"]:checked').closest('label').
next('label').find('input[type="radio"]').prop('checked', true);
three_step_reveal();
}
}
function three_step_goto(next) {
// trigger validation on the step we're leaving
var current_step = $('input[name="ak-donate-step"]:checked').val();
// skip validation if we're going backwards
if (current_step < next) {
validate_step(current_step);
}
// can't skip over a step unless it's already been completed
if ( (! step_has_errors) && (current_step == 1) && (next == 3) ) {
validate_step(2);
if ( step_has_errors ) {
$('#ak-donate-step-2').prop('checked', true);
three_step_reveal();
return;
}
}
// allow the user to go back even if there are errors
if (current_step > next || !step_has_errors) {
$('#ak-donate-step-' + next).prop('checked', true);
three_step_reveal();
}
}
function validate_product_count ( field ) {
var product_count = field.value;
if (product_count == "" || product_count == "0") {
return true
}
product_count = parseInt( product_count );
var product_max = parseInt( $(field).attr('max') );
if ( product_max && product_count > product_max ) {
var err_msg = actionkit.forms.errorMessage('product:max');
err_msg = err_msg.replace("{0}", product_max);
return err_msg
}
return true
}
/* used to limit AK built-in validation to particular fields by step */
var doing_step_validation = false;
var validate_fields = [];
function validate_step(step) {
step_has_errors = false;
if (step == "1") {
validate_fields = ["amount"];
} else if (step == "2") {
validate_fields = ["email", "first_name", "last_name", "name",
"address1", "address2", "city", "state", "zip",
"country", "region", "postal",
"shipping_address1", "shipping_address2",
"shipping_city", "shipping_state",
"shipping_zip", "shipping_country",
"shipping_region", "shipping_postal",
"privacy"
{% if has_candidates %},"action_employer", "action_occupation"{% endif %}];
} else {
validate_fields = ["card_num", "card_code",
"exp_date_year", "exp_date_month", "exp_date"];
}
doing_step_validation = true;
actionkit.forms.validate();
doing_step_validation = false;
if (step == "1") {
step_has_errors = step_1_validation();
}
if (step == "2" && !step_has_errors) {
step_has_errors = step_2_validation();
}
if (step == "3" && !step_has_errors) {
step_has_errors = step_3_validation();
}
}
function do_validate_credit_card() {
if (actionkit.donations && actionkit.donations.skip_cc_validation) {
return false;
}
return true;
}
function step_3_validation() {
var step_has_errors = false;
if (!actionkit.errors) {
actionkit.errors = {};
}
var payment_method = actionkit.form["payment_method"] && actionkit.form["payment_method"].value;
if (payment_method == 'ach') {
if ($('#ak-ownership_type').val() == 'business') {
if (!$('#ak-business_name').val()) {
actionkit.errors['business_name:missing'] = actionkit.forms.errorMessage('business_name:missing');
step_has_errors = true;
}
}
var ach_method = actionkit.form["ach_method"] && actionkit.form["ach_method"].value;
if (ach_method != 'bank_login') {
var bank_account = $('#ak-bank_account').val();
if (!bank_account) {
actionkit.errors['bank_account:missing'] = actionkit.forms.errorMessage('bank_account:missing');
step_has_errors = true;
} else if (!valid_bank_account_number(bank_account)) {
actionkit.errors['bank_account:invalid'] = actionkit.forms.errorMessage('bank_account:invalid');
step_has_errors = true;
}
var routing_number = $('#ak-routing_number').val();
if (!routing_number) {
actionkit.errors['routing_number:missing'] = actionkit.forms.errorMessage('routing_number:missing');
step_has_errors = true;
} else if (!valid_bank_routing_number(routing_number)) {
actionkit.errors['routing_number:invalid'] = actionkit.forms.errorMessage('routing_number:invalid');
step_has_errors = true;
}
}
} else if (actionkit.donations && actionkit.donations.vgs){
actionkit.donations.vgs.validateHostedForm().map(function(error){
actionkit.donations.vgs.handleError(error);
step_has_errors = true;
});
} else {
if (!do_validate_credit_card()) {
return step_has_errors;
}
if (!valid_credit_card($('#ak-card_num').val())) {
actionkit.errors['card_num:invalid'] = actionkit.forms.errorMessage('card_num:invalid');
step_has_errors = true;
}
if (!valid_credit_card_code($('#ak-card_code').val())) {
actionkit.errors['card_code:invalid'] = actionkit.forms.errorMessage('card_code:invalid');
step_has_errors = true;
}
}
if (step_has_errors) {
actionkit.forms.onValidationErrors(actionkit.errors);
}
return step_has_errors;
}
function step_2_validation() {
var step_has_errors = false;
if (!valid_email($('#id_email').val())) {
if (!actionkit.errors)
actionkit.errors = {};
actionkit.errors['email:invalid'] = actionkit.forms.errorMessage('email:invalid');
actionkit.forms.onValidationErrors(actionkit.errors);
step_has_errors = true;
}
return step_has_errors;
}
function step_1_validation() {
var step_has_errors = false;
// look for product selections
var selected_products = false;
product_infos().forEach(function(info) {
if (info.quantity) {
selected_products = true;
}
});
// look for candidate selections
var selected_candidates = false;
$('.ak_candidate_inputs').each(
function(i) {
if ($(this).val() != "")
selected_candidates = true;
});
// there's no built-in validation for amounts, so do it here
if (!selected_products && !selected_candidates &&
!$('.ak-amount-radio-button').is(':checked') &&
$('#ak-other-amount-field').val() == "") {
if (!actionkit.errors)
actionkit.errors = {};
actionkit.errors['amount:missing'] = actionkit.forms.errorMessage('amount:missing');
actionkit.forms.onValidationErrors(actionkit.errors);
step_has_errors = true;
} else if (($('#ak-other-amount-field').val() != "" &&
$('#ak-other-amount-field').val() != undefined) &&
!/^[\d,]*(\.\d{1,2})?$/.test($('#ak-other-amount-field').val())) {
if (!actionkit.errors)
actionkit.errors = {};
actionkit.errors['amount:invalid'] = actionkit.forms.errorMessage('amount:invalid');
actionkit.forms.onValidationErrors(actionkit.errors);
step_has_errors = true;
}
{% if page.minimum_amount %}
var total = update_total();
if (!step_has_errors && total < {{ page.minimum_amount }}) {
if (!actionkit.errors) {
actionkit.errors = {};
}
err = actionkit.forms.errorMessage('amount:minimum');
err = err.replace("{0}", "{{ page.minimum_amount }}");
actionkit.errors['amount:minimum'] = err;
actionkit.forms.onValidationErrors(actionkit.errors);
step_has_errors = true;
}
{% endif %}
return step_has_errors;
}
function actionkitValidationErrors(errors, field) {
// only want this running during step validation
if (!doing_step_validation) {
return;
}
// trim out validation errors we don't care about on this step
var to_delete = [];
step_has_errors = false;
for (var key in errors) {
parts = key.split(':');
if (validate_fields.indexOf(parts[0]) == -1) {
to_delete.push(key);
} else {
step_has_errors = true;
}
}
for (var i = 0; i < to_delete.length; i++) {
delete errors[to_delete[i]];
}
}
function three_step_initialize() {
if (actionkit.errors) {
var has_errors = [];
if ($('.ak-donate-area-step-1').find('.ak-err').length) {
has_errors.push($('.ak-donate-area-step-1'));
}
if ($('.ak-donate-area-step-2').find('.ak-err').length) {
has_errors.push($('.ak-donate-area-step-2'));
}
if ($('.ak-donate-area-step-3').find('.ak-err').length) {
has_errors.push($('.ak-donate-area-step-3'));
}
if (has_errors.length == 1) {
// just one pane with errors? show it
has_errors[0].show();
} else {
// otherwise show all steps
$('.ak-donate-area-step-1, .ak-donate-area-step-2, .ak-donate-area-step-3').show();
$('#ak-continue-button, .ak-donate-three-step-visible').hide();
}
}
three_step_initialized = 1;
}
$(function() {
// three-step vs. one-step UI
if ( $('form.ak-donate-three-step').length == 0 ) {
$('.ak-donate-three-step-visible').hide();
} else {
$('.ak-donate-three-step-hidden').hide();
three_step_reveal();
window.actionkitFormReady = three_step_initialize;
// $('.ak-donate-menu input[type="radio"]').on('change', three_step_reveal);
$('#ak-continue-button').on('click', function (evt) {
// letting this event go will trigger our onsubmit and lead to validation woe
evt.preventDefault();
three_step_advance();
});
$('.ak-donate-step-1').on('click', function (evt) {
evt.preventDefault();
three_step_goto('1');
});
$('.ak-donate-step-2').on('click', function (evt) {
evt.preventDefault();
three_step_goto('2');
});
$('.ak-donate-step-3').on('click', function (evt) {
evt.preventDefault();
three_step_goto('3');
});
}
});
function product_ids() {
return $("[data-product]").map(function(i, el) {
return $(el).data("product");
}).toArray();
}
function product_infos() {
return product_ids().map(function(id) {
return product_info(id);
});
}
// calculate subtotals if products exist
function calculate_product_subtotals() {
var subtotal = 0;
product_infos().forEach(function(info) {
$('.ak_product_subtotal_' + info.id).text(info.subtotal.toFixed(2));
subtotal += info.subtotal;
});
$('#ak-donation-subtotal-amount').text(subtotal.toFixed(2));
}
$(function() {
calculate_product_subtotals();
$('.ak_product_inputs').on('change', function() {
calculate_product_subtotals();
});
});
// Standard luhn check to detect mistyped credit card numbers
// from https://gist.github.com/DiegoSalazar/4075533
function valid_credit_card(value) {
if (/[^0-9-\s]/.test(value)) {
return false;
}
var nCheck = 0, nDigit = 0, bEven = false;
value = value.replace(/\D/g, "");
for (var n = value.length - 1; n >= 0; n--) {
var cDigit = value.charAt(n),
nDigit = parseInt(cDigit, 10);
if (bEven) {
if ((nDigit *= 2) > 9) {
nDigit -= 9;
}
}
nCheck += nDigit;
bEven = !bEven;
}
return (nCheck % 10) == 0;
}
function valid_credit_card_code(value) {
if (/[^0-9-\s]/.test(value)) {
return false;
}
value = value.replace(/\D/g, "");
if (value.length == 3 || value.length == 4) {
return true;
}
return false;
}
function valid_bank_account_number(value) {
return /^\d{4,17}$/.test(value);
}
function valid_bank_routing_number(value) {
value = value.replace(/\D/g,'');
if (value.length != 9) { return false; }
var checksum = 0;
for (var i = 0; i < value.length; i += 3) {
checksum += parseInt(value.charAt(i), 10) * 3
+ parseInt(value.charAt(i + 1), 10) * 7
+ parseInt(value.charAt(i + 2), 10);
}
if (checksum == 0 || checksum % 10 != 0) { return false; }
return true;
}
// not 100% the same as Django but pretty close
var email_regExp = /^\s*((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\s*$/i;
function valid_email(email) {
return email_regExp.test(email);
}
function submit_paypal() {
{% if page.paypal_user_requirements != "none" %}
{% if page.paypal_user_requirements == "email" %}
validate_fields = ["email", "privacy"];
{% else %}
validate_fields = [
"email", "first_name", "last_name", "name",
"address1", "address2", "city", "state", "zip",
"country", "region", "postal",
"shipping_address1", "shipping_address2",
"shipping_city", "shipping_state",
"shipping_zip", "shipping_country",
"shipping_region", "shipping_postal", "privacy"
{% if has_candidates %},"action_employer", "action_occupation"{% endif %}
];
{% endif %}
doing_step_validation = true;
actionkit.forms.validate();
doing_step_validation = false;
if (!$.isEmptyObject(actionkit.errors)) {
return false;
}
{% endif %}
/* set the paypal=1 hidden field */
$('#ak-pay-by-paypal').val(1);
/* clear out CC info if entered */
$('#ak-card_num').val('');
$('#ak-card_code').val('');
/* disable CC requirements */
$('#ak-card_num-required').remove();
$('#ak-card_code-required').remove();
$('#ak-exp_date_month-required').remove();
$('#ak-exp_date_year-required').remove();
/* and keep submitting */
return true;
}
function submit_cc() {
/* clear paypal=1 hidden field, only needed if someone hit back */
$('#ak-pay-by-paypal').val(0);
if ($('button.ak-submit-button').hasClass('is-submitted')) {
return false
}
if ( $('form.ak-donate-three-step').length > 0 ) {
validate_step("3");
if (step_has_errors) {
return false;
} else {
$('button.ak-submit-button').addClass('is-submitted');
return true;
}
}
/* not doing 3-step, so we need to do all the validation here,
* don't want to short-circuit and only run one step, better
* to run all three even if all three have errors */
actionkit.forms.validate();
results = [step_1_validation(),
step_2_validation(),
step_3_validation()];
var ok = !(results[0] || results[1] || results[2]);
if (ok) {
$('button.ak-submit-button').addClass('is-submitted');
}
return ok
}
$( function () {
$('#ak-paypal-button').on('click', submit_paypal);
$('.ak-submit-button').on('click', submit_cc);
$(window).on('pagehide', function() {
$('button.ak-submit-button').removeClass('is-submitted');
});
{% if page.paypal_user_requirements == "none" %}
$('#ak-paypal-button').on('mousedown', function () {
var form_elt = $(this).closest('form');
var required_fields = form_elt.find('input[name="required"]');
if ( required_fields.length ) {
required_fields.remove();
$('body').on('mouseup', function ( event ) {
form_elt.append( required_fields );
$( this ).unbind( event );
} );
}
} );
{% endif %}
} );
//-->
</script>
{% with page.payment_processor_information as pp %}
{% if pp.use_accept %}
<script src="/resources/ak_authnet_accept.js"></script>
{% authnet_js_libs %}
<script>
$(function() {
var form = document.querySelector("#act"),
options = {
form: form,
submit: form.querySelector(".ak-submit-button")
};
actionkit.authnet.initClient('{{ pp.login }}', '{{ pp.public_key }}', options);
});
</script>
{% endif %}
{% if pp.use_vzero or pp.use_vgs %}
<style type="text/css">
.hosted-field {
height: 2.375em;
padding: 7px 7px;
margin-bottom: 6px;
background-color: white;
border: 1px solid #ccc;
}
</style>
{% endif %}
{% if pp.use_vzero %}
<style type="text/css">
.hosted-field.braintree-hosted-fields-invalid {
border-color: {{ templateset.custom_fields.color_error|default:"#d00" }};
background-color: #FFC8C8;
}
</style>
{% braintree_js_libs %}
<script src="/resources/ak_braintree_vzero.js"></script>
<script>
$(function() {
var form = document.querySelector("#act"),
options = {
form: form,
fields: {
number: {
selector: '#ak-card_num-hosted'
},
cvv: {
selector: '#ak-card_code-hosted'
},
expirationDate: {
selector: '#ak-exp_date-hosted',
placeholder: 'MM / YYYY'
}
},
styles: {
'input': {
'font-family': '{{ templateset.custom_fields.font_family|default:"sans-serif"|safe }}',
'font-size': '{{ templateset.custom_fields.font_size|default:"16.5px" }}',
'color': '#4b4b4b'
},
'input.invalid': {
'color': '{{templateset.custom_fields.color_error|default:"#d00" }}',
'background-color': '#FFC8C8'
},
'input.valid': {
'color': 'green'
}
},
submitOnEmpty: function() {
return $('#ak-pay-by-paypal').val() == 1;
},
submit: form.querySelector(".ak-submit-button"),
{% if page.accept_ach %}ach: true,{% endif %}
{% if page.use_3d_secure %}use_3d_secure: true,{% endif %}
},
toRemove = ["#ak-card_num", "#ak-card_code", "#ak-exp_date_month",
"#ak-exp_date_year", "#ak-card_num-required",
"#ak-card_code-required", "#ak-exp_date_month-required",
"#ak-exp_date_year-required"];
toRemove.forEach(function(el) {
$(el).remove();
});
actionkit.donations.handleError = function(err) {
if (window.console) {
window.console.log(err);
}
if (!actionkit.errors) {
actionkit.errors = {};
}
switch (err.code) {
case 'HOSTED_FIELDS_FIELDS_EMPTY':
actionkit.errors['card_num:invalid'] = "Credit card fields are empty.";
break;
case 'HOSTED_FIELDS_FIELDS_INVALID':
err.details.invalidFieldKeys.forEach(function(key) {
var map = {
'number': 'card_num',
'cvv': 'card_code',
'expirationDate': 'card_exp'
};
actionkit.errors[map[key] + ':invalid'] = "This field is invalid.";;
});
break;
case 'HOSTED_FIELDS_FAILED_TOKENIZATION':
actionkit.errors['card_num:invalid'] = "Please check that your credit card is valid.";
break;
case 'HOSTED_FIELDS_TOKENIZATION_NETWORK_ERROR':
actionkit.errors['card_num:invalid'] = "Network error.";
break;
default:
actionkit.errors['card_num:invalid'] = "An error occurred: " + err.message;
}
$("button.ak-submit-button").removeClass("is-submitted");
actionkit.forms.onValidationErrors(actionkit.errors);
};
let braintreeInitialized = false;
function initFromContext() {
if (!braintreeInitialized) {
actionkit.donations.initClient(actionkit.context.client_token, options);
braintreeInitialized = true;
}
}
$(actionkit.form).on("actionkit.ready", initFromContext);
if (actionkit.context) {
initFromContext();
}
{% if page.use_3d_secure and page.use_account_switcher %}
function reloadWithFormData() {
if (actionkit.forms.prefilling) {
return;
}
let qs = new URLSearchParams(window.location.search),
fd = new FormData(actionkit.form),
skipKeys = {"device_data": 1, "page": 1, "url": 1};
for (let key of fd.keys()) {
if (key in skipKeys) {
continue;
}
let val = fd.get(key);
if (val) {
qs.set(key, val);
} else if (qs.has(key)) {
qs.delete(key);
}
}
qs.set("prefill", "1");
window.location.search = qs.toString();
}
$(":input[name=payment_account]").bind("change", reloadWithFormData);
{% endif %}
// read by 3-step validation
actionkit.donations.skip_cc_validation = true;
actionkit.donations.vzero = true;
});
</script>
{% endif %}
{% if pp.use_vgs %}
<style>
.hosted-field iframe {
width: 100%;
height: 100%;
}
</style>
<script type="text/javascript" src="https://js.verygoodvault.com/vgs-collect/2.8/vgs-collect.js"></script>
<script src="/resources/ak_vgs.js"></script>
<script>
var vgs = {
token: '{{ pp.client_token }}',
environment: '{{ pp.vgs_environment }}',
submitOnEmpty: function() { return $('#ak-pay-by-paypal').val() == 1; },
rawFieldSelectors: ["#ak-card_num", "#ak-card_code", "#ak-exp_date-hosted"],
fields: [{ "selector": "#ak-card_num-hosted", "name": "card_num", "type": "card-number", "placeholder": "",
"validations": ["required", "validCardNumberExtended"], "autoComplete": "cc-number",
"color": "black", "successColor": "green", "errorColor": "#d00", "fontSize": "15.5px"},
{"selector": "#ak-card_code-hosted", "name": "card_code", "type": "card-security-code", "placeholder": "",
"validations": ["required", "validCardSecurityCode"], "color": "black",
"successColor": "green", "fontSize": "15.5px", "errorColor": "#d00"}]};
{% if pp.supports_oneclick %}
$(function(){
vgs.form = actionkit.form;
var fastActionOptions = {
spinnerReplaces: '.ak-field-box', // element temporarily replaced by spinner
ccSavePlacement: { before: '.ak-submit-button' },
badgePlacement: { before: '.ak-field-box' }, // or after, container
// requireComplianceFields: 1, // require employer and occupation
vgs: vgs
};
var faForm = new actionkit.forms.fastaction.form(actionkit, fastActionOptions);
faForm.init()
.then(faForm.processOneclick)
.always(function(){
if(faForm.mode == 'interactive'){ // interactive or oneclick failed
faForm.renderInteractive();
}
})
});
{% else %}
$(function(){
vgs.form = actionkit.form;
actionkit.donations.vgs.initClient(vgs);
});
{% endif %}
</script>
{% endif %}
{% endwith %}
{% endblock %}
{% block below_form %}
{% if page.payment_processor_information.is_quickdonate %}
{% load_quickdonate %}
{% endif %}
{{ block.super }}
{% endblock %}
Event Attend¶
Attendee sign up page including error messages.
{% extends "./wrapper.html" %}
{% block css_additions %}
<link href="/resources/leaflet/leaflet.css" rel="stylesheet" type="text/css">
<style type="text/css">
#ak-map {
height: 250px;
}
.ak-marker {
width: 10px;
position: relative;
top: 4px;
}
.ak-larger-text {
text-decoration: none;
font-size: 14px;
}
</style>
{% endblock %}
{% block script_additions %}
<script type="text/javascript" src="/resources/leaflet/leaflet.js"></script>
<script type="text/javascript">
$( function () {
var have_events = $('#id_have_events').val();
if ( ! have_events ) {
var args = actionkit.utils.getArgs();
actionkit.forms.eventSearch(null, {
event_id: args.event_id,
zip: args.zip,
page: $('#id_page').val()
});
}
});
$(window).on('load', function (){
/*Add map*/
var map = L.map('ak-map').setView([ {{ event.latitude }}, {{ event.longitude }} ], 10);
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'
}).addTo(map);
var myIcon = L.icon({
iconUrl: '/media/modern/blue_marker.png',
iconSize: [30, 50]
});
L.marker([{{ event.latitude }}, {{ event.longitude }}], {icon: myIcon}).addTo(map);
});
</script>
{% endblock %}
{% block content %}
<form id="id_act" class="ak-form ak-styled-fields" name="act" method="POST" action="{% if update %}/update_action/{% else %}/act/{% endif %}" accept-charset="utf-8">
<input type="hidden" name="page" id="id_page" value="{{ page.name }}">
<input type="hidden" name="event_id" value="{{ args.event_id }}">
{% if event.is_open_for_signup or update or allow_ended %}
<div class="ak-grid-row">
<div class="ak-grid-col ak-grid-col-12-of-12">
{% if not update %}
<h2>{{ page.title }}</h2>
{% else %}
<h2>Update Signup Information</h2>
{% endif %}
</div>
</div>
<div class="ak-grid-row ak-grid-row-inverted">
{% if page.custom_fields.featured_image %}
<div class="ak-grid-col ak-grid-col-3-of-12">
<img class="ak-featured-img" src="{{page.custom_fields.featured_image}}">
</div>
{% endif %}
<div class="ak-grid-col {% if page.custom_fields.featured_image %}ak-grid-col-9-of-12{% else %}ak-grid-col-12-of-12{% endif %}">
{% if not update and form.signup_text %}
<div class="ak-page-content">
{% include_tmpl form.signup_text %}
</div>
{% endif %}
{% if not update %}
<p>
There
{% if other_open_events == 1 %}is{% else %}are{% endif %}
<strong>
{{ other_open_events }}
{% if event.is_open_for_signup %}other{% endif %}
event{{ other_open_events|pluralize }}
</strong>
open for signup{% if is_in_past or is_full %} ({% if is_full %}
plus <strong>{{ is_full|length }}</strong> full{% endif %}{% if is_in_past and is_full %}, {% endif %}
{% if is_in_past and not is_full %} plus {% endif %}
{% if is_in_past %}<strong>{{ is_in_past|length }}</strong> ended{% endif %}){% endif %}.
{% if other_open_events > 0 %}
<a href="/event/{{ search_campaign.local_name }}/?akid={{args.akid}}&zip={{args.zip}}">Search for another event</a>.
{% endif %}
</p>
{% endif %}
</div>
</div>
<div class="ak-grid-row">
<div class="ak-grid-col ak-grid-col-6-of-12 ak-margin-top-1">
<div id="event-search-results">
<!-- If you're embedding this page on your own site, remove everything from here... -->
{% with 1 as hide_map %}
{% include "./event_search_results.html" %}
{% endwith %}
<!-- ...to here -->
</div>
{% if event.search_show_map %}
<!--<img src="http://maps.google.com/maps/api/staticmap?sensor=false&size=500x300&markers={{ event.address1|urlencode }}, {{ event.city_etc|urlencode }}">-->
{% if not event.is_virtual %}
<h5><a href="https://www.google.com/maps/place/{{ event.address1|urlencode }},%20{{ event.city_etc|urlencode }}" target="_blank" class="ak-larger-text"><small><img src="/media/modern/blue_marker.png" class="ak-marker"/> Click to see larger</a></small></h5>
{% endif %}
<div id="ak-map"></div>
<p class="caption">
{% if event.is_virtual %}
Sign up to get event updates and more.
{% else %}
Sign up to get driving directions and more.
{% endif %}
</p>
{% endif %}
<ul class="compact" id="ak-errors"></ul>
</div>
<div class="ak-grid-col ak-grid-col-6-of-12">
<h3>RSVP to attend this event</h3>
<div id="event-attend-form" class="{{templateset.custom_fields.field_errors_class|default:"ak-errs-below"}}">
<div class="{{templateset.custom_fields.field_labels_class|default:"ak-labels-overlaid"}}">
{% if not update %}
{% include "./user_form_wrapper.html" %}
{% else %}
<div id="user-info">
{% include "./user_form_wrapper.html" %}
<script type="text/javascript">
$('#user-info input[name=email]').attr('disabled','disabled');
</script>
<!-- If they want to "update email", they should do a new signup instead. -->
<p>Need to sign up with another email address? <a href="?" onclick="window.actionkit.args = {}; return actionkit.forms.logOut()">Click here.</a></p>
</div>
{% endif %}
</div>
{% if form.ground_rules|is_nonblank and not update %}
<div style="margin: 10px 0">
<input id="id_event_signup_ground_rules" type="checkbox" name="event_signup_ground_rules" value="1">
<label class="ak-checkbox-label" for="id_event_signup_ground_rules">
<strong>Required:</strong>
I agree to <a href="#" onclick="$('#id_ground_rules_text').show(); $(this).before(this.innerHTML + ' (below)').hide(); return false;">the rules</a> for signing up for an event.
</label>
</div>
<blockquote id="id_ground_rules_text" class="nojs">
<div class="strong">Event ground rules:</div>
{% include_tmpl form.ground_rules %}
</blockquote>
{% else %}
<input type="hidden" name="event_signup_ground_rules" value="1">
{% endif %}
<div>
<button type="submit" class="ak-submit-button">{% if update %}Update signup{% else %}Sign up for event{% endif %}</button>
</div>
</div>
</div>
</div>
{% else %}
<div class="ak-grid-row">
<div class="ak-grid-col ak-grid-col-12-of-12">
{% if event.is_inactive or event.is_full or event.is_in_past or event.is_awaiting_confirmation %}
{% if event.is_inactive %}
<h2>Sorry, this event was cancelled.</h2>
{% endif %}
{% if event.is_full %}
<h2>Sorry, this event is full.</h2>
{% endif %}
{% if event.is_in_past %}
<h2>Sorry, it's too late to sign up for this event.</h2>
{% endif %}
{% if event.is_awaiting_confirmation %}
<h2>Sorry, the event host has not yet confirmed this event.</h2>
{% endif %}
{% else %}
<h2>Sorry, this event isn't available for signup.</h2>
{% endif %}
<div>
<a href="/event/{{ search_campaign.local_name }}/?akid={{args.akid}}&zip={{args.zip}}">Search for another event</a>.
</div>
<p>
There are <strong>{{ open_events|length }}</strong> events open for signup{% if is_in_past or is_full %}({% if is_full %} plus <strong>{{ is_full|length }}</strong> full{% endif %}{% if is_in_past and is_full %}, {% endif %}{% if is_in_past and not is_full %} plus {% endif %}{% if is_in_past %}<strong>{{ is_in_past|length }}</strong> ended{% endif %}){% endif %}.
</p>
<hr />
<p>If you already signed up to attend the event, here are the event details:</p>
{% include "./event_attendee_details.html" %}
</div>
</div><!--grid-row-->
{% endif %}
</form>
{% endblock %}
Event Attendee Details¶
Event details including message from host (optional) for display on the event_attendee_tools.html page
{% filter collapse_spaces %}
<div class="ak-field-box">
{% if campaign.use_title and campaign.show_title and event.title %}
<p class="ak-event-title"><a href="/event/{{ campaign.local_name }}/{{event.id}}/signup/?akid={{args.akid}}&zip={{args.zip}}">{{ event.title }}</a></p>
{% endif %}
{% if event.venue %}
<span class="ak-event-venue">{{ event.venue }}</span>
{% endif %}
{% if event.attendee_show_address1 %}
<div class="ak-event-address1">{{ event.address1 }}</div>
{% endif %}
<div class="ak-event-city-etc">{{ event.attendee_general_location }}</div>
<table class="ak-event-table">
{% if event.get_starts_at_display %}
<tr class="ak-event-time">
<th>When:</th>
<td>
{{ event.get_starts_at_display }}
{% if event.show_timezone %}{{ event.local_timezone|timezone_display }}{% endif %}
{% if event.is_in_past %}
<span class="ak-error ak-event-over-notice">
(event is now over)
</span>
{% endif %}
</td>
</tr>
{% endif %}
{% if event.directions %}
<tr class="ak-event-directions">
<th>
{% if event.is_virtual %}
To connect:
{% else %}
Directions to event:
{% endif %}
</th>
<td style="word-break: break-word; hyphens: auto">{{ event.directions|urlize }}</td>
</tr>
{% endif %}
{% if event.note_to_attendees %}
<tr class="ak-event-note-to-attendees">
<th>Your host says:</th>
<td>{{ event.note_to_attendees|linebreaksbr }}</td>
</tr>
{% endif %}
</table>
{% if event.public_description %}
<p class="ak-event-description">{{ event.public_description|linebreaksbr }}</p>
{% endif %}
</div>
{% endfilter %}
Event Attendee Tell-a-Friend Message¶
TAF message you entered in step 3 when you created the attendee sign up page.
Subject: Hope you can come!
{% with action.event as event %}
Hi,
{% filter single_line %}
I'm attending an event as part of {% client_name %}'s
"{{ event.campaign.local_title }}" campaign. It's
{% if event.mode == "onsite" %}at {{ event.address1 }} {% if event.venue %}({{ event.venue }}){% endif %}{% else %}{% if event.venue %}on {{ event.venue }}{% else %}online{% endif %}{% endif %}
{% if event.mode != "global" %}in {% if event.search_show_map %}{{ event.city }}, {% endif %}{{ event.region }}{% endif %}
on {{ event.starts_at|date:"l, F j" }} at {{ event.starts_at|date:"f A" }}{% if event.show_timezone %} {{ event.local_timezone|timezone_display }}{% endif %}.
{% endfilter %}
RSVP here to join me:
{% client_domain_url %}event/{{ event.campaign.name }}/{{ event.id }}/?source=taf
Thanks,
{{ action.user.first_name }}
{% endwith %}
{% comment %}
[Campaigners: the default host tell-a-friend message comes from
event_taf_msg_host.txt in the templateset.]
{% endcomment %}
Event Attendee Tools¶
Attendee tools page layout and code.
{% extends "./wrapper.html" %}
{% block content %}
{% if signup and not event.is_inactive %}
<!-- Title -->
<!-- Sidebar -->
<div class="ak-grid-row">
<div class="ak-grid-col ak-grid-col-12-of-12">
{% if campaign.use_title %}
<h2>Event: {{ event.title }}</h2>
{% else %}
<h2>Event: {{ campaign.local_title }}</h2>
{% endif %}
{% if campaign.use_title %}
<h3>{{ campaign.local_title }}</h3>
{% endif %}
<!-- Message from mothership -->
<div id="attendee-tools-intro">
{% include_tmpl form.tools_text %}
</div>
</div><!--col-12-->
</div><!--ak-grid-row-->
<div class="ak-grid-row">
<div class="ak-grid-col ak-grid-col-6-of-12">
<div id="event-attendee-details">
{% include "./event_attendee_details.html" %}
</div>
{% if event.attendee_show_map %}
<div class="event-attendee-sidebar">
<div id="map">
<iframe src="https://www.google.com/maps/embed/v1/place?q={{ event.address1|urlencode }},+{{ event.city_etc|urlencode }}&key=AIzaSyCqC-M0AKpFkQtigs-Eda4M4yvC0Xu8fKY" frameborder="0" style="border:0" width="100%" height="300"></iframe>
<form class="directions-form ak-styled-fields" action="http://maps.google.com/maps/" method="get">
<input size="26" type="text" name="saddr" placeholder="Enter your street address">
<input type="hidden" name="daddr" value="{{ event.address1 }}, {{ event.city_etc }}">
<button type="submit" class="ak-pull-right">Get Directions</button>
</form>
</div>
</div>
{% endif %}
</div><!--col-6-->
<div class="ak-grid-col ak-grid-col-6-of-12">
<ul id="event-attendee-links" class="ak-links-menu">
{% include_tmpl form.tools_sidebar %}
<li><a href="{% url 'cancel_signup' event.local_campaign.create_page.name event.id %}">Cancel signup</a></li>
<li class="narrower">
| <a href="#" onclick="$('div.contact-form').slideDown('slow'); $(this).parent('li.narrower').hide();">Email host</a>
</li>
</ul>
{% include "./event_contact.html" %}
{% if event.is_open_for_signup %}
{% include "./event_invite.html" %}
{% endif %}
</div>
</div>
{% else %}
{% if event.is_inactive %}
<h2>Sorry, this event has been cancelled.</h2>
{% endif %}
{% if not signup %}
{% comment %}
This message also shows if you were removed by the host.
{% endcomment %}
{% if args.cancel_success %}
<h2>Your signup was cancelled successfully.</h2>
{% else %}
<h2>You aren't currently signed up for this event.</h2>
<p>If you think this is a mistake, check that you cut-and-pasted the entire link to this page.</p>
{% endif %}
{% endif %}
<div>
<a href="/event/{{ campaign.local_name }}/?akid={{args.akid}}&zip={{args.zip}}">Search for another event</a>
</div>
{% endif %}
{% endblock %}
{% block below_form %}
<script type="text/javascript">
actionkit.forms.contextRoot = '/context/';
actionkit.forms.initTafForm('taf');
</script>
{% endblock %}
Event Chooser¶
Screen that displays if a host or attendee has multiple events within an event campaign.
{% extends "./wrapper.html" %}
{% block content %}
{% if signups.count == 0 %}
<div class="ak-grid-row">
<div class="ak-grid-col ak-grid-col-12-of-12">
<h2>You aren't signed up for any events</h2>
</div>
</div>
<div class="ak-grid-row">
<div class="ak-grid-col ak-grid-col-12-of-12">
<div><a href="/event/{{ campaign.local_name }}/">Search for an event here</a></div>
</div>
</div>
{% else %}
<div class="ak-grid-row">
<div class="ak-grid-col ak-grid-col-12-of-12">
<h2>Please choose an event below.</h2>
</div>
</div>
<div class="ak-grid-row">
<div class="ak-grid-col ak-grid-col-12-of-12">
<ul>
{% for signup in signups %}
<li>
<a href="{{ signup.url }}{% if signup.role == 'host' and request.GET.i %}&i={{ request.GET.i|urlencode }}&l=1{% endif %}">{{ signup.event.title }} — {{ signup.event.get_starts_at_display }}</a>
{% if signup.role == 'host' %}
(you are hosting)
{% endif %}
</li>
{% endfor %}
</ul>
</div>
</div>
{% endif %}
{% endblock %}
Event Contact¶
Form that displays if hosts select the option to email attendees or if attendees select the option to email hosts from their tools.
<a name="contact{% if to %}-{{to}}{% endif %}"></a>
<div class="ak-nodisplay-if-js contact-form contact{% if to %}-{{to}}{% endif %} ak-field-box ak-margin-1">
<h3>Email {% if to == 'attendees' %}attendee{% else %}Host{% endif %}(s)</h3>
{% if need_form != 'no' %}
<form name="contact{% if to %}-{{to}}{% endif %}" method="post" action="/event/{{ campaign.local_name }}/{{ event.id }}/contact/" accept-charset="utf-8">
<input type="hidden" name="page" value="{{ page.name }}">
<input type="hidden" name="akid" value="{{ args.akid }}">
<input type="hidden" name="form_name" value="contact{% if to %}-{{to}}{% endif %}">
<ul id="ak-errors"></ul>
<div id="ak-confirmation">
Sent! If you like, you can send more messages below.
</div>
{% endif %}
<div class="ak-styled-fields {{templateset.custom_fields.field_errors_class|default:"ak-errs-below"}}">
<table class="ak-message-form">
<tr class="ak-event-contact-headers">
<th>
<label>From</label>
</th>
<td class="ak-readonly-value">
You (<span class="header-from header-val">{{ user.name }}</span>)
</td>
</tr>
<tr class="ak-event-contact-headers">
<th>
<label>To</label>
</th>
<td class="ak-readonly-value">
<span class="header-to header-val">
{% if signup.role == 'attendee' %}
Your event host
{% else %}
<span class="if-js to-count">{{signups|length}}</span>
{% if to == 'attendees' %}attendee{% else %}{% if to == 'cohosts' %}co-{% endif %}host{% endif %}{% if signups|length > 1 %}(s){% endif %}
{% endif %}
</span>
</td>
</tr>
{% if to in 'attendees|cohosts' %}
<tr class="event-contact-subject">
<th>
<label>Subject*</label>
</th>
<td>
<input type="text" name="subject" class="ak-full-width" value="Message from your "{{ event.title|default:campaign.local_title }}" {% if user_is_moderator %}moderator{% else %}{% if to == 'cohosts'%}co-{% endif %}host{% endif %}">
</td>
</tr>
{% endif %}
<tr class="event-contact-body">
<th>
<label>Your Message*</label>
</th>
<td>
<textarea name="body"></textarea>
</td>
</tr>
</table>
<div class="ak-align-right">
<input name="send_email" value="Send" type="submit" class="ak-btn-short">
<input type="submit" name="cancel" value="Cancel" onclick="window.location.reload(); return false;" class="ak-btn-short">
</div>
</div>
{% if need_form != 'no' %}
<input type="hidden" name="required" value="body">
</form>
{% endif %}
</div>
Event Create¶
Event creation page. Hosts enter the event details based on the criteria you select when you create the event campaign.
{% extends "./wrapper.html" %}
{% block content %}
<form class="ak-form norecognize" name="act" method="POST" action="{% if update %}/update_action/{% else %}/act/{% endif %}" accept-charset="utf-8">
{% csrf_token %}
<input type="hidden" name="page" value="{{ page.name }}">
{% if args.want_prefill_data %}
<input type="hidden" name="want_prefill_data" value="1">
{% endif %}
<div class="ak-grid-row">
<div class="ak-grid-col ak-grid-col-12-of-12">
{% if not update %}
<h2>{{ page.title }}</h2>
{% else %}
<h2>Update Event Information</h2>
{% endif %}
</div>
</div>
<div class="ak-grid-row ak-grid-row-inverted">
{% if page.custom_fields.featured_image %}
<div class="ak-grid-col ak-grid-col-3-of-12">
<img class="ak-featured-img" src="{{page.custom_fields.featured_image}}">
</div>
{% endif %}
<div class="ak-grid-col {% if page.custom_fields.featured_image %}ak-grid-col-9-of-12{% else %}ak-grid-col-12-of-12{% endif %}">
{% if not update and form.host_text %}
<div class="ak-page-content">
{% include_tmpl form.host_text %}
</div>
{% endif %}
<div id="event-create-form" class="ak-styled-fields ak-labels-before {{templateset.custom_fields.field_errors_class|default:"ak-errs-below"}}">
<ul class="compact" id="ak-errors"></ul>
<div id="ak-user-info">
<h3>Your contact information</h3>
{% include "./user_form_wrapper.html" %}
<input type="hidden" name="never_recognize" value="1">
</div>
<div id="ak-event-info">
<h3>Event information</h3>
<div>
{% if campaign.use_title %}
<div>
<label for="id_event_title">Event name<span class="ak-required-flag">*</span></label>
<input id="id_event_title" type="text" name="event_title" value="{{ campaign.default_title }}">
</div>
{% endif %}
{% with event_starts_at as date_field %}
<div id="id_event_starts_at_row">
<label for="id_event_starts_at">Start date/time<span class="ak-required-flag">*</span></label>
{% include "./date_picker.html" %}
</div>
<script type="text/javascript">
// Replace animation w/instant show, because anim
// breaks tabbing quickly past the date field.
jQuery.fn.showFast = function(speed, callback) {
this.show()
callback()
}
// Removing datepicker doesn't break anything, and
// it might even be useful -- I can imagine users
// being confused when the picker covers up other
// key form fields.
$(function() {
$("#id_event_starts_at_date").datepicker( {
minDate: 0, showAnim: 'showFast'
} )
} );
</script>
{% endwith %}
{% if campaign.use_ends_at %}
{% with event_ends_at as date_field %}
<div>
<label for="id_event_ends_at">End time</label>
{% include "./date_picker.html" %}
</div>
{% endwith %}
{% endif %}
{% if campaign.allow_private %}
<div id="id_event_is_private_row" class="ak-checkbox-field">
<input id="id_event_is_private" type="checkbox" class="checkbox" name="event_is_private" value="1">
<label class="ak-checkbox-label" for="id_event_is_private">
Make event private
</label>
</div>
{% endif %}
<div>
<label for="id_event_max_attendees">Max. signups</label>
<input id="id_event_max_attendees" type="text" name="event_max_attendees" value="{{ campaign.default_event_size|default:"" }}" size=3>
</div>
{% include_tmpl form.custom_field_html %}
</div>
</div>
<div id="event-info">
<h3>Event location</h3>
<div {% if campaign.allowed_modes|length < 2 %}style="display: none"{% endif %}>
<label for="id_event_mode">Event Type<span class="ak-required-flag">*</span></label>
<select id="id_event_mode" name="event_mode">
{% for choice in campaign.allowed_modes %}
<option value="{{ choice.0 }}">{{ choice.1 }}</option>
{% endfor %}
</select>
</div>
<div class="unknown_user">
<!--
This only shows if the user form includes all of the
event fields (e.g., address1, country if you use it)
-->
<input id="id_at_my_house" type="checkbox" class="checkbox" name="at_my_house" value="1">
<label class="ak-checkbox-label" for="id_at_my_house">
Use my home address
</label>
</div>
<div>
{% with "event_" as input_name_prefix %}
<div>
<label for="id_event_venue">
<span class="for-mode-onsite">Venue<span class="ak-required-flag">*</span></span>
<span class="for-mode-local for-mode-regional for-mode-global">Platform<span class="ak-required-flag">*</span></span>
</label>
<input id="id_event_venue" type="text" if-at-my-house="Home" name="event_venue">
<div class="ak-skip-label-before">
<div class="for-mode-local for-mode-regional for-mode-global">Describe the service or technology being used for this event.</div>
</div>
</div>
<div>
<label for="event_country">Country</label>
{% include "./country_select.html" %}
<div class="ak-skip-label-before">
<div class="for-mode-local">Select a location in the local area your event is for.</div>
<div class="for-mode-global">The city and state or region you select below will only be used to determine your local timezone.</div>
</div>
</div>
<div class="for-mode-onsite">
<label for="id_event_address1">Street address<span class="ak-required-flag for-mode-onsite">*</span></label>
<input id="id_event_address1" type="text" name="event_address1">
</div>
<div>
<label for="id_event_city">City</label>
<input id="id_event_city" type="text" name="event_city">
</div>
<div>
<label for="id_event_state">State</label>
{% include "./state_select.html" %}
</div>
<div>
<label for="id_event_region">Region</label>
<input id="id_event_region" type="text" name="event_region">
</div>
<div>
<label for="id_event_postal">Postal</label>
<input id="id_event_postal" type="text" name="event_postal">
</div>
<div>
<label for="id_event_zip">ZIP</label>
<input id="id_event_zip" type="text" name="event_zip">
</div>
<!-- <div><label for="id_event_phone">Contact phone:</label> <input id="id_event_phone" type="tel" name="event_phone" size="12"></div> -->
{% if campaign.show_address1 %}
<div class="strong for-mode-onsite">
NOTE: Event addresses are public.
</div>
{% endif %}
{% endwith %}
<p>
Double-check date, time, and location before you submit!
</p>
</div>
</div>
<div id="event-info">
<h3>Event description</h3>
<div class="ak-errs-below">
<label for="id_event_public_description">
Public description<span class="ak-required-flag">*</span>
<br><span class="ak-normal">
{% if campaign.allow_private %}
For public events, people
{% else %}
People
{% endif %}
will see this text before signing up
</span>
</label>
<textarea id="id_event_public_description" name="event_public_description"></textarea>
</div>
<div>
<label for="id_event_directions">
<span class="for-mode-onsite">Directions to event</span>
<span class="for-mode-local for-mode-regional for-mode-global">Connection details</span>
</label>
<textarea id="id_event_directions" name="event_directions"></textarea>
<div class="ak-skip-label-before for-mode-local for-mode-global">
For virtual events, provide information about how people can connect to participate, such as a web page URL, dial-in phone number, or other instructions.
</div>
</div>
<div>
<label for="id_event_note_to_attenddees">Note to attendees
</label>
<textarea id="id_event_note_to_attenddees" name="event_note_to_attendees"></textarea>
</div>
</div>
</div><!--9-of-12-->
</div>
</div>
<div class="ak-grid-row">
<div class="ak-grid-col ak-grid-col-12-of-12">
{% if not update %}
{% if form.host_requirements|is_nonblank or form.ground_rules|is_nonblank %}
<div id="ground-rules">
<h3>Event rules</h3>
{% if form.host_requirements %}
<p>Here are the basic requirements for event hosts:</p>
<div class="ak-signoff-box ak-errs-below">
<blockquote>
{% include_tmpl form.host_requirements %}
</blockquote>
<div>
<input id="id_event_host_requirements" type="checkbox" name="event_host_requirements" value="1">
<label class="ak-checkbox-label" for="id_event_host_requirements">
<strong>Required:</strong>
I can meet the requirements for hosting an event.
</label>
</div>
</div>
{% else %}
<input type="hidden" name="event_host_requirements" value="1">
{% endif %}
{% if form.ground_rules|is_nonblank %}
<p>Here are the rules for hosting events:</p>
<div class="ak-signoff-box ak-errs-below">
<blockquote>
{% include_tmpl form.ground_rules %}
</blockquote>
<div>
<input id="id_event_host_ground_rules" type="checkbox" name="event_host_ground_rules" value="1">
<label class="ak-checkbox-label" for="id_event_host_ground_rules">
<strong>Required:</strong>
I agree to the rules for hosting an event.
</label>
</div>
</div>
{% else %}
<input type="hidden" name="event_host_ground_rules" value="1">
{% endif %}
</div>
{% else %}
<input type="hidden" name="event_host_requirements" value="1">
<input type="hidden" name="event_host_ground_rules" value="1">
{% endif %}
{% else %}
<input type="hidden" name="event_host_requirements" value="1">
<input type="hidden" name="event_host_ground_rules" value="1">
{% endif %}
{% if not update %}
<p>
Next, we'll email you a link to {% if campaign.require_email_confirmation %}confirm{% else%}manage{% endif %} your event.
</p>
{% else %}
<div>
<input id="id_send_details_changed_email" type="checkbox" name="send_details_changed_email" value="1">
<label class="ak-checkbox-label" for="id_send_details_changed_email">
Send an email to attendees notifying them of the event details changing
</label>
</div>
{% endif %}
<input id="id_submit" type="submit" value="{% if update %}Update event{% elif campaign.require_email_confirmation %}Continue to next step: Confirm event{% else %}Save event{% endif %}" class="ak-submit-button">
</div>
</div>
</form>
{% endblock %}
{% block script_additions %}
{% include "includes/jquery_ui.html" %}
{% if campaign.timezone %}
<script src="//cdnjs.cloudflare.com/ajax/libs/moment.js/2.7.0/moment.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.14/moment-timezone-with-data.min.js"></script>
<script type="text/javascript">
$(function() {
actionkit.forms.update_event_time("{{campaign.starts_at}}", "{{campaign.timezone}}");
});
</script>
{% endif %}
<script type="text/javascript">
isEventUnitedStates = function () {
var country = actionkit.form && actionkit.form.event_country
&& actionkit.utils.val(actionkit.form.event_country)
return country == 'United States' || country == 'US' || !country;
};
reflectEventCountryChange = function() {
var is_us = isEventUnitedStates();
var event_zip = actionkit.form.event_zip,
event_postal = actionkit.form.event_postal,
event_region = actionkit.form.event_region,
event_state = actionkit.form.event_state;
if ( event_zip && event_postal ) {
if ( is_us ) actionkit.forms.showAndHide(event_zip, event_postal);
else actionkit.forms.showAndHide(event_postal,event_zip);
}
if ( event_state ) {
if ( is_us ) {
$(event_state).removeAttr('disabled');
var shownRow = actionkit.forms.getRowForElement(event_state);
shownRow.show();
}
else {
$(event_state).attr('disabled', true);
$(event_state).val('');
$(event_state).change();
var hiddenRow = actionkit.forms.getRowForElement(event_state);
hiddenRow.hide();
}
}
if ( event_region ) {
if ( ! is_us ) {
$(event_region).removeAttr('disabled');
actionkit.forms.getRowForElement(event_region).show();
}
else {
$(event_region).attr('disabled', true);
$(event_region).val('').trigger('change');
actionkit.forms.getRowForElement(event_region).hide();
}
}
};
reflectEventMode = function () {
var mode = actionkit.utils.val( actionkit.form.event_mode ) || 'onsite';
$('.for-mode-onsite, .for-mode-local, .for-mode-regional, .for-mode-global').hide();
$('.for-mode-' + mode).show();
}
actionkitFormReady = function() {
if ( (actionkit.form.event_zip && actionkit.form.event_postal)
|| (actionkit.form.event_state && actionkit.form.event_region) ) {
if (actionkit.context.prefill_data) {
var event_zip_val = actionkit.context.prefill_data.event_zip,
event_postal_val = actionkit.context.prefill_data.event_postal;
}
reflectEventCountryChange();
if (actionkit.context.prefill_data) {
var is_us = isEventUnitedStates();
if (is_us) {
actionkit.form.event_zip.value = event_zip_val;
$(actionkit.form.event_zip).change();
}
else {
actionkit.form.event_postal.value = event_postal_val;
$(actionkit.form.event_postal).change();
}
}
}
};
$(document).ready( function() {
var prev_is_us, now_is_us;
$(actionkit.form.event_country).on('change', reflectEventCountryChange);
$('.ak-signoff-box input[type="checkbox"]').on('change', function() {
if ($(this).is(':checked')) {
$(this).next('label.ak-checkbox-label').removeClass('ak-error');
}
});
$('#id_event_mode').on('change', reflectEventMode);
reflectEventMode();
});
</script>
{% if update %}
<script type="text/javascript">
$( function() {
$('#ak-user-info input[name=email]').attr('disabled','disabled')
} );
</script>
{% endif %}
<script type="text/javascript">
var address_fields = [
'address1', 'address2', 'city', 'state', 'zip', 'postal', 'country'
];
function copyEventAddress() {
for (var i=0; i<address_fields.length; ++i)
$('#id_event_' + address_fields[i]).val(
$('#id_' + address_fields[i]).val() || ''
).change();
// handle inconsistent id="state" in user_form and
// id="event_country" from country_select.html
$('#id_event_state').val($('#state').val() || $('#id_state').val() || '').change();
$('#event_country').val($('#country').val() || $('#id_country').val() || '').change();
if ( !$('#id_event_venue').val() )
$('#id_event_venue').val($('#id_event_venue').attr('if-at-my-house') || '').change()
}
function clearEventAddress() {
for (var i=0; i<address_fields.length; ++i)
$('#id_event_' + address_fields[i]).val('').change();
if ( $('#id_event_venue').val() == $('#id_event_venue').attr('if-at-my-house') )
$('#id_event_venue').val('').change();
}
$('#id_at_my_house').click(function() {
this.checked ? copyEventAddress() : clearEventAddress();
})
$( function () {
// check whether "Use my home address" even makes sense
for ( var i = 0; i < address_fields.length; ++i ) {
var fieldName = address_fields[i];
// if no #event_city, we don't care if user form has a #id_city
if (!$('#id_event_' + fieldName + ', #event_' + fieldName).length)
continue;
// if no #id_address1 or #address1 to match #event_address1,
// hide the checkbox since it won't work
if (!$('#id_' + fieldName + ', #' + fieldName).length) {
$('#id_at_my_house').parent().remove();
break;
}
}
} );
</script>
{% endblock %}
Event Created¶
Message shown to host after they submit to create an event.
{% extends "./wrapper.html" %}
{% block content %}
<div class="ak-grid-row">
<div class="ak-grid-col ak-grid-col-12-of-12">
{% with action.event.campaign as campaign %}
{% if campaign.require_email_confirmation and campaign.create_page.followup.send_email %}
<h2>Confirm Your Event</h2>
<p>Check your email {% if args.email %}at {{args.email}}{% endif %} to finish creating your event.</p>
{% elif campaign.require_staff_approval %}
<h2>Staff approval required</h2>
<p>Your event must be approved by staff before it will be open for signups; when it is approved, you'll receive an email.</p>
{% else %}
{% if campaign.create_page.followup.send_email %}
<h2>View Host Tools</h2>
<p>Thanks for signing up to host an event! Now check your email {% if args.email %}at {{args.email}}{% endif %} to view your host tools.</p>
{% else %}
<h2>Thank you!</h2>
<p>Thanks for signing up to host an event! You'll hear from us soon.</p>
{% endif %}
{% endif %}
{% endwith %}
</div>
</div>
{% endblock %}
Event Email Attendee Removed¶
Email sent to attendee if their sign up is canceled by host or admin.
Subject: You have been removed from your "{{campaign_title}}" event
<p>You have been removed from the "{{ campaign.local_title }}" event you were signed up to attend.</p>
<!-- Replacement for unsubscribe. -->
<p><small>
You received this message because you were signed up for an event.
You won't receive any more messages about this event.
</small></p>
Event Email Cancelled¶
Email sent to attendees/hosts after an event is canceled by staff or host.
Subject: Your "{{campaign_title}}" event has been cancelled
<p>The "{{ campaign.local_title }}" event you signed up for has been cancelled.</p>
<p>You can search for other events here:</p>
<p><a href="{% client_domain_url %}event/{{ campaign.local_name }}/search/">{% client_domain_url %}event/{{ campaign.local_name }}/search/</a></p>
<!-- Replacement for unsubscribe. -->
<p><small>
You received this message because you were signed up for an event.
You won't receive any more messages about this event.
</small></p>
Event Email Created¶
Email sent to host after they create an event with link they must click to confirm the event.
Subject: {% if action.event.campaign.require_email_confirmation %}Confirm{% else %}Manage{% endif %} your "{{ action.event.campaign.local_title }}" event
<!-- event_email_created.html in the templateset contains the default
confirmation email for hosts -->
<p>Thanks for setting up a "{{ action.event.campaign.local_title }}" event. {% if action.event.campaign.require_email_confirmation %}<b>Before anyone can sign up for your event, you'll need to click the link below to access your host tools and confirm your event.</b>
{% else %}
Please click the link below to access your host tools:
{% endif %}
<p><a href="https://{% client_ssl_domain %}/event/{{ action.event.campaign.local_name }}/{{ action.event.id }}/host/?i={{ user|login_string }}&l=1">https://{% client_ssl_domain %}/event/{{ action.event.campaign.local_name }}/{{ action.event.id }}/host/?i={{ user|login_string }}&l=1</a></p>
<p>Please <b>don't forward this email</b>: the link above is personalized, and can be used to manage your event or change your account password.</p>
<p>Thanks again!</p>
<!-- Replacement for unsubscribe -->
<p><small>You're receiving this message because you set up a "{{ action.event.campaign.local_title }}" event. If you don't want to receive further emails about this event, you can cancel the event using the host tools linked above.</small></p>
Event Email Approved¶
Email sent to host after an event they created has been approved.
Subject: Your "{{campaign_title}}" event has been approved!
<!-- If a campaign requires event approval, this email gets sent out to event hosts when their event is approved -->
<p>Congratulations! Your "{{campaign_title}}" event has been approved and is now open for signups!</p>
{% filter tag_links:'nr=1' %}
<p>You can start sharing your event at <a href="{% client_domain_url event.public_url %}">{% client_domain_url event.public_url %}</a> with potential attendees. </p>
{% endfilter %}
<p>To use your event tools, visit <a href="https://{% client_ssl_domain %}{{ signup.url }}&i={{ user|login_string }}&l=1">https://{% client_ssl_domain %}{{ signup.url }}&i={{ user|login_string }}&l=1</a></p>
<p>Please <b>don't forward this email</b>: the link above is personalized, and can be used to manage your event or change your account password.</p>
<p>Thanks again!</p>
<!-- Replacement for unsubscribe -->
<p><small>You're receiving this message because you set up a "{{campaign_title}}" event. If you don't want to receive further emails about this event, you can cancel the event using the host tools linked above.</small></p>
Event Email from Admin¶
Email from staff user to hosts, sent from the event management interface.
Subject: {{subject}}
<p>{{ message|linebreaksbr }}</p>
<hr>
<p>To use your event tools, visit <a href="https://{% client_ssl_domain %}{{ signup.url }}{% if signup.role == "host" %}&i={{ user|login_string }}&l=1{% endif %}">https://{% client_ssl_domain %}{{ signup.url }}{% if signup.role == "host" %}&i={{ user|login_string }}&l=1{% endif %}</a></p>
{% if signup.role == "host" %}
<p>Please <b>don't forward this email</b>: the link above is personalized, and can be used to manage your event or change your account password.</p>
{% endif %}
<!-- Replacement for unsubscribe. -->
<p><small>
You're receiving this message because you're signed up for an event.
You can use your event tools, linked above, to cancel your signup and quit receiving these messages.
</small></p>
Event Email from Attendee¶
Email from attendee to hosts.
Subject: Your "{{campaign_title}}" attendee sent you a message
<p>Here's a message from {{ sender_signup.user }}, an {{ sender_signup.role }} of your {{ campaign.local_title }} event:</p>
<blockquote>
{{ message|linebreaksbr }}
</blockquote>
<p>To use your event tools, visit <a href="https://{% client_ssl_domain %}{{ signup.url }}{% if signup.role == "host" %}&i={{ user|login_string }}&l=1{% endif %}">https://{% client_ssl_domain %}{{ signup.url }}{% if signup.role == "host" %}&i={{ user|login_string }}&l=1{% endif %}</a></p>
{% if signup.role == "host" %}
<p>Please <b>don't forward this email</b>: the link above is personalized, and can be used to manage your event or change your account password.</p>
{% endif %}
<!-- Replacement for unsubscribe. -->
<p><small>
You're receiving this message because you're signed up for an event.
You can use the link above to cancel your signup and quit receiving these messages.
</small></p>
Event Email from Host¶
Email sent to attendees or co-hosts by host with link to appropriate event tools.
Subject: {{subject}}
<p>Here's a message from {{ sender_signup.user }}, a {{ sender_signup.role }} of your {{ campaign.local_title }} event:</p>
<blockquote>
{{ message|linebreaksbr }}
</blockquote>
<p>To use your event tools, visit <a href="https://{% client_ssl_domain %}{{ signup.url }}{% if signup.role == "host" %}&i={{ user|login_string }}&l=1{% endif %}">https://{% client_ssl_domain %}{{ signup.url }}{% if signup.role == "host" %}&i={{ user|login_string }}&l=1{% endif %}</a></p>
{% if signup.role == "host" %}
<p>Please <b>don't forward this email</b>: the link above is personalized, and can be used to manage your event or change your account password.</p>
{% endif %}
<!-- Replacement for unsubscribe. -->
<p><small>
You're receiving this message because you're signed up for an event.
You can use your event tools, linked above, to cancel your signup and quit receiving these messages.
</small></p>
Event Email Role Changed¶
Email sent to user whose role has been changed (i.e., he/she has been made a co-host).
Subject: You are now a {{new_role}} of your "{{campaign_title}}" event
<p>You are now a {{ signup.role }} of your "{{ campaign.local_title }}" event.</p>
<p>To use your event tools, visit <a href="https://{% client_ssl_domain %}{{ signup.url }}{% if signup.role == "host" %}&i={{ user|login_string }}&l=1{% endif %}">https://{% client_ssl_domain %}{{ signup.url }}{% if signup.role == "host" %}&i={{ user|login_string }}&l=1{% endif %}</a></p>
{% if signup.role == "host" %}
<p>Please <b>don't forward this email</b>: the link above is personalized, and can be used to manage your event or change your account password.</p>
{% endif %}
<!-- Replacement for unsubscribe. -->
<p><small>
You're receiving this message because you're signed up for an event.
You can use your event tools, linked above, to cancel your signup and quit receiving these messages.
</small></p>
Event Host Details¶
Event details including venue for display on the event_host_tools.html page.
{% filter collapse_spaces %}
{% if event.venue %}
<div class="event-venue">
{{ event.venue }}
</div>
{% endif %}
<div class="event-address clearfix">
<div class="event-address-content">
{% if event.mode != "onsite" %}
<div class="ak-event-mode">{{ event.get_mode_display }}</div>
{% endif %}
{% if event.attendee_show_address1 %}
<div class="ak-event-address1">{{ event.address1 }}</div>
{% endif %}
<div class="ak-event-city-etc">{{ event.attendee_general_location }}</div>
</div>
</div>
<table class="ak-event-table">
{% if event.get_starts_at_display %}
<tr class="ak-event-time">
<th>When:</th>
<td>
{{ event.get_starts_at_display }}
{% if event.show_timezone %}{{ event.local_timezone|timezone_display }}{% endif %}
{% if event.is_in_past %}<span class="ak-error ak-event-over-notice">(event is now over)</span>{% endif %}
</td>
</tr>
{% endif %}
{% if event.directions %}
<tr class="ak-event-directions">
<th>
{% if event.is_virtual %}
To connect:
{% else %}
Directions to event:
{% endif %}
</th>
<td style="word-break: break-word; hyphens: auto">{{ event.directions|urlize }}</td>
</tr>
{% endif %}
{% if event.note_to_attendees %}
<tr class="ak-event-note-to-attendees">
<th>Note to attendees:</th>
<td>{{ event.note_to_attendees|linebreaksbr }}</td>
</tr>
{% endif %}
{% if event.campaign.allow_private %}
<tr class="ak-event-privacy">
<th></th>
<td>
<label>Event is {% if event.is_private %}private{% else %}public{% endif %}.</label>
</td>
</tr>
{% endif %}
<tr class="ak-event-signup-link">
<th>Signup link:</th>
<td> <a href="{% client_domain_url event.public_url %}">{% client_domain_url event.public_url %}</a></td>
</tr>
</table>
{% if event.public_description %}
<p class="ak-event-description">{{ event.public_description|linebreaksbr }}</p>
{% endif %}
{% endfilter %}
Event Host Tell-a-Friend Message¶
TAF message you entered in step 3 when you created the event page.
Subject: Hope you can come!
{% with action.event as event %}
Hi,
{% filter single_line %}
I'm hosting an event as part of {% client_name %}'s
"{{ event.campaign.local_title }}" campaign. It's at
{{ event.address1 }} {% if event.venue %}({{ event.venue }}){% endif %}
in {{ event.city }}, {{ event.region }}
on {{ event.starts_at|date:"l, F j" }} at {{ event.starts_at|date:"f A" }}.
{% endfilter %}
RSVP here so I can know you're coming:
{% client_domain_url %}event/{{ event.campaign.name }}/{{ event.id }}/?source=taf
Thanks,
{{ action.user.first_name }}
{% endwith %}
{% comment %}
[Campaigners: the default host tell-a-friend message comes from
event_host_taf_msg.txt in the templateset.]
{% endcomment %}
Event Host Tools¶
Host tools page layout and code.
{% extends "./wrapper.html" %}
{% block script_additions %}
<script type="text/javascript">
// Roster toggle-all checkbox
function toggleSignups() {
$(this)
.closest('form')
.find('input.toggle')
.attr('checked', this.checked);
}
// Update "N attendee(s)" in email form
function handleSignupsChanged() {
var frm = $(this).closest('form');
var to_count = $('input.toggle:checked').length;
// Mailing all recipients if nobody's checked
if ( !to_count )
to_count = $('input.toggle').length
// They've figured out the checkboxes; no need to advertise
if ( to_count )
frm.find('.check-recipients-help').hide();
frm.find('.to-count').text(to_count);
}
// Email button
function handleEmail() {
var frm = $(this).closest('form');
frm.find('.signup-list-controls').slideUp('fast');
frm.find('.contact-form').slideDown('fast', function() { $(this).css('overflow','visible');});
return false;
}
// "Email attendee", "email cohost", "invite friends" links
// Unhide if needed and fake :target on IE
function handleJumpLink() {
var targetEl;
if ( this.id == 'email-cohosts-link' )
targetEl = $('div.contact-cohosts');
else if ( this.id == 'email-attendees-link' )
targetEl = $('div.contact-attendees');
else if ( this.id == 'invite-friends-link' )
targetEl = $('#taf');
else if ( this.id == 'add-attendees-link' )
targetEl = $('#more-attendees');
// console.log(targetEl);
// Unhide email form if needed
if ( /^email-/.test(this.id) ) {
var emailButton = targetEl.closest('form').find('input[type="submit"].email');
handleEmail.apply(emailButton, []);
}
if(this.id == 'add-attendees-link'){
$('.signup-list-controls').slideUp('fast');
$('#more-attendees').slideDown('fast');
actionkit.forms.initValidation('attendees-add');
}
// Highlight
targetEl.addClass('target');
// Allow jump to #foo to happen
return true;
}
// Confirm cancelling event
function confirmSubmit() {
return confirm($(this).attr('confirm-message'));
}
// Stash the name of the submit button in the 'action' form field
// (helps the validation JS see which kind of action to validate for)
function setFormAction() {
var formEl = $(this).closest('form')[0];
if ( !formEl && !formEl.action ) return;
formEl.action.value = this.name;
}
// Check for required fields for remove/promote/demote/email
function validateRoster(form) {
var action = form.action.value;
// Nobody to remove/promote/demote
if ( /(change-role|remove)/.test(action)
&& !($(form).find('input.toggle:checked').length) )
actionkit.errors['user_id:missing'] =
actionkit.forms.errorMessage('event_roster_user_ids:missing');
// No message to send
if ( action == 'send_email'
&& !form.body.value )
actionkit.errors['body:missing'] =
actionkit.forms.errorMessage('event_contact_body:missing');
}
// Confirm removing folks
function confirmRoster(form) {
var action = form.action.value;
var actionButton = $(form).find('input[name="' + action + '"]');
var confirmMessage = actionButton.attr('confirm-message');
if ( confirmMessage )
return confirm(confirmMessage);
else
return true;
}
// Click anywhere in row to check/uncheck attendee
function toggleRow(e) {
var toggleEl = $(this).closest('tr').find('.toggle')[0];
if ( toggleEl ) toggleEl.checked = !toggleEl.checked;
return false;
}
// Update the confirmation div from a different page
function updateConfirmationMessage() {
for (var key in actionkit.args) {
if (key.indexOf(':') > 0 && actionkit.args[key] == 1) {
$('#ak-confirmation').text(actionkit.forms.text['error_' + key]);
$('#ak-confirmation').show();
}
}
}
// Set everything up onready
function initHostTools() {
$('input.toggle-all').click(toggleSignups);
$('input.toggle').click(handleSignupsChanged);
$('.signup-list td:not(.toggle-col)').click(toggleRow);
$('input[type="submit"].email').click(handleEmail);
$('input[type="submit"]').click(setFormAction);
$('#event-host-links .jump-link').click(handleJumpLink);
$('a[confirm-message]').click(confirmSubmit);
if ($('#manage-host').length)
actionkit.forms.initValidation('manage-host');
if ($('#manage-attendee').length)
actionkit.forms.initValidation('manage-attendee');
var attendeeTable = new formTable(fields, 'attendee_', 5);
$('#more-attendees .data-entry').append(attendeeTable.build());
$('#more-attendees input.more-rows').click(function(e){attendeeTable.addRows($(e.target).data('count'))});
// when adding attendees, clear empty rows
$('#more-attendees input[type=submit]').click(function(e){
attendeeTable.clearEmptyRows()
return true;
});
$(window).load(function() {
updateConfirmationMessage();
});
}
$(initHostTools);
</script>
{% endblock %}
{% block content %}
<div id="ak-confirmation" class="ak-confirmation">
</div>
{% if signup and not event.is_inactive %}
<!-- Title -->
<div class="ak-grid-row">
<div class="ak-grid-col ak-grid-col-12-of-12">
{% if campaign.use_title %}
<h2>{{ campaign.local_title }}: {{ event.title }}</h2>
{% else %}
<h2>{{ campaign.local_title }}: Event Tools</h2>
{% endif %}
<!-- Message from mothership -->
<div id="host-tools-intro">
{% include_tmpl form.tools_text %}
</div>
</div>
</div>
<div class="ak-grid-row ak-grid-row-inverted">
<div class="ak-grid-col ak-grid-col-4-of-12">
<!-- Tools -->
<div class="ak-bar-holder">
{% block extra_links %}{% endblock %}
{% block host_links %}
<div class="ak-bar ak-field-box" id="event-host-tools">
<h3>Manage Event</h3>
{% if event.is_awaiting_approval and not user_is_moderator %}
<span class="ak-error">Note: this event is awaiting approval by staff.</span>
{% endif %}
<ul id="event-host-links">
{% include_tmpl form.tools_sidebar %}
{% if user_is_manager %}
<li>Logged in as a manager
{% if campaign.require_email_confirmation and not event.host_is_confirmed %}
<br> <a onclick="$.get('/event/{{campaign.local_name}}/{{event.id}}/modify/confirm/'); $(this).text('Confirmed');" href="#">Confirm event</a>
{% endif %}
</li>
{% endif %}
<li><a href="{% url 'create_event' event.local_campaign.create_page.name %}?action_id={{ action.id }}&update=1&want_prefill_data=1{% if host %}&host_akid={{ host.akid }}{% endif %}">Edit event details</a></li>
{% if cohosts %}
<li class="if-js"><a class="jump-link" id="email-cohosts-link" href="#contact-cohosts">Email cohost{{ cohosts|length|pluralize }}</a></li>
{% endif %}
{% if attendees %}
<li class="if-js"><a class="jump-link" id="email-attendees-link" href="#contact-attendees">Email attendee{{ attendees|length|pluralize }}</a></li>
{% else %}
<!-- Flag that the functionality will be there -->
<li class="if-js">
Email attendees<br>
(Available after people sign up for your event.)
</li>
{% endif %}
{% if event.is_in_past %}
<li class="if-js"><a class="jump-link" id="add-attendees-link" href="#attendees-add">Add Attendees</a></li>
{% endif %}
{% if event.is_open_for_signup and page.pagefollowup.send_taf %}
<li class="if-js"><a class="jump-link" id="invite-friends-link" href="#invite-friends">Invite friends</a></li>
{% endif %}
<li><a confirm-message="Really cancel event? This can't be undone." href="{% url 'cancel_event' event.local_campaign.create_page.name event.id %}">Cancel event</a></li>
<li><a href="/logout/">Log out</a></li>
</ul>
</div>
{% endblock %}
</div><!-- bar holder -->
</div><!-- span -->
<div class="ak-grid-col ak-grid-col-8-of-12">
{% block details %}
<!-- Details -->
<div id="host-event-details ak-clearfix">
<h3>
Event Details
{% block event_edit_link %}(<a class="ak-underline-on-hover" href="{% url 'create_event' event.local_campaign.create_page.name %}?action_id={{ action.id }}&update=1&want_prefill_data=1{% if host %}&host_akid={{ host.akid }}{% endif %}">Edit</a>){% endblock %}
</h3>
{% include "./event_host_details.html" %}
</div>
{% endblock %}
{% block tools %}
<!-- Cohost roster -->
{% if cohosts %}
{% with cohosts as signups %}
{% include "./event_roster.html" %}
{% endwith %}
{% endif %}
<!-- Guest roster -->
{% if attendees %}
{% with attendees as signups %}
{% include "./event_roster.html" %}
{% endwith %}
{% else %}
<!-- Optional no attendees message, e.g., "go use the Invite Folks tool at right" -->
{% endif %}
{% include './event_roster_add.html' %}
<!-- Invite -->
{% if event.is_open_for_signup %}
<div class="ak-margin-top-2 ak-clearfix">
{% include "./event_invite.html" %}
</div>
{% endif %}
{% endblock %}
</div>
</div>
{% else %}
<div class="ak-grid-row">
<div class="ak-grid-col ak-grid-col-12-of-12">
{% if event.is_inactive %}
<h3>This event is no longer active.</h3>
{% endif %}
{% if not signup %}
<h3>Sorry, you aren't currently signed up for this event.</h3>
<p>If you think this is a mistake, check that you cut-and-pasted the entire link to this page.</p>
{% endif %}
{% block find_another_event %}<div><a href="/event/{{ campaign.local_name }}/?akid={{args.akid}}&zip={{args.zip}}">Search for another event</a></div>{% endblock %}
</div>
</div>
{% endif %}
{% endblock %}
{% block below_form %}
<script type="text/javascript">
actionkit.forms.contextRoot = '/context/';
actionkit.forms.initTafForm('taf');
</script>
{% endblock %}
Event Invite¶
Form hosts and attendees use to invite friends.
{% if page.pagefollowup.send_taf %}
<a name="invite-friends"></a>
<form name="taf" method="POST" action="/update_action/" accept-charset="utf-8">
<input type="hidden" name="page" value="{{ page.name }}">
<input type="hidden" name="action_id" value="{{ action.id }}">
<input type="hidden" name="taf_only" value="1">
<input type="hidden" name="required" value="taf_emails">
<div class="ak-styled-fields {{templateset.custom_fields.field_errors_class|default:"ak-errs-below"}} ak-field-box">
<h3>Invite friends</h3>
<p id="taf-confirmation" class="ak-confirmation">
Sent! If you like, you can send more messages below.
</p>
<ul id="ak-errors"></ul>
<table class="ak-clearfix ak-message-form">
<tr>
<th>
<label for="id_taf_emails">To*</label>
</th>
<td>
<textarea id="id_taf_emails" name="taf_emails" placeholder="Enter email addresses separated by commas"></textarea>
</td>
</tr>
<tr>
<th>
<label> </label>
</th>
<td><input class="ak-btn-short" type="submit" value="Send invitations"></td>
</tr>
</table>
<div id="ak-taf-form">
<table class="ak-nodisplay-if-js ak-message-form" id="taf_preview">
<tr>
<th>
<label for="id_taf_subject">Subject</label>
</th>
<td><div class="ak-readonly-value taf_subject">{% include_tmpl page.followup.taf_subject escaped %}</div></td>
</tr>
<tr>
<th>
<label for="id_taf_note">Your note</label>
</th>
<td><textarea id="id_taf_note" name="taf_note" class="wide" style="height: 75px;" placeholder="Optionally add a personal comment"></textarea></td>
</tr>
<tr>
<th>
<label for="id_taf_body">Message</label>
</th>
<td><div class="ak-readonly-value"> {% filter referring_akid:akid|tag_links:"source=taf"|strip|linebreaksbr %}{% include_tmpl page.followup.taf_body escaped %}{% endfilter %}</div></td>
</tr>
</table>
</div>
<p>
<a class="if-js ak-emailalt" id="ak_hide_message_note" href="#" style="display: none;" onclick="$('#taf_preview').fadeOut(); $(this).hide(); $('#ak_view_message_note').show(); return false;">Hide message/note</a>
</p>
<p class="ak-clearfix">
<a class="if-js ak-emailalt" id="ak_view_message_note" href="#" onclick="$('#taf_preview').fadeIn(); $('#ak_hide_message_note').show(); $(this).hide(); return false;">View message/add note</a>
</p>
<p class="ak-clearfix">You can also <a href="mailto:?subject={% filter referring_akid:akid|strip|urlencode %}
{% include_tmpl page.followup.taf_subject unescaped %}
{% endfilter %}&body={% filter referring_akid:akid|strip|urlencode %}
{% include_tmpl page.followup.taf_body unescaped %}
{% endfilter %}">mail friends through your email program</a>.
</p>
</div>
</form>
{% block script_additions %}
<script type="text/javascript">
$(document).ready(function() {
$('.ak-emailalt').on('click', function() {
$('#ak-taf-form').slideToggle(function() {
$('#taf_form').toggleClass('ak-closed');
});
$('#copy-and-paste').slideToggle();
});
});
</script>
{% endblock %}
{% endif %}
<div class="ak-margin-top-1 ak-clearfix">
<div style="float: left; width: 49%;">
<a class="ak-button ak-share-button ak-small-share-button ak-facebook" href="/share/link?type=fb&page_name={{ event.signup_page.name }}&append=../{{ event.id }}&action_id={{action.id}}&akid={{akid}}" target="_blank">Post to Facebook</a>
</div>
<div style="float: right; width: 49%;">
<a class="ak-button ak-share-button ak-small-share-button ak-twitter" href="/share/link?type=tw&page_name={{ event.signup_page.name }}&append=../{{ event.id }}&action_id={{action.id}}&akid={{akid}}" target="_blank">Share on Twitter</a>
<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");</script>
</div>
</div>
Event Roster¶
Cohost/attendee roster for host page
<!-- event_roster.html: Cohost/attendee roster for host page -->
<style type="text/css">
.{{signups.role}}-list .toggle-col { width: 1% }
.{{signups.role}}-list-holder button { margin-top: 0; margin-bottom: 0; }
fieldset.{{signups.role}}-list-holder { clear: both; }
</style>
<div class="signup-list {{signups.role}}-list ak-clearfix">
<h3>
{% if signups.role == 'host' %}{% if user_is_moderator %}Host{% else %}Cohost{% endif %}{% else %}Attendee{% endif %}{{ signups|length|pluralize }} ({{ signups|length }} total)
</h3>
<form id="manage-{{signups.role}}" onvalidate="return validateRoster(this)" onconfirm="return confirmRoster(this)" name="manage-{{signups.role}}" method="post" action="/event/{{campaign.local_name}}/{{event.id}}/manage_signups" accept-charset="utf-8">
<div id="manage-{{signups.role}}-confirmation" class="ak-confirmation"></div>
<ul class="compact" id="ak-errors"></ul>
<input type="hidden" name="page" value="{{ page.name }}">
<input type="hidden" name="event_id" value="{{ event.id }}">
<input type="hidden" name="akid" value="{{ args.akid }}">
<input type="hidden" name="role" value="{{ signups.role }}">
<input type="hidden" name="action" value="">
<input type="hidden" name="form_name" value="manage-{{signups.role}}">
<table class="signup-tbl {{signups.role}}-tbl ak-data-table">
<thead>
<th class="toggle-col"><input type="checkbox" class="if-js toggle-all"></th>
<th class="name-col">Name</th>
<th class="phone-col">Phone</th>
{% if event.is_in_past and signups.role == 'attendee' %}
<th class="attended-col">Attended</th>
{% endif %}
</thead>
<tbody>
{% for signup in signups %}
<tr class="{% cycle 'even' 'odd' %}">
<td class="toggle-col">
<input type="checkbox" class="toggle" name="user_id" value="{{ signup.user.id }}">
</td>
<td class="name-col">{{ signup.user }}</td>
<td class="phone-col">{{ signup.user.phone }}</td>
{% if event.is_in_past and signups.role == 'attendee' %}
<td class="attended-col">
{% if signup.attended %}yes{% else %}no{% endif %}
</td>
{% endif %}
</tr>
{% endfor %}
</tbody>
</table>
<div class="signup-list-controls ak-clearfix">
<input type="submit" class="email if-js ak-btn-short" value="Email">
{% if signups.role == 'attendee' %}
<input type="submit" confirm-message="Really remove attendee? This can't be undone." name="remove" value="Remove" class="remove ak-btn-short">
{% if event.is_in_past %}
<input type="submit" name="change-attended" value="Change Attendance" class="change-attended ak-btn-short">
{% endif %}
{% endif %}
<input type="submit" name="change-role" value="Make {% if signups.role == 'host' %}attendee{% else %}co-host{% endif %}" class="change-role ak-btn-short">
</div>
{% with 'no' as need_form %}
{% if signups.role == 'host' %}
{% if user_is_moderator %}
{% with 'hosts' as to %}
{% include "./event_contact.html" %}
{% endwith %}
{% else %}
{% with 'cohosts' as to %}
{% include "./event_contact.html" %}
{% endwith %}
{% endif %}
{% else %}
{% with 'attendees' as to %}
{% include "./event_contact.html" %}
{% endwith %}
{% endif %}
{% endwith %}
</form>
</div>
<!-- End event_roster.html -->
Event Search¶
Page for end user event search and display of events found.
{% extends "./wrapper.html" %}
{% block css_additions %}
<link href="/resources/leaflet/leaflet.css" rel="stylesheet" type="text/css">
<link href="/resources/leaflet/MarkerCluster.css" rel="stylesheet" type="text/css">
<link href="/resources/leaflet/MarkerCluster.Default.css" rel="stylesheet" type="text/css">
{% endblock %}
{% block script_additions %}
<script type="text/javascript" src="/resources/leaflet/leaflet.js"></script>
<script type="text/javascript" src="/resources/leaflet/leaflet.markercluster-src.js"></script>
{% endblock %}
{% block content %}
<div class="event-search ak-search-area">
<div class="ak-grid-row">
<div class="ak-grid-col ak-grid-col-12-of-12">
<h2>{{ page.title }} - Find an Event</h2>
</div>
</div>
<!-- no class=ak-form because we don't need to wait for context to show this -->
<form name="act" method="GET" action="" accept-charset="utf-8" onsubmit="actionkit.forms.eventSearch(this); return false;" class="ak-styled-fields">
<input type="hidden" name="page" value="{{ page.name }}">
<input type="hidden" name="template" value="event_search.html">
<input type="hidden" name="akid" value="{{ args.akid }}">
<input type="hidden" name="distance" value="50">
<input type="hidden" name="limit" value="10">
<input type="hidden" name="event_search_on_load" value="1">
<div class="ak-grid-row">
<div class="ak-grid-col ak-grid-col-12-of-12">
<div {% if form.search_page_text %}class="ak-grid-col-3-of-12 ak-margin-top-1 clearfix" style="float: right; min-width: 200px; margin-left: 1em"{% endif %}>
<div style="{% if not form.search_page_text %}width: 50%; float: left; padding-right: 0.5em;{% endif %}">
<a class="ak-button ak-share-button ak-small-share-button ak-facebook" href="/share/link?type=fb&page_name={{page.name}}&action_id={{action.id}}&akid={{akid}}" target="_blank">Post to Facebook</a>
</div>
<div style="{% if not form.search_page_text %}width: 50%; float: left; padding-left: 0.5em;{% endif %}">
<a class="ak-button ak-share-button ak-small-share-button ak-twitter" href="/share/link?type=tw&page_name={{page.name}}&action_id={{action.id}}&akid={{akid}}" target="_blank">Share on Twitter</a>
<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");</script>
</div>
</div>
{% if form.search_page_text %}
<div class="area">
{% include_tmpl form.search_page_text %}
</div>
{% endif %}
<ul class="compact" id="ak-errors"></ul>
<div class="ak-event-search">
{% if campaign.allows_geographic_modes %}
<div class="ak-display-inline-block">
<label for="id_zip">{% if form.templateset.is_intl %}Postcode{% else %}ZIP{% endif %} or City:</label>
<input type="text" name="place" value="{% if args.place %}{{args.place}}{% else %}{{args.zip}}{% endif %}">
</div>
{% if form.templateset.is_intl %}
<div class="ak-display-inline-block">
<label for="id_country">Country:</label>
{% include "./country_select.html" %}
</div>
{% endif %}
<button type="submit" class="ak-event-search">Search</button>
{% endif %}
{% if campaign.also_search_campaigns.all %}
<div>
<input type="hidden" name="also_search_present" value="1">
Include:
<input type="hidden" name="also_search_self_present" value="1">
<input type="checkbox" name="also_search_self" value="{{ campaign.name }}" checked>
{{ campaign.title }}
{% for also in campaign.also_search_campaigns.all %}
<input type="checkbox" name="also_search" value="{{ also.name }}" checked>
{{ also.title }}
{% endfor %}
</div>
{% endif %}
</div>
</div>
</div>
</form>
<div class="ak-grid-row">
<div class="ak-grid-col ak-grid-col-12-of-12">
<div id="event-search-results">
{% if args.page %}
{% include "./event_search_results.html" %}
{% endif %}
</div>
</div>
</div>
</div>
{% endblock %}
Event Search Results¶
Display for details you specify for all events meeting search criteria. Displays on event_search.html page.
{% filter collapse_spaces %}
{% comment %}
This file is so long because you can choose whether your campaign uses
event titles, venues, etc., and different choices produce different HTML.
The field that's linked in each search result is the first of these
that's defined:
1. Title
2. Venue
3. Distance
4. Campaign name
{% endcomment %}
{% if events|is_defined %}
<input type="hidden" id="id_have_events" name="have_events" value="1">
{% if not events|length %}
<h3>No events found near {{ place|default:"your location" }}.</h3>
{% else %}
{% if not hide_map %}
<p>There are <strong>{{ open_events|length }}</strong> events open for signup {% if is_in_past or is_full %}({% if is_full %}plus <strong>{{ is_full|length }}</strong> full{% endif %}{% if is_in_past and is_full %}, {% endif %}{% if is_in_past and not is_full %}plus {% endif %}{% if is_in_past %}<strong>{{ is_in_past|length }}</strong> ended{% endif %}){% endif %}</p>
{% endif %}
{% if campaign.show_address1 and not hide_map and map_events|length and map_events|length < 300 %}
<style>
#map {
width: 100%;
height: 400px;
}
.leaflet-container a.ak-button { color: #fff; }
#map .leaflet-popup-content p { margin: 5px 0px; }
</style>
<div id="map"></div>
<div id="map-items" style="display: none">
{% for event in map_events %}
<div data-latitude="{{ event.latitude }}" data-longitude="{{ event.longitude }}" data-icon="{% if event.is_open_for_signup %}open_for_signup{% else %}not_open_for_signup{% endif %}">
<p>{{ event.starts_at_dt|date:"l, F jS, g:i a" }}</p>
<p class="ak-event-title">
<a href="/event/{{ event.campaign.local_name }}/{{event.id}}/signup/?akid={{args.akid}}&source={{args.source}}{% if campaign.id != event.campaign.id %}&search_campaign={{ campaign.name }}{% endif %}" {% if event.public_title_is_from_campaign %}class="ak-campaign-title"{% endif %}>{{ event.public_title }}</a>
</p>
<p>{% if event.search_show_address1 %}{{ event.address1 }}<br>{% endif %}{{ event.search_general_location }}</p>
{% if event.is_in_past %}
<p><strong>Sorry, the event is over.</strong></p>
{% elif event.is_full %}
<p><strong>Sorry, the event is full.</strong></p>
{% else %}
<a href="/event/{{ event.campaign.local_name }}/{{event.id}}/signup/?akid={{args.akid}}&source={{args.source}}{% if campaign.id != event.campaign.id %}&search_campaign={{ campaign.name }}{% endif %}" class="ak-button">Sign up</a>
{% endif %}
</div>
{% endfor %}
</div>
<script>
function draw_map() {
// Extract list of mappable events
var loc = [];
$('#map-items div').each( function () {
var item = $( this );
loc.push( [
item.html(),
item.data('latitude'),
item.data('longitude'),
item.data('icon')
] );
} ).remove();
{% if all and not args.akid %}
// akids in "all" may be empty because of server-side cache,
// so substitute in any id from request args
if (actionkit.args.akid) {
// escape() prevents this from being an xss vector
var akid_arg = 'akid=' + escape(actionkit.args.akid) + '&';
for (var i=0; i<loc.length; i++) {
// relies on exactly how the links are written above
loc[i][0] = loc[i][0].replace(/akid=&/g, akid_arg);
}
}
{% endif %}
// Initialize the map
var map = L.map('map').setView( [
{{ map_events.0.latitude }},
{{ map_events.0.longitude }}
], {% if all %}2{% else %}12{% endif %} );
L.tileLayer(
'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 19,
attribution: '© <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'
}).addTo(map);
// Plot markers
var markers = L.markerClusterGroup({maxClusterRadius: 20});
var icon = {
open_for_signup: L.icon({
iconUrl: '/media/modern/blue_marker.png',
iconSize: [30, 50],
iconAnchor: [15, 50]
}),
not_open_for_signup: L.icon({
iconUrl: '/media/modern/grey_marker.png',
iconSize: [30, 50],
iconAnchor: [15, 50]
})
};
var marker_items = [];
for(var i=0; i<loc.length; i++) {
marker_items.push(
L.marker(
[loc[i][1], loc[i][2]], {icon: icon[loc[i][3]]}
).bindPopup(loc[i][0])
);
}
markers.addLayers(marker_items);
map.addLayer(markers);
}
setTimeout( draw_map(), 0.01 );
</script>
{% endif %}
{% for event in events %}
{% if "Global" in event.mode or not all %}
<div class="ak-field-box {% if event.is_in_past or event.is_full %}ak-event-disabled{% endif %}">
<div class="ak-info-column">
<p class="ak-event-title">
<a href="/event/{{ event.campaign.local_name }}/{{event.id}}/signup/?akid={{args.akid}}&source={{args.source}}{% if campaign.id != event.campaign.id %}&search_campaign={{ campaign.name }}{% endif %}" {% if event.public_title_is_from_campaign %}class="ak-campaign-title"{% endif %}>
{{ event.public_title }}
</a>
</p>
{% if event.campaign.show_venue and event.venue %}
<span class="ak-event-venue">{{ event.venue }}</span>
{% endif %}
{% if event.search_show_address1 %}
<div class="ak-event-address1">{{ event.address1 }}</div>
{% endif %}
{% if event.search_show_general_location %}
<div class="ak-event-city-etc">{{ event.search_general_location }}</div>
{% endif %}
{% if event.has_distance %}
<p><span class="ak-event-distance">{{ event.distance_str }} away</a></span></p>
{% endif %}
<table cellspacing="0" class="ak-event-table">
{% if event.starts_at %}
<tr class="ak-event-time">
<th>When:</th>
<td>{{ event.starts_at_dt|date:"l, F jS, g:i a" }} {% if "Global" in event.mode %}{{ event.local_timezone|timezone_display }}{% endif %}</td>
</tr>
{% endif %}
{% if event.campaign.show_directions and event.directions %}
<tr class="ak-event-directions">
<th>
{% if event.is_virtual %}
To connect:
{% else %}
Directions:
{% endif %}
</th>
<td style="word-break: break-word; hyphens: auto">{{ event.directions|urlize }}</td>
</tr>
{% endif %}
{% if event.campaign.show_attendee_count %}
<tr class="ak-event-attendee-count">
<th>Attendee count:</th>
<td>{{ event.attendee_count }} attendee{{ event.attendee_count|pluralize }}</td>
</tr>
{% endif %}
</table>
</div>
<div class="ak-description-column" style="width: 100%">
{% if event.campaign.show_public_description %}
{% if event.public_description %}
<p class="ak-event-description">{{ event.public_description|linebreaksbr }}</p>
{% endif %}
{% endif %}
</div>
</div>
{% endif %}
{% endfor %}
{% endif %}
{% if campaign.public_create_page %}
<div>
<a class="ak-button ak-event-create" href="/event/{{ campaign.name }}/create/">Create your own event</a>
</div>
{% endif %}
{% endif %}
{% if errors|length %}
<ul id="ak-errors">
{% for key,val in errors.items %}
<li>{{ val|nth:0 }}</li>
{% endfor %}
</ul>
{% endif %}
{% endfilter %}
Inline Tell-a-Friend¶
Tell-a-friend widget layout and code for display on petition page (see thanks.html for thanks page taf layout and code).
{% if page.followup.send_taf %}
<div class="ak-inline-taf">
<div id="ak-fieldbox-taf_emails" class="ak-field">
<label for="id_taf_emails">
{% filter ak_text:"inline_taf_ask" %}Optional: enter friends' email addresses to send them this page{% endfilter %}
</label>
<textarea id="id_taf_emails" name="taf_emails" style="margin-bottom: 0px;"></textarea>
</div>
<div id="ak-inline-taf-link">
<a href="#" onclick="$('#ak-inline-taf-link').hide(); $('#ak-inline-taf-label, #ak-inline-taf-preview').show(); return false;">{% filter ak_text:"taf_preview_link" %} + Preview message to friends/add note{% endfilter %}</a>
</div>
<div id="ak-inline-taf-label" class="ak-nodisplay">
{% filter ak_field_label:"taf_preview" %}Message to friends{% endfilter %}
</div>
<div id="ak-inline-taf-preview" class="ak-field ak-nodisplay">
<div class="taf_subject">
<strong>{{ "Subject"|ak_field_label:"subject"|capfirst }}:</strong>
{% include_tmpl page.followup.taf_subject escaped %}
</div>
<div>
<label for="id_taf_note">
{% filter ak_field_label:"taf_note" %}Optional: Add a short note to the message{% endfilter %}
</label>
<textarea id="id_taf_note" name="taf_note"></textarea>
</div>
<div>
{% filter referring_akid:akid|tag_links:"source=taf"|linebreaksbr %}{% include_tmpl page.followup.taf_body escaped %}{% endfilter %}
</div>
</div>
</div>
{% endif %}
Language Picker¶
Display of the page translations associated with each other through sharing the same multilingual campaign.
{% if can_switch_lang %}
{% with page.translations as translations %}
<!-- Remove this if you don't want popins like "This page also in English" -->
<span style="ak-lang-popin"></span>
<span style="display: block; float: right;" class="ak-language-list">
{% for translated_page in translations %}
{% if translated_page.id == page.id %}
<span class="disabled-lang">{{ translated_page.lang.name|default:"English" }}</span>
{% else %}
<a class="lang" href="{{ translated_page.derived.canonical_path }}{% for name, value in args.items %}{% if forloop.first %}?{{ name }}={{ value }}{% else %}&{{ name }}={{ value }}{% endif %}{% endfor %}">{{ translated_page.lang.name|default:"English" }}</a>
{% endif %}
{% if not forloop.last %}
•
{% endif %}
{% endfor %}
</span>
{% endwith %}
{% endif %}
Letter¶
Letter page layout.
{% extends "./wrapper.html" %}
{% block content %}
<form class="ak-form" name="act" method="POST" action="/act/" accept-charset="utf-8">
<input type="hidden" name="page" value="{{ page.name }}">
<div class="ak-grid-row">
<div class="ak-grid-col ak-grid-col-12-of-12">
<h2>{{ page.title }}</h2>
</div>
</div>
<div class="ak-grid-row">
<div class="ak-grid-col ak-grid-col-8-of-12">
<div id="letter-story">
<div class="ak-text-expander">{% include_tmpl form.about_text %}</div>
<a href="#" class="ak-read-more ak-mobile" data-lines="10">Read more</a>
{% if form.statement_leadin %}
<div class="ak-p-before-textarea ak-margin-top-3">
{% include_tmpl form.statement_leadin %}
</div>
{% endif %}
<div class="ak-margin-bottom-1 ak-styled-fields">
<textarea id="id_comment" name="action_comment" class="ak-letter-text ">{% include_tmpl form.letter_text escaped %}</textarea>
</div>
</div>
</div>
<div class="ak-grid-col ak-grid-col-4-of-12">
{% include "./progress_meter.html" %}
{% if page.custom_fields.featured_image %}
<img class="ak-featured-img" src="{{page.custom_fields.featured_image}}">
{% endif %}
<h3>Send the letter</h3>
<div id="letter-form" class="ak-field-box ak-styled-fields {{templateset.custom_fields.field_labels_class|default:"ak-labels-overlaid"}} {{templateset.custom_fields.field_errors_class|default:"ak-errs-below"}}">
{% include "./user_form_wrapper.html" %}
{# Optional TAF {% include "./inline_tellafriend.html" %} #}
<button type="submit" class="ak-submit-button">Send Letter</button>
</div>
</div>
</div>
</form>
{% endblock %}
Letter to the Editor (LTE)¶
Letter to the editor page layout.
{% extends "./wrapper.html" %}
{% block script_additions %}
<script type="text/javascript">
function toggleChooser(on) {
var name,
to_row = $("#to_target_row"),
media_target = $("#media_target"),
lte_letter = $('#lte-letter, #lte-submit');
if (on) {
media_target.fadeIn('fast');
//lte_letter.fadeOut('fast');
to_row.fadeOut('fast');
$("input[name=media_target]:checked").attr('checked', false);
} else {
media_target.fadeOut('fast');
lte_letter.fadeIn('fast');
to_row.fadeIn('slow');
name = $("input[name=media_target]:checked").closest(".ak-newspaper-row").find('.ak-newspaper-title a').html();
$("#to_target_name").html("Editor, " + name);
$("html body").scrollTop($("form.ak-form").position().top);
}
}
// adapted from http://blog.themeforest.net/tutorials/creating-a-jquery-word-counter/
function countWords(textarea) {
//console.log('count words running');
var countControl = ( '' + $(textarea).data('wordcount') ).split(',');
var minWords = 0;
var maxWords = 0;
if(countControl.length > 1) {
minWords = countControl[0];
maxWords = countControl[1];
} else {
maxWords = countControl[0];
}
var countArea = $(textarea).siblings(".ak-counter-area");
var countDigits = countArea.children('.ak-counter-words');
var update_func = function() {
// console.log('countWords update_func');
var numWords = jQuery.trim($(textarea).val()).split(/\s+/).length;
if($(textarea).val() === '') {
numWords = 0;
}
countDigits.text(numWords);
if(numWords < minWords || (numWords > maxWords && maxWords != 0)) {
countDigits.addClass('ak-color-error');
} else {
countDigits.removeClass('ak-color-error');
}
};
update_func();
$(textarea).bind('keyup click blur focus change paste', update_func);
}
function abbreviate(name, maxLength) {
return name.length <= maxLength ?
name : name.substring(0, maxLength - 3) + "...";
}
$(window).load( function() {
$('.ak-accordion>ul>li').children(':not(.ak-accordion-head)').hide();
$(".ak-accordion .ak-accordion-head").on('click', function() {
var section = $(this).parent();
section.toggleClass('active');
section.children(':not(.ak-accordion-head)').slideToggle();
} );
$('.ak-accordion .ak-accordion-head').append(
'<span class="ak-arrow-holder"><span class="ak-arrow"></span></span>'
);
$("input[name=media_target]").change( function() {
toggleChooser(false);
return false;
} );
$('#ak-newspaper-change').click( function() {
toggleChooser(true);
return false;
} );
/*If there is an error on form submission, make sure the page reloads to stay on the form*/
if ($('ul.compact:contains("letter")').length){
toggleChooser(false);
}
} );
</script>
{% endblock %}
{% block content %}
<form class="ak-form" name="act" method="POST" action="/act/" accept-charset="utf-8">
<input type="hidden" name="page" value="{{ page.name }}">
<div class="ak-grid-row">
<div class="ak-grid-col ak-grid-col-12-of-12">
<h2>{{ page.title }}</h2>
</div>
</div>
<div class="ak-grid-row">
<div class="ak-grid-col ak-grid-col-6-of-12">
{% if page.custom_fields.featured_image %}
<img class="ak-featured-img" src="{{page.custom_fields.featured_image}}">
{% endif %}
<div class="ak-styled-description ak-text-expander">
{% include_tmpl form.introduction_text %}
</div>
<a href="#" class="ak-read-more ak-mobile" data-lines="10">Read more</a>
<div id="lte-prelim"></div>
<div id="ak-lte-help" class="ak-accordion"></div>
<script type="text/ak-template" for="ak-lte-help">
<ul>
{% if form.talking_points %}
<li>
<div class="ak-accordion-head">
Talking Points
</div>
<div>
{% include_tmpl form.talking_points %}
</div>
</li>
{% endif %}
{% if form.writing_tips %}
<li>
<div class="ak-accordion-head">
Writing Tips
</div>
<div>
{% include_tmpl form.writing_tips %}
</div>
</li>
{% endif %}
{% for letter in form.cannedletter_set.all %}
<li>
<div class="ak-accordion-head">
Sample: {{ letter.subject|truncateletters:"20" }}
</div>
<div>
{% if letter.subject|length > 20 %}
<p><b>{{letter.subject}}</b></p>
{% endif %}
{{letter.letter_text|linebreaks}}
</div>
</li>
{% endfor %}
</ul>
</script>
</div>
<div class="ak-grid-col ak-grid-col-6-of-12">
{% include "./progress_meter.html" %}
<div class="ak-styled-fields {{templateset.custom_fields.field_labels_class|default:"ak-labels-overlaid"}} {{templateset.custom_fields.field_errors_class|default:"ak-errs-below"}}">
<div id="ak-need-contact-info"></div>
<script type="text/ak-template" for="ak-need-contact-info">
[% if (incomplete) { %]
<div class="ak-instructions ak-faded-text">
{% filter ak_text:"lte_needs_contact_info" %}
Please enter your information so we can find newspapers for you to contact.
{% endfilter %}
</div>
[% } %]
</script>
{% include "./user_form_wrapper.html" %}
</div>
<div id="media_target"></div>
<script type="text/ak-template" for="media_target">
[% if (!incomplete) { %]
<p>Choose a newspaper to send a letter to:</p>
[%
var headers = {
"local": "Local Newspapers",
"regional": "Regional Newspapers",
"national": "National Newspapers"
};
var mediaTargets = actionkit.context.mediaTargets || {};
var mediaTargetTypes = ['national', 'regional', 'local'];
for (var j = 0; j < mediaTargetTypes.length; j++) {
var mediaTargetType = mediaTargetTypes[j];
var targetsOfType = mediaTargets[mediaTargetType];
if (targetsOfType) {
%]
<div class="ak-newspaper">
<h3>[%=headers[mediaTargetType]%]</h3>
</div>
[%
var shade = true;
for (var i = 0; i < targetsOfType.length; i++) {
var mediaTarget = targetsOfType[i],
targetId = "media_target_" + mediaTarget.id,
name = abbreviate(mediaTarget.name, 30),
label = "<a>" + name + "</a>";
if (mediaTarget.website_url) {
label = "<a class=\"ak-highlight-on-hover\" target=\"_blank\" href=\"" + mediaTarget.website_url + "\">" + name + "</a>";
}
shade = !shade;
%]
<div class="[%= shade ? "ak-alternate-row" : "" %] ak-newspaper-row">
<div class="ak-newspaper-title">[%=label|safe%]</div>
<div>
<label class="ak-button ak-newspaper-choice" for="[%=targetId%]">
<input class="media_target" id="[%=targetId%]" value="[%=mediaTarget.id%]" type="radio" name="media_target">
Select
</label>
</div>
<div class="ak-faded-text">
<div class="number">
<strong>Circulation:</strong>
[%= actionkit.utils.add_commas(mediaTarget.circulation) %]
</div>
[% if (actionkit.context.show_phones && mediaTarget.phone) { %]
<div class="nowrap">
<strong>Phone:</strong>
[%=mediaTarget.phone%]
</div>
[% } %]
<div class="number">
<strong>Sent:</strong>
[%=mediaTarget.sent%]
</div>
</div>
</div>
[%
}
}
}
} %]
</script>
<div id="lte-letter" style="display: none;"></div>
<script type="text/ak-template" for="lte-letter">
[% if (!incomplete) { %]
<table class="ak-styled-fields ak-message-form">
<tr id="to_target_row">
<th>
<label>
To
</label>
</th>
<td>
<div class="ak-readonly-value">
<span id="to_target_name"></span>
<a id="ak-newspaper-change" href="#">Change</a>
</div>
</td>
</tr>
<tr>
<th>
<label for="letter_subject" >
Subject
</label>
</th>
<td>
<input id="letter_subject" type="text" name="subject" size="40">
</td>
</tr>
<tr>
<th>
<label for="letter_text" >
Message
</label>
</th>
<td>
<textarea id="letter_text" name="letter_text" class="ak-large-message" data-wordcount="250,350"></textarea>
<div class="ak-counter-area">
<span style="font-weight: bold" class="ak-counter-words">0</span> Words.
Most newspapers only consider letters of 250 to 350 words.
</div>
</td>
</tr>
<tr>
<th> </th>
<td>Your name, address and phone number will be added as a signature.</td>
</tr>
</table>
[% } %]
</script>
<div id="lte-submit">
<button type="submit" class="ak-submit-button">Submit</button>
</div>
</div>
</div>
</form>
<div id="na"></div>
<script type="text/ak-template" for="na">
[%
/* Done inside an ak-template to ensure this executes after other ak-templates. */
if (!incomplete) {
countWords($("[data-wordcount]")[0]);
$('#lte-submit').hide()
}
%]
</script>
{% endblock %}
Login¶
Login page including error messages.
{% extends "./wrapper.html" %}
{% block content %}
<div class="ak-grid-row">
<div class="ak-grid-col ak-grid-col-4-of-12 ak-grid-centered">
<h2>Log In</h2>
<div class="area">
{% if error_message %}
<p class="errornote">{{ error_message }}</p>
{% endif %}
{% if invalid %}
<p class="errornote">Incorrect email or password. Try again, or <a href="{% url 'user_password_forgot' %}?next={{ next }}&email={{ email }}">we can email you a link to reset your password</a>.</p>
{% endif %}
<div id="content-main">
{% if no_password %}
<p>It looks like you've never logged in before. <a href="{% url 'user_password_forgot' %}?email={{ email }}">Click here to set up a password.</a>.</p>
{% endif %}
{% if wrong_account %}
<p>It looks like you may need another email address to view that page, or the page may no longer be accessible.</p>
{% endif %}
<form action="{{ app_path }}" method="post" id="login-form" name="login-form">
<input type="hidden" name="this_is_the_login_form" value="1">
<input type="hidden" name="next" value="{{ next }}">
<input type="hidden" name="required" value="password">
<div class="ak-styled-fields ak-labels-above ak-errs-below ak-clearfix">
<div>
<label for="id_email">Email</label>
<input type="text" name="email" value="{{ email }}" id="id_email" class="ak-full-width">
</div>
<div>
<label for="id_password">Password</label>
<input type="password" name="password" id="id_password" class="ak-full-width">
</div>
<button type="submit" class="ak-submit-button">Log In</button>
</div>
<div>
<a href="{% url 'user_password_forgot' %}?next={{ next }}&email={{ email }}">Forgot your password?</a>
</div>
<div>
<a href="{% url 'user_password_forgot' %}?next={{ next }}&first=1&email={{ email }}">Never logged in before?</a>
</div>
</form>
</div>
</div>
</div>
</div>
{% endblock %}
{% block below_form %}
<script>
actionkit.forms.contextRoot = '/context/';
actionkit.forms.initValidation('login-form');
document.getElementById('id_{% if email %}password{% else %}email{% endif %}').focus()
</script>
{% endblock %}
Logout¶
Page shown when a user logs out.
{% extends "./wrapper.html" %}
{% block content %}
<div class="ak-grid-row">
<div class="ak-grid-col ak-grid-col-4-of-12 ak-grid-centered">
<h2>Logged Out</h2>
<p>You have been signed out!</p>
<div class="ak-margin-top-3 ak-margin-bottom-3">
<a class="ak-button ak-full-width" href="/login/">Log In Again</a>
</div>
</div>
</div>
{% endblock %}
Password¶
Page displayed if user clicks that they forgot or never set their password. Prompts reset_password_email.html.
{% extends "./wrapper.html" %}
{% block content %}
<div class="ak-grid-row">
<div class="ak-grid-col ak-grid-col-4-of-12 ak-grid-centered">
{% if message %}
<p class="ak-large-text">{{ message }}</p>
{% else %}
{% if first %}
<p>Fill out your email below and we'll send you a link to set up a password so you can log in.</p>
{% else %}
<p>Fill out the form below and we'll send you a link to reset your password.</p>
{% endif %}
<form action="{{ app_path }}" method="post" id="login-form" name="login-form" class="ak-styled-fields ak-labels-above ak-errs-below">
{{ form.non_field_errors }}
{% for field in form.visible_fields %}
<div>
<label for="{{ field.id_for_label }}">
{{ field.label }}
</label>
{{ field }}
{{ field.errors }}
</div>
{% endfor %}
{% for field in form.hidden_fields %}
{{ field }}
{% endfor %}
<div class="submit-row">
<button type="submit" class="ak-submit-button">Send</button>
</div>
</form>
{% endif %}
</div>
</div>
{% endblock %}
{% block script_additions %}
<script type="text/javascript">
$( function () {
var email_field = $('#id_email');
email_field.focus();
var email_from_url = {{ email|json }};
if (email_from_url) {
email_field.val( email_from_url ).change();
}
} );
</script>
{% endblock %}
{% block below_form %}
<script>
actionkit.forms.contextRoot = '/context/';
actionkit.forms.initValidation('login-form');
</script>
{% endblock %}
Petition¶
Petition page layout.
{% extends "./wrapper.html" %}
{% block content %}
<form class="ak-form" name="act" method="POST" action="/act/" accept-charset="utf-8">
<input type="hidden" name="page" value="{{ page.name }}">
<div class="ak-grid-row">
<div class="ak-grid-col ak-grid-col-12-of-12">
<h2>{{ page.title }}</h2>
</div>
</div>
<div class="ak-grid-row">
<div class="ak-grid-col ak-grid-col-7-of-12">
{% if page.custom_fields.featured_image or form.about_text %}
<div id="ak-petition-story">
{% if page.custom_fields.featured_image %}
<img class="ak-featured-img {% if page.goal %}ak-margin-top-1{% endif %}" src="{{page.custom_fields.featured_image}}">
{% endif %}
<div class="ak-text-expander">{% include_tmpl form.about_text %}</div>
<a href="#" class="ak-read-more ak-mobile" data-lines="10">Read more</a>
</div>
{% else %}
{% if form.statement_leadin %}
<div class="ak-petition-leadin">
{% include_tmpl form.statement_leadin %}
</div>
{% endif %}
<div class="ak-margin-bottom-1 ak-text-expander">
{% include_tmpl form.statement_text %}
</div>
<a href="#" class="ak-read-more ak-mobile" data-lines="10">Read more</a>
{% endif %}
</div>
<div class="ak-grid-col ak-grid-col-5-of-12">
{% include "./progress_meter.html" %}
<div class="statement-text-wrapper ak-field-box ak-field-box-borderless">
<h3>Sign the petition</h3>
{% if page.custom_fields.featured_image or form.about_text %}
{% if form.statement_leadin %}
<div class="ak-petition-leadin">
{% include_tmpl form.statement_leadin %}
</div>
{% endif %}
<div class="ak-margin-bottom-1">
{% include_tmpl form.statement_text %}
</div>
{% endif %}
<div id="petition-form" class="ak-styled-fields {{templateset.custom_fields.field_labels_class|default:"ak-labels-overlaid"}} {{templateset.custom_fields.field_errors_class|default:"ak-errs-below"}}">
{% include "./user_form_wrapper.html" %}
<div class="ak-field">
<label for="id_comment">Comment</label>
<textarea id="id_comment" name="action_comment"></textarea>
</div>
{# Optional TAF {% include "./inline_tellafriend.html" %} #}
<button type="submit" class="ak-submit-button">Sign</button>
</div>
</div>
</div>
</div><!--gridrow-->
</form>
{% endblock %}
Petition Download¶
Don't use. Page that sets display of errors and choices in the admin for generating a PDF petition.
{% extends "./wrapper.html" %}
{% block title %}
Download constituent comments and signatures
{% endblock %}
{% block script_additions %}
<script>
function showStatus(details) {
if ( details.status == 'error' ) {
var error = details.error.replace(/\n/g, '<br>');
$('#task-status').addClass('ak-err').html(
'Error: ' + (error || generic_error)
);
window.clearInterval(statusCheckTimer);
}
if ( details.status == 'complete' ) {
var download_url = (
'/constituents/finish_download/'
+ '?akid={{user.token}}&backgroundtask_id={{backgroundtask.id}}'
+ '&_rand=' + Math.random()
)
$('#task-status').html('<a href="' + download_url + '">Your file is ready! Click here to download.</a>');
window.clearInterval(statusCheckTimer);
}
if ( details.status == 'failed' ) {
$('#task-status').html('<b>Sorry, there was an error preparing your file</b>');
window.clearInterval(statusCheckTimer);
}
}
function checkStatus() {
actionkit.forms.createScriptElement(
'/constituents/check_download/'
+ '?akid={{user.token}}&backgroundtask_id={{backgroundtask.id}}'
+ '&_rand=' + Math.random()
);
}
</script>
{% endblock %}
{% block content %}
<div class="ak-grid-row">
<div class="ak-grid-col ak-grid-col-12-of-12">
{% if fmt %}
{% comment %}
Monitor the status of the PDF job, and
provide a download link when it's done.
{% endcomment %}
<h2>Download Constituent Signatures And Comments</h2>
<h2 id="task-status">We're preparing your file now...</h2>
<script>
actionkit.forms.initForm = function() {} // not an action form
statusCheckTimer = window.setInterval(checkStatus, 5000);
checkStatus();
</script>
{% else %}
{% comment %}
Need to pick format
{% endcomment %}
<h2>Choose Download Format</h2>
<ul>
<li>
<a href="?akid={{user.token}}&job_id={{job.id}}&fmt=pdf">
Download printable PDF
</a>
</li>
<li>
<a href="?akid={{user.token}}&job_id={{job.id}}&fmt=csv">
Download spreadsheet in CSV format (Excel-compatible)
</a>
</li>
</ul>
{% endif %}
</div>
</div>
{% endblock %}
Progress Meter¶
Thermometer layout and code. Included in any page where you enter a goal when creating the page.
{% if page.goal %}
<!-- Begin progress meter code.-->
<div id="progress" class="ak-progress-meter"></div>
<script type="text/ak-template" for="progress">
[% with (progress) { %]
[% if ( goal && total ) { %]
[% progress.current = goal_type == 'dollars' ? total.dollars : goal_type == 'money' ? total.money : total.actions; %]
[% progress.percent = parseInt(progress.current/goal*100); %]
<div class="ak-progress-holder">
<div class="ak-progress-meter-border">
<div class="ak-progress-bar" style="width: [%= progress.current > goal ? 100 : progress.percent %]%;"> </div>
</div>
</div>
<div class="ak-clearfix">
<span class="ak-progress-percent">[%= progress.percent %]%</span>
<div class="ak-progress-goals">
[% if (goal_type == "dollars") { %]
<span class="ak-progress-actions">
$[%= add_commas(total.dollars) %] raised so far
</span> <br>
of our goal of $[%= add_commas(goal) %]!
[% } else if (goal_type == "money") { %]
<span class="ak-progress-actions">
{{ page.currency|iso_currency_symbol }}[%= add_commas(total.money) %] raised so far
</span> <br>
of our goal of {{ page.currency|iso_currency_symbol }}[%= add_commas(goal) %]!
[% } else { %]
<span class="ak-progress-actions">
[%= add_commas(total.actions) %] [%= total.actions != 1 ? 'actions' : 'action' %] taken so far
</span> <br>
of our goal of [%= add_commas(goal) %]!
[% } %]
</div>
</div>
[% } %]
[% } %]
</script>
<input type="hidden" name="want_progress" value="1">
<!-- End progress meter code -->
{% endif %}
Recurring Cancel¶
Page where users with a recurring profile can cancel future payments. Users access it from recurring_update.html.
{% extends "./wrapper.html" %}
{% block content %}
<div class="ak-grid-row">
<div class="ak-grid-col ak-grid-col-12-of-12">
<h2>{{ page.title }}</h2>
</div>
<div>
<p id="unknown_user"></p>
<p id="known_user"></p>
<p>Logged in as {{ logged_in_user.name }}. <a href="/logout/">Log out</a></p>
</div>
</div>
<div class="ak-grid-row ak-grid-row-inverted">
{% if page.custom_fields.featured_image %}
<div class="ak-grid-col ak-grid-col-3-of-12">
<img class="ak-featured-img" src="{{page.custom_fields.featured_image}}">
</div>
{% endif %}
<div class="ak-grid-col {% if page.custom_fields.featured_image %}ak-grid-col-9-of-12{% else %}ak-grid-col-12-of-12{% endif %}">
{% if not active %}
<p>You don't have any active recurring donations.</p>
{# We have to have a form, or the JavaScript doesn't work. #}
<form class="action_form" name="act" method="POST" action="/act/" accept-charset="utf-8">
<ul class="compact" id="ak-errors"></ul>
<input type="hidden" name="page" value="{{ page.name }}">
</form>
{% else %}
<p>{% include_tmpl form.please_stay_text %}</p>
{% for profile in active %}
<div class="ak-field-box ak-styled-fields ak-labels-before">
<form class="action_form" name="act" method="POST" action="/act/" accept-charset="utf-8">
<input type="hidden" name="akid" value="{{ logged_in_user.token }}">
<input type="hidden" name="page" value="{{ page.name }}">
<input type="hidden" name="profile_id" value="{{ profile.id }}">
<div>
<label>
Next Payment
</label>
<div class="ak-readonly-value">
<div>
{{ profile.next_payment_date|date }}
</div>
</div>
</div>
<div class="ak-show-amount">
<label>
Monthly Amount
</label>
<div class="ak-readonly-value">
<div>
{{ profile.amt }}
</div>
</div>
</div>
<div>
<label>
First Payment
</label>
<div class="ak-readonly-value">
<div>
{{ profile.created_at|date }}
</div>
</div>
</div>
{% if profile.order.payment_method == "cc" %}
<div class="ak-show-cc">
<label>
Credit Card
</label>
<div class="ak-readonly-value">
<div>
Card ending in {{ profile.card_num }}
<br>
Expiration {{ profile.display_expiration_date }}
</div>
</div>
</div>
{% endif %}
<div><button type="submit" class="ak-normal">Cancel Donation</button></div>
</form>
</div>
{% endfor %}
</div>
{% endif %}
</div>
{% endblock %}
Recurring Info¶
Information about a recurring profile. Used in recurring_update.html template.
{% with profile.payment_processor_information as pp %}
<form id="change_profile_{{ profile.id }}" {% if pp.processor == "stripe" %}data-stripe-pub-key="{{ pp.pub_key }}"{% endif %} class="action_form" name="act_{{ profile.id }}" method="POST" action="/act/" accept-charset="utf-8" onsubmit="return true;">
<input type="hidden" name="page" value="{{ page.name }}">
<input type="hidden" name="profile_id" value="{{ profile.id }}">
{% comment %} akid is needed to tell javascript required field checking we have a user, but the view requires a user to be logged in. {% endcomment %}
<input type="hidden" name="akid" value="{{ logged_in_user.token }}">
<div class="ak-field-box">
<div class="ak-styled-fields ak-labels-before {{templateset.custom_fields.field_errors_class|default:"ak-err-above"}}">
{% once %}<ul id="ak-errors"></ul>{% endonce %}
<ul class="ak-errors"></ul>
<div>
<label>
Next Payment
</label>
<div class="ak-readonly-value">
<div>
{{ profile.next_payment_date|date }}
</div>
{% if not profile.is_import_stub %}
<div>
<a href = "/cms/pledge/cancel/monthly/">Cancel donation</a>
</div>
{% endif %}
</div>
</div>
<div class="ak-show-amount">
<label>
{{ profile.get_period_display }} Amount
</label>
<div class="ak-readonly-value">
<div>
{{ profile.amt }}
</div>
<div>
{%if not profile.is_import_stub %}<a href="#" onclick="return ak_recurring_change_amount('{{ profile.id }}');" class="ak-change-amount-link">Change amount</a>{% endif %}
</div>
</div>
</div>
<div class="ak-change-amount" style="display: none">
<label>
{{ profile.get_period_display }} Amount
</label>
<input type="text" name="amount" size="6" value="{{ profile.amount }}">
</div>
<div>
<label>
First Payment
</label>
<div class="ak-readonly-value">
<div>
{{ profile.first_payment_date|date }}
</div>
</div>
</div>
{% if profile.order.payment_method == "cc" %}
<div class="ak-show-cc">
<label>
Credit Card
</label>
<div class="ak-readonly-value">
<div>
Card ending in {{ profile.card_num }}
<br>
Expiration {{ profile.display_expiration_date }}
</div>
<div>
{%if not profile.is_import_stub %} <a href="#" onclick="return ak_recurring_change_card('{{ profile.id }}');">Change credit card information</a>{% endif %}
</div>
</div>
</div>
<div class="ak-change-cc" style="display: none">
<label for="card_num_{{ profile.id }}">
Credit Card Number
</label>
<input id="card_num_{{ profile.id }}" type="text" name="card_num" disabled=true>
<div class="ak-card_num-hosted"></div>
</div>
<div class="ak-change-cc" style="display: none">
<label for="exp_date_{{ profile.id }}">
Expiration Date
</label>
<input id="exp_date_{{ profile.id }}" type="text" name="exp_date" size="6" placeholder="MMYY" style="max-width: 33%" disabled=true>
<div class="ak-exp_date-hosted"></div>
</div>
<div class="ak-change-cc" style="display: none">
<label for="card_code_{{ profile.id }}">
Verification Number
</label>
<input id="card_code_{{ profile.id }}" type="text" name="card_code" size="6" style="max-width: 33%" disabled=true>
<div class="ak-card_code-hosted"></div>
</div>
{% endif %}
{% if profile.is_ach %}
<input type="hidden" name="payment_method" value="ach">
<input type="hidden" name="first_name" value="{{ user.first_name }}">
<input type="hidden" name="last_name" value="{{ user.last_name }}">
<div class="ak-show-cc">
<label>
Bank Account
</label>
<div class="ak-readonly-value">
<div>
{% if profile.card_num %}
Account ending in {{ profile.card_num }}
{% endif %}
</div>
<div>
{%if not profile.is_import_stub %} <a href="#" onclick="return ak_recurring_change_card('{{ profile.id }}');">Change bank information</a>{% endif %}
</div>
</div>
</div>
<div class="ak-change-cc" style="display: none">
<label for="ak-routing_number_{{ profile.id }}">
Routing Number
</label>
<input id="ak-routing_number_{{ profile.id }}" type="text" name="routing_number" size="9" style="max-width: 33%" onvalidate="return valid_bank_routing_number(this.value)" disabled=true>
<input type="hidden" name="required" value="routing_number"/>
</div>
<div class="ak-change-cc" style="display: none">
<label for="ak-bank_account_{{ profile.id }}">
Bank Account
</label>
<input id="ak-bank_account_{{ profile.id }}" type="text" name="bank_account" size="17" style="max-width: 33%" onvalidate="return valid_bank_account_number(this.value)" disabled=true>
<input type="hidden" name="required" value="bank_account"/>
</div>
<div class="ak-change-cc" style="display: none">
<label for="ak-account_type_{{ profile.id }}">
Account Type
</label>
<select id="ak-account_type_{{ profile.id }}" type="text" name="account_type" style="max-width: 33%" disabled=true>
<option value="checking">checking</option>
<option value="savings">savings</option>
</select>
</div>
<div class="ak-change-cc" style="display: none">
<label for="ak-ownership_type_{{ profile.id }}">
Ownership Type
</label>
<select id="ak-ownership_type_{{ profile.id }}" type="text" name="ownership_type" style="max-width: 33%" onvalidate="return validate_business_name(this)" disabled=true>
<option value="personal">personal</option>
<option value="business">business</option>
</select>
</div>
<div class="ak-change-cc ak-business_name" style="display: none">
<label for="ak-business_name_{{ profile.id }}">
Business Name
</label>
<input id="ak-business_name_{{ profile.id }}" type="text" name="business_name" disabled=true>
</div>
{% endif %}
{% if profile.order.payment_method == "cc" or profile.is_ach %}
<div class="ak-show-address" style="display: none">
<label>
Address
</label>
<div class="ak-readonly-value">
<div class="ak-full-address">{{ profile.user.full_address }}</div>
{% if pp.recurring_update_supports_address %}
<div>
<a href="#" onclick="return ak_recurring_change_address('{{ profile.id }}');">Change billing information</a>
</div>
{% endif %}
</div>
</div>
{% if pp.recurring_update_supports_address %}
<div class="ak-change-address" style="display: none">
{% if not profile.is_ach %}
<div style="text-align: center">
Optionally also enter your credit card billing address:
</div>
{% endif %}
<div>
<label for="id_address1_{{ profile.id }}">
Street Address
</label>
<input name="address1" id="id_address1_{{ profile.id }}" type="text" value="{{ profile.order.user_detail.address1 }}" disabled=true>
{% if profile.is_ach %}
<input type="hidden" name="required" value="address1"/>
{% endif %}
</div>
<div>
<label for="id_city_{{ profile.id }}">
City
</label>
<input name="city" id="id_city_{{ profile.id }}" type="text" value="{{ profile.order.user_detail.city }}" disabled=true>
{% if profile.is_ach %}
<input type="hidden" name="required" value="city"/>
{% endif %}
</div>
<div class="state_select_box">
<label>
State
</label>
{% include "./state_select.html" %}
{% if profile.is_ach %}
<input type="hidden" name="required" value="state"/>
{% endif %}
</div>
<div>
<label for="id_zip_{{ profile.id }}">
ZIP Code
</label>
<input name="zip" id="id_zip_{{ profile.id }}" type="text" value="{{ profile.order.user_detail.zip }}" disabled=true>
{% if profile.is_ach %}
<input type="hidden" name="required" value="zip"/>
{% endif %}
</div>
{% if not profile.is_ach %}
<div>
<label for="id_region_{{ profile.id }}">
Region
</label>
<input name="region" id="id_region_{{ profile.id }}" type="text" value="{{ profile.order.user_detail.region }}" disabled=true>
</div>
<div>
<label for="id_postal_{{ profile.id }}">
Postal
</label>
<input name="postal" id="id_postal_{{ profile.id }}" type="text" value="{{ profile.order.user_detail.postal }}" disabled=true>
</div>
<div class="country_select_box">
<label>
Country
</label>
{% include "./country_select.html" with onchange="actionkit.forms.setForm(this.form); actionkit.forms.reflectCountryChange();" %}
</div>
{% endif %}
<script>
$(function () {
var profile_el = $("#change_profile_{{ profile.id }}");
{% if profile.order.user_detail.country %}
profile_el.find(".country_select_box select").val("{{ profile.order.user_detail.country }}");
{% endif %}
{% if profile.order.user_detail.state %}
profile_el.find(".state_select_box select").val("{{ profile.order.user_detail.state }}");
{% endif %}
actionkit.forms.initForm('act_{{ profile.id }}');
});
</script>
</div>
{% endif %}
{% endif %}
{% if profile.is_ach %}
<div class="ak-change-cc" style="display: none">
<div class="ak-mandate">By clicking "Save Changes", I authorize Braintree, a service of PayPal, on behalf of <span class="ak-client-name">{% filter ak_text:"org_name" %}{% client_name %}{% endfilter %}</span> (i) to verify my bank account information using bank information and consumer reports and (ii) to debit my bank account.</div>
</div>
{% endif %}
<div class="ak-change-submit ak-align-right" style="display: none">
<button name="submit_form" type="submit" {% if profile.is_ach %}onclick="return ach_validation(this.form);"{% else %}onclick="return disable_invisibles(this.form);"{% endif %}">Save Changes</button>
</div>
</div>
</div>
</form>
{% if pp.use_vzero %}
<script>
initVZeroForForm('#change_profile_{{ profile.id }}', '{{ pp.client_token }}', {% if profile.is_ach %}true{% else %}false{% endif %}, {% if pp.use_3d_secure %}true, {% using profile.payment_nonce_info %}'{{nonce}}', '{{bin}}'{% endusing %}{% else %}false, '', ''{% endif %});
var ownership_type_menu = $('#change_profile_{{ profile.id }} [name=ownership_type]');
if (ownership_type_menu.length) {
ownership_type_menu.change(function() {
if (this.value == 'business') {
$(this.form).find('.ak-business_name').show();
} else {
$(this.form).find('.ak-business_name').hide();
}
});
}
</script>
{% endif %}
{% if pp.use_vgs %}
<script>
var $akForm = $('#change_profile_{{profile.id}}');
var vgsOptions = {form: $akForm[0], token: '{{pp.client_token}}',
rawFieldSelectors: ['#card_num_{{profile.id}}', '#card_code_{{profile.id}}'],
fields: [{selector: '#' + $akForm[0].id + ' .ak-card_num-hosted',
name: 'card_num', type: 'card-number',
placeholder: '', autoComplete: 'cc-number',
color: 'black', fontSize: '15.5px',
successColor: 'green', errorColor: '#d00'}]};
if ($akForm.find('input[name=card_code]').length){
vgsOptions.fields.push({selector: '#' + $akForm[0].id + ' .ak-card_code-hosted',
name: 'card_code', type: 'card-security-code',
placeholder: '', fontSize: '15.5px',
color: 'black', successColor: 'green',
errorColor: '#d00'});
}
$akForm.find('.ak-card_num-hosted, .ak-card_code-hosted')
.addClass('hosted-field');
actionkit.donations.vgs.initClient(vgsOptions);
</script>
{% endif %}
{% endwith %}
Recurring Update¶
Page where users with a recurring profile can update their credit card number or donation amount and access pages to cancel their profile or update their contact info. Requires log in.
{% extends "./wrapper.html" %}
{% load humanize %}
{% block css_additions %}
{% for profile in active %}
{% if profile.payment_processor_information.use_vzero or profile.payment_processor_information.use_vgs %}
{% once %}
<style type="text/css">
.hosted-field {
height: 2.375em;;
display: inline-block;
padding: 7px 7px;
border: 1px solid #ccc;
background-color: white;
}
</style>{% endonce %}
{% endif %}
{% if profile.payment_processor_information.use_vzero %}
{% once %}
<style type="text/css">
.hosted-field.braintree-hosted-fields-invalid {
border-color: {{ templateset.custom_fields.color_error|default:"#d00" }};
background-color: #FFC8C8;
}
</style>
{% endonce %}
{% endif %}
{% if profile.payment_processor_information.use_vgs %}
{% once %}
<style type="text/css">
.hosted-field iframe {width: 100%; height:100%; }
</style>
{% endonce %}
{% endif %}
{% endfor %}
{% endblock %}
{% block script_additions %}
<script language="javascript">
function ak_recurring_change_amount(profile_id) {
var profile_el = $('#change_profile_' + profile_id);
profile_el.find('.ak-show-amount').hide();
profile_el.find('.ak-change-amount').fadeIn();
profile_el.find('.ak-change-submit').fadeIn();
return false;
}
function ak_recurring_change_card(profile_id) {
var profile_el = $('#change_profile_' + profile_id);
profile_el.find('.ak-show-cc').hide();
profile_el.find('.ak-change-cc').not('.ak-business_name').fadeIn();
profile_el.find('.ak-change-address').fadeIn();
profile_el.find('.ak-change-submit').fadeIn();
profile_el.find(':input').prop('disabled', false);
return false;
}
function ak_recurring_change_address(profile_id) {
var profile_el = $('#change_profile_' + profile_id);
profile_el.find('.ak-show-address').hide();
profile_el.find('.ak-change-address').fadeIn();
profile_el.find('.ak-change-submit').fadeIn();
profile_el.find(':input').prop('disabled', false);
return false;
}
$(document).ready(function() {
var match = /profile_id=(\d+)/.exec(window.location.search);
if (match) {
var profile_id = match[1];
if (/error_card_num/.test(window.location.search) ||
/error_address1/.test(window.location.search) ||
/error_city/.test(window.location.search) ||
/error_profile_id/.test(window.location.search)) {
ak_recurring_change_card(profile_id);
} else if (/amount=/.test(window.location.search)) {
ak_recurring_change_amount(profile_id);
}
}
});
</script>
{% for profile in active %}
{% if profile.payment_processor_information.use_accept %}
{% once %}
<script src="/resources/ak_authnet_accept.js"></script>
{% authnet_js_libs %}
<script>
$(function() {
var form = $("#change_profile_{{ profile.id }}").get(0);
options = {
form: form,
submit: $("#change_profile_{{ profile.id }} .ak-change-submit button").get(0),
};
actionkit.authnet.initClient('{{ profile.payment_processor_information.login }}', '{{ profile.payment_processor_information.public_key }}', options);
});
</script>
{% endonce %}
{% endif %}
{% if profile.payment_processor_information.use_vgs %}
{% once %}
<script type="text/javascript" src="https://js.verygoodvault.com/vgs-collect/2.8/vgs-collect.js"></script>
<script type="text/javascript" src="/resources/ak_vgs.js"></script>
{% endonce %}
{% endif %}
{% if profile.payment_processor_information.use_vzero %}
{% once %}
{% braintree_js_libs %}
<script src="/resources/ak_braintree_vzero.js"></script>
<script>
function initVZeroForForm(form_id, clientToken, is_ach, use_3d_secure, nonce, bin) {
var form = document.querySelector(form_id),
options = {
form: form,
fields: {
number: {
selector: form_id + ' .ak-card_num-hosted'
},
cvv: {
selector: form_id + ' .ak-card_code-hosted'
},
expirationDate: {
selector: form_id + ' .ak-exp_date-hosted',
placeholder: 'MM / YYYY'
}
},
styles: {
'input': {
'font-family': '{{ templateset.custom_fields.font_family|default:"sans-serif"|safe }}',
'font-size': '{{ templateset.custom_fields.font_size|default:"16.5px" }}',
'color': '#4b4b4b'
},
'input.invalid': {
'color': '{{templateset.custom_fields.color_error|default:"#d00" }}',
'background-color': '#FFC8C8'
},
'input.valid': {
'color': 'green'
}
},
submit: form.querySelector("button[type=submit]"),
use_3d_secure: !!use_3d_secure,
nonce: nonce,
bin: bin,
isRecurringUpdate: true,
// allow empty submit so just amount can be changed
submitOnEmpty: function() { return true; }
},
toRemove = ["input[name=card_num]", "input[name=card_code]",
"input[name=exp_date]"];
if (is_ach) {
options['fields'] = {};
options['ach'] = true;
} else {
toRemove.forEach(function(el) {
form.querySelector(el).remove();
});
Object.keys(options.fields).forEach(function(key) {
var field = options.fields[key];
document.querySelector(field.selector).classList.add('hosted-field');
});
}
actionkit.donations.initClient(clientToken, options);
}
</script>
{% endonce %}
{% endif %}
{% if profile.payment_processor_information.processor == 'stripe' %}
{% once %}
<script type="text/javascript" src="https://js.stripe.com/v2/"></script>
<script type="text/javascript">
$(function() {
$('[data-stripe-pub-key] [name=card_num]').attr('data-stripe', 'number');
$('[data-stripe-pub-key] [name=exp_date]').attr('data-stripe', 'exp');
$('[data-stripe-pub-key] [name=card_code]').attr('data-stripe', 'cvc');
});
window.actionkitBeforeSubmit = function() {
var $form = $(actionkit.form);
// user can have non-stripe and stripe recurrings--don't interfere with
// non-stripe forms
var stripePubKey = $form.attr('data-stripe-pub-key');
if ( stripePubKey ) {
Stripe.setPublishableKey(stripePubKey)
}
else {
return;
}
// user might just be changing amount
if ( !$form.find('[name=card_num]').is(':visible') )
return;
var $expField = $form.find('[name=exp_date]');
var exp = $expField.val();
// Stripe wants exp as 12/99 not 1299
exp = exp.replace(/[^0-9]/g, '').replace(/^([0-9][0-9])/, function(match) { return match + '/' });
$expField.val(exp);
try {
Stripe.card.createToken(actionkit.form, onStripeResponse);
} catch(e) {
// Stripe will throw (rather than return a failed response) for an
// out of range exp date month.
$expField.val(
$expField.val().replace('/', '')
);
alert('Sorry, we could not process your credit card information. Check your entries, such as your expiration date format, and try again.')
throw e;
}
return false;
}
function onStripeResponse(status, response) {
var $form = $(actionkit.form);
var $cardNumField = $form.find('[name=card_num]')
if ( response.error ) {
alert('We could not process your credit card information: ' + response.error.message);
$cardNumField.focus();
return;
}
$cardNumField.attr('disabled', true);
$cardNumField.after('<input type="hidden" name="card_num" value="token:' + response.id + '">')
// Stripe got exp_date in the format it wants, but set it back to the
// format ActionKit wants:
var $expField = $form.find('[name=exp_date]');
$expField.val(
$expField.val().replace('/', '')
);
actionkit.form.submit()
}
</script>
{% endonce %}
{% endif %}
{% endfor %}
<script type="text/javascript">
function valid_bank_account_number(value) {
return /^\d{4,17}$/.test(value);
}
function valid_bank_routing_number(value) {
value = value.replace(/\D/g,'');
if (value.length != 9) { return false; }
var checksum = 0;
for (var i = 0; i < value.length; i += 3) {
checksum += parseInt(value.charAt(i), 10) * 3
+ parseInt(value.charAt(i + 1), 10) * 7
+ parseInt(value.charAt(i + 2), 10);
}
if (checksum == 0 || checksum % 10 != 0) { return false; }
return true;
}
function validate_business_name(input) {
form = input.form;
if (input.value == 'business' && !form['business_name'].value) {
return "Business name is required for business accounts.";
}
return true;
}
function ach_validation(form) {
actionkit.forms.setForm(form);
// allow changing amount separately
if ($(form['bank_account']).is(':hidden')) { return true; }
// clear_errors will delete these inputs from other
// forms if we don't remove the error class from them here
$(':input.ak-error, label.ak-error').removeClass('ak-error');
// address is required for ACH changes, even for logged in users
var saved_state = actionkit.forms.alwaysRequireUserFields;
actionkit.forms.alwaysRequireUserFields = true;
var is_valid = actionkit.forms.validate();
actionkit.forms.alwaysRequireUserField = saved_state;
return is_valid;
}
/* This prevents the invisible inputs from being submitted. Needed
because reflectCountryChange() messes with the disabled prop. */
function disable_invisibles(form) {
$(form).find(':input:hidden[type!="hidden"]').prop('disabled', true);
return true;
}
</script>
{% endblock %}
{% block content %}
<div class="ak-grid-row">
<div class="ak-grid-col ak-grid-col-12-of-12">
<h2>{{ page.title }}</h2>
</div>
</div>
<div class="ak-grid-row ak-grid-row-inverted">
{% if page.custom_fields.featured_image %}
<div class="ak-grid-col ak-grid-col-3-of-12">
<img class="ak-featured-img" src="{{page.custom_fields.featured_image}}">
</div>
{% endif %}
<div class="ak-grid-col {% if page.custom_fields.featured_image %} ak-grid-col-9-of-12 {% else %}ak-grid-col-12-of-12 {% endif %}">
<div>
<p>Logged in as <a href="/me/">{{ logged_in_user.name }}</a>. <a href="/logout/">Log out</a></p>
</div>
<div style="display:none">{% comment %}actionkit.js wants this, but we don't{% endcomment %}
<p id="unknown_user"></p>
<div id="known_user"><span id="known_user_name"></span></div>
</div>
{% if action %}
<h3>Update saved!</h3>
<div>
{% include_tmpl form.thank_you_text %}
</div>
{% endif %}
<p>{% include_tmpl form.update_card_text %}</p>
{% if not active %}
<p>Whoops! You don't have any active recurring donations to update.</p>
{% else %}
{% for profile in active %}
{% include "./recurring_info.html" %}
{% endfor %}
{% endif %}
{% comment %}
This is an example of how to show inactive profiles.
{% if inactive %}
<label class="ak-label-above">Your old, no longer active recurring donations</label>
<ul>
{% for profile in inactive %}
<li>{{ profile.status }} on {{ profile.updated_at }}. Started on {{ profile.start }}, {% with profile.payment_count as count %} {{ count }} {{ profile.get_period_display|lower }} payment{{ count|pluralize }}{% endwith %} were made for a total of {{ profile.payment_total_amt }}.</li>
{% endfor %}
</ul>
{% endif %}
{% endcomment %}
</div>
</div>
{% endblock %}
Reset¶
Page where users set or reset their password. Link provided in the reset_password_email.html.
{% extends "./wrapper.html" %}
{% block content %}
<div class="ak-grid-row">
<div class="ak-grid-col ak-grid-col-4-of-12 ak-grid-centered">
<p>Fill out the form below and we'll set your password.</p>
{% if message %}
<p class="ak-large-text">{{ message }}</p>
{% endif %}
<form action="{{ app_path }}" method="post" id="login-form" name="login-form" class="ak-styled-fields ak-labels-above {{page.custom_fields.field_errors_class}}">
{{ form.non_field_errors }}
{% for field in form.visible_fields %}
<div>
<label for="{{ field.id_for_label }}">
{{ field.label }}
</label>
{{ field }}
{{ field.errors }}
</div>
{% endfor %}
{% for field in form.hidden_fields %}
{{ field }}
{% endfor %}
<div class="submit-row">
<button type="submit" class="ak-submit-button">Update</button>
</div>
</form>
</div>
</div>
{% endblock %}
{% block below_form %}
<script>
actionkit.forms.contextRoot = '/context/';
actionkit.forms.initValidation('login-form');
</script>
{% endblock %}
Reset Password Email¶
Email sent to users if they submit on password.html.
<html>
<p>
You can set the password for your {{ actionkit_user.email }} {{ organization }} account, by visiting the link below:
</p>
<p>
<a href="https://{{ webhostname }}/reset/?i={{ secret }}&next={{ next }}">https://{{ webhostname }}/reset/?i={{ secret }}&next={{ next }}</a>
</p>
<p>
If you didn't request this email, don't worry—no one else got this email and nothing will happen to your account if you take no action.
</p>
</html>
Signup¶
Sign up page layout.
{% extends "./wrapper.html" %}
{% block content %}
<div class="ak-grid-row">
<div class="ak-grid-col ak-grid-col-12-of-12">
<h2>{{ page.title }}</h2>
</div>
</div>
<form class="action_form" name="act" method="POST" action="/act/" accept-charset="utf-8">
<div class="ak-grid-row">
<div id="signup-story" class="ak-grid-col ak-grid-col-6-of-12">
{% if page.custom_fields.featured_image %}
<img class="ak-featured-img" src="{{page.custom_fields.featured_image}}">
{% endif %}
<div class="ak-abovefold">
{% include_tmpl form.introduction_text %}
</div>
<div class="ak-mobile-lead"></div>
{% include "./progress_meter.html" %}
</div>
<div id="signup-form" class="ak-grid-col ak-grid-col-6-of-12 ak-styled-fields {{templateset.custom_fields.field_labels_class|default:"ak-labels-overlaid"}} {{templateset.custom_fields.field_errors_class|default:"ak-errs-below"}}">
{% include "./user_form_wrapper.html" %}
<button type="submit" class="full">Sign Up</button>
</div>
</div>
<input type="hidden" name="page" value="{{ page.name }}">
</form>
{% endblock %}
Site 404¶
Page displayed if the user follows a link to an address that does not exist.
<html>
<body>
<p>
Sorry, the URL you tried to load doesn't exist. Check that it's typed
correctly.
</p>
</body>
</html>
Site 500¶
Page displayed if the user follows a link to an address that does not exist.
<html>
<body>
<p>
Sorry, we're having trouble handling your request at the moment. Please give us a few minutes and try again.
</p>
</body>
</html>
Site Root¶
Lets you control what is served up at the root of your client domains.
<html>
<head>
</head>
<body>
</body>
</html>
State Select¶
Drop down of states used by user_form.html.
<select name="{{ input_name_prefix }}state" id="id_{{ input_name_prefix }}state" {% if onchange %}onchange="{{ onchange }}" onblur="{{ onchange }}"{% endif %}>
<option value="">State</option>
<option value="AL">Alabama</option>
<option value="AK">Alaska</option>
<option value="AZ">Arizona</option>
<option value="AR">Arkansas</option>
<option value="CA">California</option>
<option value="CO">Colorado</option>
<option value="CT">Connecticut</option>
<option value="DE">Delaware</option>
<option value="DC">District of Columbia</option>
<option value="FL">Florida</option>
<option value="GA">Georgia</option>
<option value="HI">Hawaii</option>
<option value="ID">Idaho</option>
<option value="IL">Illinois</option>
<option value="IN">Indiana</option>
<option value="IA">Iowa</option>
<option value="KS">Kansas</option>
<option value="KY">Kentucky</option>
<option value="LA">Louisiana</option>
<option value="ME">Maine</option>
<option value="MD">Maryland</option>
<option value="MA">Massachusetts</option>
<option value="MI">Michigan</option>
<option value="MN">Minnesota</option>
<option value="MS">Mississippi</option>
<option value="MO">Missouri</option>
<option value="MT">Montana</option>
<option value="NE">Nebraska</option>
<option value="NV">Nevada</option>
<option value="NH">New Hampshire</option>
<option value="NJ">New Jersey</option>
<option value="NM">New Mexico</option>
<option value="NY">New York</option>
<option value="NC">North Carolina</option>
<option value="ND">North Dakota</option>
<option value="OH">Ohio</option>
<option value="OK">Oklahoma</option>
<option value="OR">Oregon</option>
<option value="PA">Pennsylvania</option>
<option value="RI">Rhode Island</option>
<option value="SC">South Carolina</option>
<option value="SD">South Dakota</option>
<option value="TN">Tennessee</option>
<option value="TX">Texas</option>
<option value="UT">Utah</option>
<option value="VT">Vermont</option>
<option value="VA">Virginia</option>
<option value="WA">Washington</option>
<option value="DC">Washington, D.C.</option>
<option value="WV">West Virginia</option>
<option value="WI">Wisconsin</option>
<option value="WY">Wyoming</option>
{% if 'territories' in templateset.custom_fields.state_select_options %}
<option value="">---</option>
<option value="AS">American Samoa</option>
<option value="GU">Guam</option>
<option value="MP">Northern Mariana Islands</option>
<option value="PR">Puerto Rico</option>
<option value="VI">Virgin Islands</option>
{% endif %}
{% if 'military' in templateset.custom_fields.state_select_options %}
<option value="">---</option>
<option value="AE">Armed Forces Europe</option>
<option value="AA">Armed Forces Americas</option>
<option value="AP">Armed Forces Pacific</option>
{% endif %}
</select>
Survey¶
Survey page layout.
{% extends "./wrapper.html" %}
{% block content %}
<form class="ak-form" name="act" method="POST" action="/act/" accept-charset="utf-8">
<input type="hidden" name="page" value="{{ page.name }}">
<div class="ak-grid-row">
<div class="ak-grid-col ak-grid-col-12-of-12">
<h2>{{ page.title }}</h2>
<div class="ak-mobile-padding ak-text-expander">
{% include_tmpl form.introduction_text %}
</div>
<a href="#" class="ak-read-more ak-mobile" data-lines="10">Read more</a>
</div>
</div>
<div class="ak-grid-row">
<div class="ak-grid-col ak-grid-col-4-of-12">
{% if page.custom_fields.featured_image %}
<img class="ak-featured-img" src="{{page.custom_fields.featured_image}}">
{% endif %}
<div id="survey-contact" class="ak-styled-fields {{templateset.custom_fields.field_labels_class|default:"ak-labels-overlaid"}} {{templateset.custom_fields.field_errors_class|default:"ak-errs-below"}}">
{% include "./user_form_wrapper.html" %}
</div>
{% include "./progress_meter.html" %}
</div>
<div id="ak-survey-questions" class="ak-grid-col ak-grid-col-8-of-12">
<div class="ak-field-box ak-field-box-padded ak-styled-fields ak-labels-above {{templateset.custom_fields.field_errors_class|default:"ak-errs-below"}}">
{% for question in form.surveyquestion_set.all %}
<div>
<label class="ak-survey-question-label">
{{ question.question_label|safe }}
</label>
{{ question.input_html|safe }}
</div>
{% endfor %}
<button type="submit" class="ak-submit-button">Submit Survey</button>
</div>
</div>
</div>
</form>
{% endblock %}
Thanks¶
Thanks page layout with TAF widget, if selected.
{% extends "./wrapper.html" %}
{% block content %}
<form name="taf" method="POST" action="/update_action/" accept-charset="utf-8" class="ak-thanks ak-styled-fields">
<input type="hidden" name="page" value="{{ page.name }}">
{% if actionkit_user %}
{% if recurring_update or recurring_cancel %}
<div class="ak-grid-row">
<div class="ak-grid-col ak-grid-col-12-of-12">
<p>
{% filter ak_text:"logged_in_as" %}You are logged in as{% endfilter %} <a href="/me/">{{ actionkit_user.name|escape }}</a>.
<a href="/logout">{% filter ak_text:"logout" %}Click to log out.{% endfilter %}</a>
</p>
</div>
</div>
{% endif %}
{% endif %}
{% if page.SUPPRESS_SHARING %}
<div class="ak-grid-row">
<div class="ak-grid-col ak-grid-col-12-of-12">
<h2>
<img src="/media/modern/stance-supportive.svg" width="34" class="ak-checkmark-icon" alt="✓">
{% filter ak_text:"noshare_thanks_banner" %}
Thanks!
{% endfilter %}
</h2>
<div>
{% include_tmpl form.thank_you_text %}
</div>
</div>
</div>
{% else %}
<div class="ak-grid-row">
<div class="ak-grid-col ak-grid-col-6-of-12">
<h2>
<img src="/media/modern/stance-supportive.svg" width="34" class="checkmark-icon" alt="✓">
{% if page.followup.send_taf and args.taf %}
{% filter ak_text:"tell_your_friends_banner" %}
You're almost done!
{% endfilter %}
{% elif not action.custom_fields.cwc_prefix and page.send_via_cwc and page.is_targeting_us_senate %}
Information Needed
{% else %}
{% filter ak_text:"notaf_thanks_banner" %}
You're almost done!
{% endfilter %}
{% endif %}
</h2>
<div>
{% if not action.custom_fields.cwc_prefix and page.send_via_cwc and page.is_targeting_us_senate %}
<p>To deliver your signature to the Senate <b>you must select a prefix</b> from the following list. Your selection will only be used to deliver your signature.</p>
<select name="action_cwc_prefix">
<option>Mr.</option>
<option>Mrs.</option>
<option>Miss</option>
<option>Ms.</option>
<option>Dr.</option>
</select>
<button type="submit" class="ak-submit-button">Update</button>
{% else %}
{% include_tmpl form.thank_you_text %}
{% endif %}
</div>
{% include "./progress_meter.html" %}
</div>
<div class="ak-grid-col ak-grid-col-6-of-12 ak-margin-top-2">
<div>
<a class="ak-button ak-share-button ak-facebook" href="/share/link?type=fb&page_name={{page.name}}&action_id={{action.id}}&akid={{akid}}" target="_blank">Post to Facebook</a>
</div>
<div>
<a class="ak-button ak-share-button ak-twitter" href="/share/link?type=tw&page_name={{page.name}}&action_id={{action.id}}&akid={{akid}}" target="_blank">Share on Twitter</a>
<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");</script>
</div>
{% if page.followup.send_taf and args.taf %}
<div>
<a class="ak-button ak-share-button ak-email" href="mailto:?subject={{ page.followup.taf_subject|urlencode }}&body={% filter referring_akid:akid|tag_links:"source=mailto"|urlencode %}{% include_tmpl page.followup.taf_body unescaped %}{% endfilter %}" target="_blank">{% filter ak_text:"taf_mailto_ask" %}Send an email now {% endfilter %}</a>
</div>
<div id="copy-and-paste">
<p class="ak-normal">Or copy and paste the text below into an email message:</p>
<textarea class="ak-share-message" readonly>Subject: {% include_tmpl page.followup.taf_subject escaped %}
{% filter referring_akid:akid|tag_links:"source=taf" %}{% include_tmpl page.followup.taf_body escaped %}{% endfilter %}
</textarea>
</div>
<input type="hidden" value="{{ page.canonical_url }}"> <a href="/share/link?as_text=1&type=ot&page_name={{page.name}}&action_id={{action.id}}&akid={{akid}}" target="_blank" style="display: none"></a>
<div id="ak-confirmation">
{% filter ak_text:"taf_confirmation" %}Sent! If you like, you can send more messages below.{% endfilter %}
</div><!--akconfirmation-->
<div id="taf-preview" class="taf-preview last ak-percent-full ak-padding-left-none ak-hidden-mobile">
<p class="ak-normal ak-align-right">
<a class="ak-emailalt ak-underline-on-hover" href="#" for="id_taf_body">{% filter ak_field_label:"taf_preview" %}<span>Or, send a message using our site</span>{% endfilter %} <span class="ak-arrow-holder"><span class="ak-arrow-inline"></span></span></a>
</p>
<div id="ak-taf-form" class="ak-field-box">
<div class="ak-pull-right" style="margin-bottom: -30px">
<a class="ak-emailalt ak-sendemail-opened">×</a>
</div>
<table class="ak-message-form ak-errs-below">
<tr>
<th>
<label for="id_taf_emails">
To
</label>
</th>
<td style="padding-right: 30px">
<textarea id="id_taf_emails" name="taf_emails" placeholder="{% filter ak_text:"taf_ask" %}Enter email addresses separated by commas{% endfilter %} "></textarea>
<input type="hidden" name="required" value="taf_emails">
</td>
</tr>
<tr>
<th>
<label id="lbl_taf_subject" for="id_taf_subject">Subject</label>
</th>
<td>
<div id="id_taf_subject" class="ak-readonly-value ak-sharebox-tafsubject">{% include_tmpl page.followup.taf_subject escaped %}</div>
</td>
</tr>
<tr>
<th>
<label for="id_taf_note">Your Note</label>
</th>
<td>
<textarea id="id_taf_note" name="taf_note" placeholder="Optionally add a personal comment"></textarea>
</td>
</tr>
<tr>
<th>
<label for="id_taf_body">Message</label>
</th>
<td>
<div id="id_taf_body" name="taf_body" class="ak-readonly-value">{% filter referring_akid:akid|tag_links:"source=taf" %}{% include_tmpl page.followup.taf_body escaped %}{% endfilter %}</div>
</td>
</tr>
<tr>
<th>
</th>
<td>
<button type="submit" class="ak-sendmessage ak-btn-short">{% filter ak_text:"taf_send_messages" %}Send{% endfilter %}</button>
</td>
</tr>
</table>
</div>
</div>
{% endif %}
</div>
</div>
{% endif %}
</form>
{% endblock %}
{% block script_additions %}
<script type="text/javascript">
$(document).ready(function() {
$('.ak-emailalt').on('click', function() {
$(this).parent('p').toggleClass('active');
$('#ak-taf-form').slideToggle(function() {
$('#taf_form').toggleClass('ak-closed');
});
$('#copy-and-paste').slideToggle();
return false;
});
});
</script>
{% endblock %}
{% block below_form %}
<script type="text/javascript">
actionkit.forms.contextRoot = '/context/';
actionkit.forms.initTafForm('taf');
actionkit.sharing.initShareTools();
</script>
{% endblock %}
Unsubscribe¶
Unsubscribe page layout. If you have multiple lists, they must all be pre-checked (as they are in the original templateset).
{% extends "./wrapper.html" %}
{% block content %}
<div class="ak-grid-row">
<div class="ak-grid-col ak-grid-col-12-of-12">
<h2>{{ page.title }}</h2>
</div>
</div>
<form id="unsub-form" name="act" method="POST" action="/act/" accept-charset="utf-8">
<div class="ak-grid-row">
<div class="area ak-grid-col ak-grid-col-6-of-12">
{% if page.custom_fields.featured_image %}
<img class="ak-featured-img" src="{{page.custom_fields.featured_image}}">
{% endif %}
{% include_tmpl form.introduction_text %}
</div>
<div class="area ak-grid-col ak-grid-col-6-of-12 ak-styled-fields {{templateset.custom_fields.field_labels_class|default:"ak-labels-overlaid"}} {{templateset.custom_fields.field_errors_class|default:"ak-errs-below"}}">
<ul class="compact" id="ak-errors"></ul>
<div id="unknown_user">
<div>
<div>
<label for="id_email">Email address</label>
<input id="id_email" type="text" name="email" size=40>
</div>
<input type="hidden" name="country" value="United States">
</div>
</div>
<div id="known_user">
<div class="ak-err">
Not <span id="known_user_name"></span>?
Please don't use this form!
</div>
</div>
{% if user.subscriptions|length > 1 %}
<input type="hidden" name="have_unsub_lists" value="1">
<div>
<label>
Unsubscribe From
</label>
<div class="ak-unsubscribe-lists ak-checkbox-set">
{% for s in user.subscriptions %}
<label class="ak-checkbox-choice" style="display: block">
<input type="checkbox" checked name="unsub_lists" value="{{ s.list.id }}">
{{ s.list.name }}
</label>
{% endfor %}
</div>
</div>
{% endif %}
<div>
<label for="id_action_survey">
{% include_tmpl form.survey_question_text %}
</label>
<textarea id="id_action_survey" name="action_survey"></textarea>
</div>
<button type="submit">Unsubscribe</button>
</div>
</div>
<input type="hidden" name="page" value="{{ page.name }}">
</form>
{% endblock %}
User Form¶
Standard contact form used in all page types except donate.html, event_attend.html and recurring_update.html.
{% load switchcase %}
{% filter remove_blank_lines %}
{% comment %}
To change which fields show, edit {% hide_by_default %} below and set
individual pages' required fields in the page admin, or activate the
User Fields customization option in the page admin to override which
fields are visible and the order they're shown in.
Unhide or require the 'country' field to make the form international. To
geolocate more users outside the United States, unhide/require 'city'.
You can change label text in the language admin, change {% field_order %}
below, edit the CSS, or replace this form entirely with static HTML. See
the advanced template ref for more:
https://roboticdogs.actionkit.com/docs/manual/developer/customizing_pages.html#working-with-templates
name email prefix first_name middle_name last_name suffix country address1 address2 city state zip region postal phone
Enjoy!
{% endcomment %}
{% field_order name email prefix first_name middle_name last_name suffix country address1 address2 city state zip region postal phone %}
{% hide_by_default prefix first_name middle_name last_name suffix country phone address1 address2 city state region postal %}
{% for field in user_fields %}
<div id="ak-fieldbox-{{ field.field_name }}" {% if field.field_name|is_in:context.required %}class="required"{% endif %}>
<label for="id_{{ field.field_name }}">
{{ field.label_text }}{% if field.field_name|is_in:context.required %}<span class="ak-required-flag">*</span>{% endif %}
</label>
{% switch field.field_name %}
{% case 'country' %}
{% include "./country_select.html" %}
{% case 'state' %}
{% include "./state_select.html" %}
{% else %}
{{ field.input_html }}
{% endswitch %}
</div>
{% endfor %}
{% if 'country'|is_in:fields %}
<input type="hidden" name="auto_country" value="1">
<style type="text/css">
/* Ensure that, if there's no JavaScript, and there are both
* global-friendly and US-only fields, the global-friendly
* fields show rather than the US-only ones */
{% if 'postal'|is_in:fields %}
#ak-fieldbox-zip { display: none; }
{% endif %}
{% if 'region'|is_in:fields %}
#ak-fieldbox-state { display: none; }
{% endif %}
</style>
{% else %}
<input type="hidden" name="country" value="United States">
{% endif %}
{% endfilter %}
User Form Intl¶
Contact form with country drop down. Cut and paste into user_form.html to create international templateset.
{% comment %}
This is a sample of an international-friendly user form. If you're using the
latest user_form.html as a base, you don't need this! Just add 'country' to
your page's list of required fields, or remove 'country' from the {%
hide_by_default %} tag in your user_form.html, and you're done.
{% endcomment %}
<div id="ak-fieldbox-name">
<label for="id_name">Name</label>
<input name="name" id="id_name" type="text">
</div>
<div id="ak-fieldbox-email">
<label for="id_email">Email</label>
<input name="email" id="id_email" type="text">
</div>
<div id="ak-fieldbox-address1">
<label for="id_address1">Address</label>
<input name="address1" id="id_address1" type="text">
</div>
<div id="ak-fieldbox-city">
<label for="id_city">City</label>
<input name="city" id="id_city" type="text">
</div>
<div id="ak-fieldbox-country">
<label for="id_country">Country</label>
{% include "./country_select.html" %}
</div>
<div id="ak-fieldbox-state">
<label for="id_state">State</label>
{% include "./state_select.html" %}
</div>
<div id="ak-fieldbox-zip">
<label for="id_zip">Zip</label>
<input name="zip" id="id_zip" type="text">
</div>
<div id="ak-fieldbox-region">
<label for="id_region">Region</label>
<input name="region" id="id_region" type="text">
</div>
<div id="ak-fieldbox-postal">
<label for="id_postal">Postal</label>
<input name="postal" id="id_postal" type="text">
</div>
<input type="hidden" name="auto_country" value="1">
<style type="text/css">
/* Ensure that, if there's no JavaScript, the global-friendly fields show
* rather than the US-only ones */
#ak-fieldbox-state, #ak-fieldbox-zip { display: none; }
</style>
User Form Wrapper¶
<ul class="compact" id="ak-errors"></ul>
<div id="known_user">
Not <span id="known_user_name"></span>? <a href="?" onclick="return actionkit.forms.logOut()">Click here.</a>
<hr>
</div>
<div id="unknown_user" class="ak-user-form">
{% include "./user_form.html" %}
</div>
{% include "./privacy.html" %}
User Merge¶
Page displayed if user tries to change their email on the user_update.html page to an email already registered to another user.
{% extends "./wrapper.html" %}
{% block content %}
<div class="ak-grid-row">
<div class="ak-grid-col ak-grid-col-12-of-12">
{% if sent %}
<h2>Sent!</h2>
{% else %}
<h2>Almost Done! One More Step!</h2>
<p>
We already have another user account with the email <b>{{ target }}</b>. Maybe you already took an action with that email?
</p>
<p>
If you'd like to consolidate your two accounts, we'll send an email to <b>{{ target }}</b> to confirm it's your email. Once you click the link in the email, we'll change your email address from <b>{{ actionkit_user.email }}</b> to <b>{{ target }}</b>.
</p>
<form name="merge" method="POST">
<input type="hidden" name="target" value="{{ target }}">
<input type="submit" value="Okay, send me the email!">
</form>
{% endif %}
</div>
</div>
{% endblock %}
User Update¶
Form an end user uses to edit their contact information, including message displayed when they submit.
{% extends "./wrapper.html" %}
{% load switchcase %}
{% block title %}Update Your Account{% endblock %}
{% block content %}
{% if updated %}
<div class="ak-grid-row">
<div class="ak-grid-col ak-grid-col-12-of-12">
<p>Thanks! We've updated your information.</p>
</div>
</div>
{% endif %}
<div class="ak-grid-row">
<div class="ak-grid-col ak-grid-col-12-of-12">
<h2>Update Your Account</h2>
{% if user %}
<p>
{% filter ak_text:"logged_in_as" %}You are logged in as{% endfilter %} <a href="/me/">{{ user.name|escape }}</a>.
<a href="/logout">{% filter ak_text:"logout" %}Log out{% endfilter %}</a>
</p>
{% endif %}
</div>
</div>
<div class="ak-grid-row">
<div class="ak-grid-col ak-grid-col-9-of-12">
<form name="accountupdate" method="POST" class="ak-styled-fields {{templateset.custom_fields.field_errors_class|default:"ak-errs-below"}}">
{{ form.non_field_errors }}
{% for field in form.visible_fields %}
<div class="ak-labels-before">
<label for="{{ field.id_for_label }}">
{{ field.label }}
</label>
{% switch field.name %}
{% case 'country' %}
<select name="{{ input_name_prefix }}country" id="id_{{ input_name_prefix }}country" {% if onchange %}onchange="{{ onchange }}" onblur="{{ onchange }}"{% endif %}>
<option selected="{{ field.value }}">{{ field.value }}</option>
{% for std_name,name in templateset.lang.country_names_us_first %}
<option value="{{ std_name|escapeall }}">{{ name|escapeall }}</option>
{% endfor %}
</select>
{% case 'state' %}
<script>
$(function() { //Make sure the current State value is selected
let selectedState = "{{ field.value }}";
$('#id_state > option[value=' + selectedState + ']').prop('selected', true);
})
</script>
{% include "./state_select.html" %}
{% else %}
{{ field }}
{% endswitch %}
{{ field.errors }}
</div>
{% endfor %}
<div class="ak-skip-label-before">
{{ form.privacy.errors }}
{% include "./privacy.html" %}
</div>
</div>
<div class="ak-grid-col ak-grid-col-3-of-12">
</div>
</div>
<div class="ak-grid-row">
<div class="ak-grid-col ak-grid-col-12-of-12">
<button type="submit" class="ak-submit-button">Submit</button>
</div>
</div>
</form>
<script>
$('ul.errorlist').each( function () {
$( this ).addClass('ak-errors').css('display', 'block').
parent().find('label, :input').addClass('ak-error').
closest('form').addClass('contains-errors');
} );
// Run just the country-switching stuff from action forms.
actionkit.forms.setForm('accountupdate');
actionkit.context = {{ js_context|json }};
$(actionkit.form.country).change(function() {
actionkit.forms.setForm('accountupdate');
actionkit.forms.reflectCountryChange();
});
actionkit.forms.reflectCountryChange();
</script>
{% endblock content %}
User Update Form¶
Similar to user_form.html but doesn't let user change email; used for updating event info.
{% comment %}
Like user_form, but doesn't let user change email;
used for updating event host/attendee signups.
{% endcomment %}
<div class="gridded">
<p><label for="id_name">Name:</label> <input id="id_name" type="text" name="name"></p>
<p><label for="id_address1">Street address:</label> <input id="id_address1" type="text" name="address1">
<p><label for="id_city">City:</label> <input id="id_city" type="text" name="city"></p>
<p><label for="id_state">State:</label>{% include "./state_select.html" %}</p>
<p><label for="id_zip">ZIP:</label> <input id="id_zip" type="text" name="zip" size="5"></p>
<input type="hidden" name="country" value="United States">
</div>
User View¶
Read only screen showing user contact information.
{% extends './wrapper.html' %}
{% block content %}
<div class="ak-grid-row">
<div class="ak-grid-col ak-grid-col-12-of-12">
<h2 class="ak-display-inline-block">{{ actionkit_user.name }}</h2>
<a href="/logout/">Log Out</a>
</div>
</div>
<div class="ak-grid-row">
<div class="ak-grid-col ak-grid-col-12-of-12">
{% if messages %}
<ul class="messages">
{% for message in messages %}
<li>
{{ message }}
</li>
{% endfor %}
</ul>
{% endif %}
<h3>Email And Address</h3>
<div><strong>{{ actionkit_user.email }}</strong></div>
<div class="ak-full-address">{{ actionkit_user.full_address }}</div>
<div><a href="update/">Update your email or address.</a></div>
<h3> Subscription History </h3>
<ul class="ak-margin-none">
{% for subscription in actionkit_user.subscription_history %}
<li>
{{ subscription.list.name }}, {{ subscription.change.name }}, at {{ subscription.created_at|date:"m/d/Y" }}
</li>
{% endfor %}
</ul>
{% if actionkit_user.is_subscribed %}
<div><a href="/cms/unsubscribe/unsubscribe/?akid={{ actionkit_user.token }}">Unsubscribe</a></div>
{% endif %}
{% if recurring_donations %}
<h3> Your Recurring Donations </h3>
<ul class="ak-margin-none">
{% for profile in recurring_donations %}
<li>
<strong>{{ profile.amt }}</strong> a {{ profile.inverse_period_display|lower }}, started on {{ profile.created_at|date:"m/d/Y" }}.
You've given a total of {{ profile.payment_total_amt }}.
{% if profile.is_active and not profile.is_import_stub %}
{% if profile.order.payment_method != "paypal" %}
<a href="/cms/pledge/update/update/">Manage your recurring profile.</a>
{% else %}
<a href="/cms/pledge/cancel/monthly/">Cancel at any time.</a>
{% endif %}
{% else %}
<b>{{ profile.get_status_display }} on {{ profile.updated_at|date:"m/d/Y" }} </b>
{% endif %}
</li>
{% endfor %}
</ul>
{% endif %}
{% for campaign, upcoming_event_count in campaigns_moderating.items %}
{% if forloop.first %}
<h3>Event Moderation</h3>
<ul>
{% endif %}
<li>
<b>{{ campaign.title }}</b> campaign with <b>{{ upcoming_event_count }}</b> upcoming events ({{ campaign.event_set.count }} total). <a href='/event/{{campaign.moderate_page.name}}/moderator_search/?akid={{akid}}'>Moderate</a>
</li>
{% if forloop.last %}
</ul>
{% endif %}
{% endfor %}
{% for event in upcoming_events %}
{% if forloop.first %}
<h3>Upcoming Events</h3>
<ul>
{% endif %}
<li>
<b>{{ event.event.starts_at_dt|date:"l, F j, Y, g:i A" }}:</b>
{% if event.role == 'host' %}Hosting <a href="{% url 'event_host_tools' event.event.campaign.local_name event.event.id %}?action_id={{ event.action.id }}&akid={{ event.action.user.akid }}">
{% else %} Attending <a href="{% url 'event_attendee_tools' event.event.campaign.local_name event.event.id %}?action_id={{ event.action.id }}&akid={{ event.action.user.akid }}">
{% endif %}
{{ event.event.title }}</a>
</li>
{% if forloop.last %}
</ul>
{% endif %}
{% endfor %}
{% for event in past_events %}
{% if forloop.first %}
<h3>Past Events</h3>
<ul>
{% endif %}
<li>
<b>{{ event.event.starts_at_dt|date:"l, F j, Y, g:i A" }}:</b>
{% if event.role == 'host' %}Hosted <a href="{% url 'event_host_tools' event.event.campaign.local_name event.event.id %}?action_id={{ event.action.id }}&akid={{ event.action.user.akid }}">
{% else %} Attended <a href="{% url 'event_attendee_tools' event.event.campaign.local_name event.event.id %}?action_id={{ event.action.id }}&akid={{ event.action.user.akid }}">
{% endif %}
{{ event.event.title }}</a>
</li>
{% if forloop.last %}
</ul>
{% endif %}
{% endfor %}
{% if donations %}
<h3> Donation History </h3>
<ul>
{% for donation in donations %}
<li>
{{ donation.amt }} on {{ donation.created_at|date:"m/d/Y" }} {% if donation.recurring %} (Recurring) {% endif %}
</li>
{% endfor %}
</ul>
{% endif %}
</div>
</div>
{% endblock %}
Whipcount¶
The whipcount page layout.
{% extends "./wrapper.html" %}
{% block content %}
<form class="ak-form whipcount" name="act" method="POST" action="/act/" accept-charset="utf-8">
<input type="hidden" name="page" value="{{ page.name }}">
<div class="ak-grid-row">
<div class="ak-grid-col ak-grid-col-12-of-12">
<h2>{{ page.title }}</h2>
</div>
</div>
{% if action %}
<div class="ak-grid-row">
<div class="ak-grid-col ak-grid-col-12-of-12">
<h3 class="thanks">Thanks for making a whipcount call!</h3>
<p>We've noted that {% for contact in action.called.all %}{{ contact.target.title_last }} is {{ contact.response }}{% endfor %}!</p>
<div>
{% include_tmpl form.thank_you_text %}
</div>
</div>
</div>
{% endif %}
<div class="ak-grid-row ak-grid-row-inverted">
{% if page.custom_fields.featured_image or page.goal %}
<div class="ak-grid-col ak-grid-col-4-of-12">
{% if page.custom_fields.featured_image %}
<img class="ak-featured-img" src="{{page.custom_fields.featured_image}}">
{% endif %}
{% include "./progress_meter.html" %}
</div>
{% endif %}
<div class="ak-grid-col {% if page.custom_fields.featured_image or page.goal %}ak-grid-col-8-of-12{% else %}ak-grid-col-12-of-12{% endif %} ak-styled-description">
<div class="ak-text-expander">
{% include_tmpl form.introduction_text %}
</div>
<a href="#" class="ak-read-more ak-mobile" data-lines="10">Read more</a>
</div>
</div>
{% if not target %}
<div class="ak-grid-row">
<div class="ak-grid-col ak-grid-col-12-of-12">
{% include "./whipcount_results.html" %}
</div>
</div>
{% else %}
<div class="ak-grid-row ak-steps-area">
<ul id="ak-errors"></ul>
<div id="who_to_call" class="ak-grid-col ak-grid-col-4-of-12">
<div>
<h3>
<label class="ak-step-label" for="{{ target.id }}">
<div class="ak-step-number">1</div>
Review Script
</label>
<span class="ak-arrow-holder"><span class="ak-arrow"></span></span>
</h3>
<div id="what_to_say" class="ak-field-box ak-field-box-borderless"></div>
<script type="text/ak-template" for="what_to_say">
{% include_tmpl form.script_text %}
</script>
</div>
</div>
<div id="response" class="ak-styled-fields ak-grid-col ak-grid-col-4-of-12">
<h3>
<label class="ak-step-label">
<div class="ak-step-number">2</div>
Make the call
</label>
<span class="ak-arrow-holder"><span class="ak-arrow"></span></span>
</h3>
<div class="ak-whipcount-callbox">
<div class="ak-whipcount-boxhead">
<div class="ak-target-name">{{ target.title_full }}:</div>
<div class="ak-target-phone">{{ target.phone }}</div>
</div>
<div class="ak-whipcount-boxbody">
<label for="response-{{target.id}}">What is {{ target.title_full }}'s stance on this issue?</label>
<ul class="ak-errs-below ak-err-below">
<li>
<label for="uncommitted-{{ target.id }}"><input type="radio" name="response-{{ target.id }}" value="uncommitted" id="uncommitted-{{ target.id }}"> Uncommitted/Did not answer</label>
</li>
<li>
<label for="supportive-{{ target.id }}"><input type="radio" name="response-{{ target.id }}" value="supportive" id="supportive-{{ target.id }}"> Supportive of our position</label>
</li>
<li>
<label for="opposed-{{ target.id }}"><input type="radio" name="response-{{ target.id }}" value="opposed" id="opposed-{{ target.id }}"> Opposed to our position</label>
</li>
<li>
<label for="message-{{ target.id }}"><input type="radio" name="response-{{ target.id }}" value="message" id="message-{{ target.id }}"> Left a message</label>
</li>
</ul>
<input type="hidden" name="required" value="response-{{ target.id }}">
<input type="hidden" name="error_response-{{target.id}}:missing" value="Please let us know what {{ target.title_last }} responded!">
</div>
</div>
</div>
<div class="ak-grid-col ak-grid-col-4-of-12">
<h3>
<label class="ak-step-label">
<div class="ak-step-number">3</div>
Report the call
</label>
<span class="ak-arrow-holder"><span class="ak-arrow"></span></span>
</h3>
<div class="ak-styled-fields {{templateset.custom_fields.field_labels_class|default:'ak-labels-overlaid'}} {{templateset.custom_fields.field_errors_class|default:'ak-errs-below'}}" id="ak-report-call">
{% include "./user_form_wrapper.html" %}
<div id="ak-survey_question"></div>
{% if form.survey_question_text %}
<script type="text/ak-template" for="ak-survey_question">
<label for="id_action_survey">{% filter striptags %}{% include_tmpl form.survey_question_text %}{% endfilter %}</label>
<textarea id="id_action_survey" name="action_survey" style="height: 100px"></textarea></p>
</script>
{% endif %}
</div>
<div style="clear: both;">
<button type="submit" class="ak-submit-button">Submit</button>
</div>
</div>
<input type="hidden" name="status" value="whipcount">
</div>
{% endif %}
</form>
{% endblock %}
{% block script_additions %}
<script type="text/javascript">
$(window).load(function() {
var $window = $(window);
function call_page_steps_mobile() {
var windowSize = $window.width();
if (windowSize < 480) {
$('.ak-steps-area h3').addClass('clickable');
} else {
$('.ak-steps-area h3').removeClass('clickable');
$('.ak-steps-area h3').each( function () {
$(this).siblings('div').show();
});
}
}
$('.ak-steps-area').on('click', 'h3.clickable', function(e) {
e.stopPropagation();
$(this).toggleClass('active');
$(this).siblings('div').stop().slideToggle('fast');
});
$(window).on('resize', call_page_steps_mobile);
call_page_steps_mobile();
});
</script>
{% endblock %}
Whipcount Results¶
The layout for the whipcount results.
<div id="ak-whipcount-targets">
{% for group in target_groups %}
<h3>{{ group.name }}</h3>
<table class="ak-whipcount-listing">
<thead>
<th>Name</th>
<th>Seat</th>
<th>Calls <span class="ak-hide-under-750">Reported</span></th>
<th>Stance</th>
<th></th>
</thead>
<tbody>
{% for target in group.targets %}
<tr class="ak-target-{{ target.stance.view }}">
<td>
<a class="ak-target-name ak-highlight-on-hover" href="?target={{ target.resource_uri }}&akid={{ user.token }}&source={{ args.source }}&referring_akid={{ args.referring_akid }}">{{ target.title_last }}</a>
</td>
<td>
{% if target.us_district %}
{{ target.us_district }}
{% elif target.seat %}
{{ target.seat }}
{% elif target.state %}
{{ target.state }}
{% else %}
{{ target.district_name }}
{% endif %}
</td>
<td>
{{ target.stance.calls }}
</td>
<td>
{% if not target.stance.view %}
<div class="ak-whipcount-icon">
<img src="/media/modern/stance-unknown.svg">
</div>
<span class="ak-target-stance">Unknown</span>
{% elif target.stance.view == 'supportive' %}
<div class="ak-whipcount-icon">
<img src="/media/modern/stance-supportive.svg">
</div>
<span class="ak-target-stance">{{ target.stance.view|title}}</span>
{% elif target.stance.view == 'opposed' %}
<div class="ak-whipcount-icon">
<img src="/media/modern/stance-opposed.svg">
</div>
<span class="ak-target-stance">{{ target.stance.view|title}}</span>
{% elif target.stance.view == 'uncommitted' %}
<span class="ak-target-stance">{{ target.stance.view|title}}</span>
{% endif %}
</td>
<td>
{% if not target.stance.view %}
<a href="?target={{ target.resource_uri }}&akid={{ user.token }}&source={{ args.source }}&referring_akid={{ args.referring_akid }}" class="ak-button">Call</a>
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endfor %}
</div>
Wrapper¶
Defines the overall site appearance; individual page types (i.e., survey), pull in the wrapper with {% extends "./wrapper.html" %}
.
<!DOCTYPE html>
<html lang="{{page.lang.iso_code|default:'en'}}"{% if page.lang.is_rtl %} dir="rtl"{% endif %}>
<head>
<meta charset="utf-8">
<title>{% block title %}{{ page.title }} | {% filter ak_text:"org_name" %}{% client_name %}{% endfilter %}{% endblock %}</title>
<script>startTime=new Date()</script>
<meta http-equiv="X-UA-Compatible" content="IE=edge;chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
{% block share_metatags %}
{{ page.followup.share_title_tag }}
{{ page.followup.share_description_tag }}
{{ page.followup.share_image_tag }}
{{ page.followup.share_url_tag }}
<meta property="og:site_name" content="{% filter ak_text:"org_name" %}{% client_name %}{% endfilter %}">
<meta property="og:type" content="article">
<meta name="twitter:card" content="summary">
{% endblock %}
{% block meta_additions %}{% endblock %}
{% load_css %}
//fonts.googleapis.com/css?family=Open+Sans:100,300,400,600,700
/media/modern/actionkit.css?1=22
{% end %}
{% block css_additions %}{% endblock %}
{% load_prefill %}
{% load_ak_context context %}
{% load_js %}
//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js
/resources/actionkit.js
{% end %}
<style>
{% if templateset.custom_fields.font_family %}
html {
font-family: {{ templateset.custom_fields.font_family|safe }};
}
{% endif %}
{% if templateset.custom_fields.font_size %}
html {
font-size: {{ templateset.custom_fields.font_size }};
}
{% endif %}
{% if templateset.custom_fields.color_page %}
div.ak-page-container {
background-color: {{ templateset.custom_fields.color_page }};
}
.ak-progress-meter .ak-progress-meter-border {
border-color: {{ templateset.custom_fields.color_page }};
}
.ak-whipcount-callbox .ak-whipcount-boxhead {
color: {{ templateset.custom_fields.color_page }};
}
@media (min-width:480px) {
body .ak-steps-area h3 div.ak-step-number {
color: {{ templateset.custom_fields.color_page }};
}
}
@media (max-width:479px) {
.ak-steps-area h3 {
color: {{ templateset.custom_fields.color_page }};
}
.ak-steps-area h3 div.ak-step-number {
background-color: {{ templateset.custom_fields.color_page }};
}
}
{% endif %}
{% if templateset.custom_fields.color_margin %}
body {
background-color: {{ templateset.custom_fields.color_margin }};
}
{% endif %}
{% if templateset.custom_fields.color_header %}
.ak-page-header {
background-color: {{ templateset.custom_fields.color_header }};
}
{% endif %}
{% if templateset.custom_fields.color_header_text %}
.ak-page-header {
color: {{ templateset.custom_fields.color_header_text }};
}
{% endif %}
{% if templateset.custom_fields.color_title|default:templateset.custom_fields.color_header %}
h2 {
color: {{ templateset.custom_fields.color_title|default:templateset.custom_fields.color_header }};
}
{% endif %}
{% if templateset.custom_fields.color_text %}
body,
a.ak-highlight-on-hover {
color: {{ templateset.custom_fields.color_text }};
}
.ak-donate-menu input:checked + div.ak-step-number {
background: {{ templateset.custom_fields.color_text }};
}
.ak-whipcount-callbox .ak-whipcount-boxhead {
background-color: {{ templateset.custom_fields.color_text }};
}
@media (min-width:480px) {
.ak-steps-area h3 label.ak-step-label {
color: {{ templateset.custom_fields.color_text }};
}
.ak-steps-area h3 div.ak-step-number {
background-color: {{ templateset.custom_fields.color_text }};
}
}
@media (max-width:479px) {
.ak-steps-area h3 {
background: {{ templateset.custom_fields.color_text }};
}
.ak-steps-area h3 div.ak-step-number {
color: {{ templateset.custom_fields.color_text }};
}
}
{% endif %}
{% if templateset.custom_fields.color_text_faded %}
.ak-faded-text,
.ak-labels-overlaid label.ak-is-overlaid.active,
.ak-donate-step input:checked span {
color: {{ templateset.custom_fields.color_text_faded }};
}
.ak-donate-menu div.ak-step-number {
background-color: {{ templateset.custom_fields.color_text_faded }};
}
{% endif %}
{% if templateset.custom_fields.color_link %}
a {
color: {{ templateset.custom_fields.color_link }};
}
{% endif %}
{% if templateset.custom_fields.color_link_hover %}
a:active,
a:hover,
a.ak-highlight-on-hover:hover,
label.ak-donate-step:hover {
color: {{ templateset.custom_fields.color_link_hover }};
}
.ak-donate-menu input:checked + div.ak-step-number:hover,
label.ak-donate-step:hover div.ak-step-number {
background-color: {{ templateset.custom_fields.color_link_hover }};
}
{% endif %}
{% if templateset.custom_fields.color_button %}
button,
input[type="submit"],
a.ak-button,
.ak-button {
background-color: {{ templateset.custom_fields.color_button }};
}
.ak-arrow:after,
.ak-arrow-inline:after {
color: {{ templateset.custom_fields.color_button }};
}
{% endif %}
{% if templateset.custom_fields.color_button_hover %}
button:hover,
input[type="submit"]:hover,
a.ak-button:hover,
.ak-button:hover {
background-color: {{ templateset.custom_fields.color_button_hover }};
}
{% endif %}
{% if templateset.custom_fields.color_button_text %}
button,
input[type="submit"],
a.ak-button,
.ak-button,
a.ak-button:hover,
.ak-button:hover {
color: {{ templateset.custom_fields.color_button_text }};
}
{% endif %}
{% if templateset.custom_fields.color_fieldbox %}
.ak-field-box,
.ak-accordion ul li {
background-color: {{ templateset.custom_fields.color_fieldbox }};
}
{% endif %}
{% if templateset.custom_fields.color_fieldbox_text %}
.ak-field-box,
.ak-accordion ul li {
color: {{ templateset.custom_fields.color_fieldbox_text }};
}
.ak-field-box .ak-donate-menu input:checked + div.ak-step-number {
background: {{ templateset.custom_fields.color_fieldbox_text }};
}
{% endif %}
{% if templateset.custom_fields.color_accentbox %}
#ak-whipcount-targets tbody tr,
.ak-newspaper-row,
.ak-signoff-box,
.ak-progress-meter .ak-progress-holder {
background-color: {{ templateset.custom_fields.color_accentbox }};
}
{% endif %}
{% if templateset.custom_fields.color_accentbox_text %}
#ak-whipcount-targets tbody tr,
.ak-newspaper-row,
.ak-signoff-box {
color: {{ templateset.custom_fields.color_accentbox_text }};
}
{% endif %}
{% if templateset.custom_fields.color_amount %}
#ak-amount-list li label {
background: {{ templateset.custom_fields.color_amount }};
}
{% endif %}
{% if templateset.custom_fields.color_amount_hover %}
#ak-amount-list li label:hover,
#ak-amount-list li label.ak-radio-checked,
div#ak-amount-list label[for="amount_other_field"].ak-radio-checked {
background-color: {{ templateset.custom_fields.color_amount_hover }};
}
{% endif %}
{% if templateset.custom_fields.color_progress %}
.ak-progress-meter .ak-progress-bar {
background-color: {{ templateset.custom_fields.color_progress }};
}
.ak-progress-meter .ak-progress-percent {
color: {{ templateset.custom_fields.color_progress }};
}
{% endif %}
{% if templateset.custom_fields.color_error %}
#ak-errors,
.ak-errors {
background-color: {{ templateset.custom_fields.color_error }};
}
.ak-styled-fields input[type="text"].ak-error,
.ak-styled-fields input[type="password"].ak-error,
.ak-styled-fields input[type="number"].ak-error,
.ak-styled-fields input[type="email"].ak-error,
.ak-styled-fields textarea.ak-error,
.ak-styled-fields select.ak-error,
input.ak-error,
select.ak-error,
textarea.ak-error {
border-color: {{ templateset.custom_fields.color_error }};
}
.ak-err,
.ak-color-error,
span.ak-error,
label.ak-error,
.ak-labels-overlaid input.ak-error,
.ak-labels-overlaid label.ak-error,
.ak-labels-before label.ak-error,
.ak-styled-fields select.ak-error,
ul.errorlist.ak-errors,
ul.errorlist li {
color: {{ templateset.custom_fields.color_error }};
}
{% endif %}
.ak-target-phone .ak-target-label, span.office_phone_label,
span.ak-target-fax, span.ak-target-separator { display: none }
.ak-event-description, .ak-event-note-to-attendees, .ak-event-directions { white-space: pre-line; }
</style>
{% block script_additions %}{% endblock %}
</head>
<body class="ak-pagetype-{{ filename|split:'.'|nth:0 }} ak-lang-{{page.lang.iso_code|default:"unknown"}}{% if page.lang.is_rtl %} ak-rtl{% endif %} ak-no-js {% block body_extra_classes %}{% endblock %}">
<script type="text/javascript">
actionkit.forms.initPage()
</script>
<div class="ak-page-header">
<div class="ak-page-header-contents">
<h1>{% filter ak_text:"org_name" %}{% client_name %}{% endfilter %}</h1>
{% include "./language_picker.html" %}
<div class="ak-page-nav"></div>
</div>
</div>
<div class="ak-page-container">
{% block content %}{% endblock %}
<div class="ak-page-footer">
<div class="ak-page-footer-contents">
<span>{% filter ak_text:"org_name" %}{% client_name %}{% endfilter %}</span>
<span><a href="{{ templateset.custom_fields.privacy|default:'//example.com/privacy' }}">{{ 'Privacy'|ak_text:'privacy' }}</a></span>
<span><a href="{{ templateset.custom_fields.contact|default:'//example.com/privacy' }}">{{ 'Contact'|ak_text:'contact' }}</a></span>
</div>
</div>
</div>
{% block below_form %}
<script type="text/javascript">
actionkit.forms.contextRoot = '/context/';
actionkit.forms.initForm('act');
</script>
{% endblock %}
{# Page Analytics Tag (often aka: "Google Tag"), if any #}
{{ analytics_tag_code|safe }}
{% if analytics_key %}
<script type="text/javascript">
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', '{{ analytics_key }}', 'auto');
ga('send', 'pageview');
</script>
{% endif %}
</body>
</html>
Template Changes in each Release¶
We provide the diffs of each change made to the Original templateset since it was released in October 2016 in order to help you keep your templateset up to date.
Where possible, we apply these updates to your templatesets automatically with no action required on your part. But we aren't always able to apply these changes automatically, especially if your templatesets have been heavily customized or if you are using the GitHub integration.
For this reason, we provide the precise diffs of each change so you can apply the changes to your templatesets on your own. See the Template Changes in each Release Reference for more.
Changes from the Previous Original¶
These are the major functional improvements and bug fixes that we’ve addressed in the new Original templateset released on 10/11/2016.
Overall changes
- Modernized design.
- Custom templateset fields allow for easy customization of colors, fonts and donation page layout.
- Built-in support for a featured image on action pages that is controlled through the custom page field called
Featured Image
. - For templateset developers, we’ve prepended “.ak-” to most AK-specific classes and moved the CSS out of the HTML files and into
actionkit.css
to make the set easier to work with.
User form changes
- Fixed label positions for custom action fields in the user form such that the labels are no longer overlapping the field choices for checkbox, radio, select, and multiselect input types.
- Clicking on a radio or checkbox label will now select the associated value.
Donation changes
- Option to choose between a multi-step donation form layout or to display all fields at once.
- Can update billing address for recurring donations on
recurring_update.html
. Updates are only supported for Braintree, Authorize.net and PayflowPro accounts; recurring donations made through Paypal cannot be updated through this form. Additionally, the billing address will be prefilled by the billing address stored in thecore_order_user_detail
table, and upon saving, will update that address in the table.
Changes to other action pages
- The map on the Event Attend page is now an interactive Google map which can be zoomed and panned.
- Phone numbers for targets on call and whipcount pages now display on a separate line from the target name.
- Reconfigured layout for LTE pages such that writing tips and sample letters are side-by-side with the newspaper list.
Improvements for mobile viewers
- A “Read More” tab will show up for action pages with long introductory text when viewing the page on a narrow screen. This hides the rest of the text behind a link that unveils the remainder of the section once clicked. Note that this kicks in at 4.5 em height, so sentences will likely be cut short, and if a word spans two lines it could also break mid-word. Only petition, letter, survey, call, whipcount and LTE page types have the “Read More” feature.
- Call and whipcount pages get a special mobile layout that toggles the call step visibility.
Custom Templateset Fields Reference¶
The fields included in the Original templateset are:
- Font Family - The base font style used throughout the page. Defaults to "Open Sans".
- Font Size - The size of regular text; other elements will be sized larger or smaller than this by percentages. Defaults to "15.5px".
- Page Header Color - Background color for the top section of every page. Defaults to
#668d24
. Also sets the color for the page titles by default. - Text Color - Primary text color for content written on your pages. Defaults to
#4b4b4b
. - Button Color - Background color for action buttons. Defaults to
#007bc5
. Applies to all buttons except for donation amount buttons. - Progress Color - Color used for progress bar fill and text showing percentage of actions completed. Defaults to
#884974
. - Donation Page Steps - Defaults to "Three Steps (Amount, Name, Payment)". Or you can select "All Fields on One Screen" to display all form fields on the page at once.
There are additional custom templateset fields that you could add to the Original templateset. Those are:
- Accent Box Color - Background color for boxes around some additional information. Defaults to
#e7e7e7
. - Accent Box Text Color - Text color used within boxes around some additional information. Defaults to
#4b4b4b
. - Amount Color - Background color for donation amount buttons. Defaults to
#d7d7d7
. - Amount Hover Color - Highlight color used for selected donation amount button. Defaults to
#FFC700
. - Button Hover Color - Highlight color used for buttons when the mouse is positioned over them. Defaults to
#31a8f0
. - Button Text Color - Color of the text labels identifying action buttons. Defaults to
#ffffff
. - Error Color - Used to show error messages and highlight fields that need correction. Defaults to
#dd0000
. - Field Box Color - Background color for boxes used to contain some submission forms. Defaults to
#f3f6f7
. - Field Box Text Color - Text color used within boxes around some submission forms. Defaults to
#4b4b4b
. - Field Error Position - Where should error messages appear relative to the fields they describe. Defaults to "Below Fields".
- Field Label Position - Where should field labels appear relative to their input elements. Defaults to "Overlaid on Fields".
- Link Color - Primary color user for hyperlinked text. Defaults to
#268ECD
. - Link Hover Color - Highlight color used for hyperlinks when the mouse is positioned over them. Defaults to
#31a8f0
. - Page Background Color - The primary background used for page content. Defaults to
#ffffff
. - Page Header Text Color - Color of the text on the top section of every page. Defaults to
#ffffff
. - Page Margin Color - Shown at the left and right edges of the page on large screens. Defaults to
#efefef
. - Page Title Color - Text color used for the headline containing the page title. Defaults to
#668d24
. - Subdued Text Color - A softer color used for supporting text and instructions. Defaults to
#909090
.
Context Object Reference¶
If your JavaScript needs access to internal ActionKit information to do its thing, these are the documented global variables available through the context object:
actionkit.context.recognized_user
- true when the user is recognized.actionkit.context.required
- a partial list of required fields. Instead of using this, call actionkit.forms.required() to get the full list.
actionkit.context.name
- the user name to display, if user is recognized.actionkit.context.incomplete
- true when the user needs to provide contact information before they see the personalized action page, e.g., on call and LTE pages.actionkit.text
- Translated text for error messages, field names, etc. (may not be available until afteractionkitFormReady
)
There's additional data in actionkit.context
you typically use indirectly rather than from a script:
actionkit.context.progress
- used by progress meter; has a number of actions taken (or dollars raised) and any goal you set when creating the page in the admin.actionkit.context.targets
- usable in the "What to say" section of call pages if you're hosting the page on your site (rather than on ActionKit). Instead of directly scripting with this, you'll typically use snippets, see Edit Content and Call Page Snippets.
The other information in context
isn't documented, and might be changed in future releases.
You can inspect a page's context directly in your browser's developer tools: the Web Console (in Firefox), Web Inspector's Console tab (in Chrome and Safari), or F12 Developer Tools's Script tab (in Internet Explorer). If you're interested in doing something with undocumented parts of the context, it's probably best to let us know what you're trying to do via the Support tab; we might have an easier or more reliable approach, and in any case it's helpful for us to know when people are running against the limits of supported features.
You can also edit your templates to pass other information to your scripts; for example, this would put the page title:
<script>window.actionkitPageTitle = {{page.title|json}};</script>
User Form Field Variable Reference¶
Within the user_form.html template, there are a number of attributes of form fields you can reference to customize the form layout.
All of the following apply within the context of a {% for field in user_fields %}
loop:
{{ field.field_name }}
- contains the field name to be used for HTML inputs{{ field.label }}
- contains custom label text if provided by user{{ field.label_text }}
- returns translated field label or uses field name after replacing underscores with spaces{{ field.type }}
- contains the field's scope, one of "user" (built-in user fields), "custom" (custom user fields), "action", or "html".{{ field.input }}
- contains the field's input style, one of "html", "text", "textarea", "number", "select", "multiple", "radio", or "checkbox".{{ field.input_html }}
- generates standard HTML input elements for the field type{{ field.input_tag }}
- same as input_html except wraps <span> tags around the labels for checkbox and radio fields instead of <label> tags.{{ field.html }}
- for HTML fields, contains the user-provided chunk of HTML{{ field.alternative }}
- for fields with predefined choices, contains choices as multiline text block{{ field.alternative_pairs }}
- for fields with predefined choices, returns choices as a list of lists, with each choice being a pair of value and label
Definitions¶
Following are terms you may see in the templates, CSS or Javascript:
- form() - Maps to the
cms_form
and thecms_FORMTYPE_form
tables. There is aform
object for each page type.
- args() - The
QueryDict
from the request. See the django documentation.
page - Hidden field giving the "short name" specified during page creation, maps to the
core_page
table. An example from the Call template is:<input type="hidden" name="page" value="{{ page.name }}">
- lists - Hidden field providing numeric ID(s) of the list(s) the user will be added too. You must provide a link to the privacy policy from any page that signs users up for lists. If you want to have an opt-in checkbox in a form, you can make lists a checkbox instead of a hidden field. See the example for Creating an opt-in page
- taf_emails - The email addresses of friends to receive tellafriend messages.
- taf_body - The body of the tellafriend message. If there's no
taf_body
field in the form, the text you supplied when setting up the page will be used.
Some hidden fields and methods are automatically added to the templates by actionkit.js.
akid - The user's hashed ActionKit user and mailing ID in this format:
[optional mailing id].[user_id].[hash].
- referring_akid - The user and mailing ID of the referring user, that is, the user who sent a tellafriend message or forwarded the mailing.
- forms() - See Forms.
- utils() - See Utils.
- source - An arbitrary "source" tag you can choose (e.g., "banner_ads").
- want_progress - Is set to 1 if the page includes a progress meter.
- js - Is set to 1 if the user has JavaScript available.
- url, t, rd - Used in click-through tracking.
- utf8 - A hidden field that forces the browser to submit the response in Unicode.
Cascading Style Sheet Reference¶
This reference includes the code for actionkit.css and ak-look.css files.
actionkit.css¶
body.js form.ak-form,
#ak-errors,
#ak-confirmation,
#ak-error-info,
.ak-errors,
.ak-confirmation,
.ak-error-info {
display: none
}
input.ak-error, select.ak-error, textarea.ak-error {
background-color: rgb(255,200,200);
border-color: red;
}
label.ak-error {
color: red;
font-weight: bold;
}
#ak-errors,
#ak-confirmation,
.ak-errors,
.ak-confirmation {
list-style-type: none;
font-weight: bold;
color: white;
padding: 7px;
margin: 7px;
}
#ak-errors, .ak-errors {
background-color: red;
}
#ak-confirmation, .ak-confirmation {
background-color: green;
}
form.contains-errors #ak-errors,
form.contains-errors #ak-error-info,
form.contains-errors .ak-errors,
form.contains-errors .ak-error-info {
display: block;
}
.ak-err { /* inline error */
color: red;
list-style-type: none;
padding: 0px;
margin: 0px;
}
.ak-err-above .ak-err { margin-top: 0.5em; }
.ak-err-below .ak-err { margin-bottom: 0.5em; }
ul#ak-errors li,
ul.ak-errors li {
padding: 0px;
margin: 0px;
}
#known_user, .known_user {
display: none;
}
.taf_body {
border: solid rgb(128,128,128) 1px;
padding: 5px;
}
div.event-signup {
zoom: 1; /* work around IE 8 content-hiding bug */
}
/* Targets */
div.target {}
a.local_toggle {}
span.local_toggle_label {font-size: 90%;font-weight:normal}
div.office {display:none;font-weight:normal}
span.office_phone {font-size:90%;color:#666;font-weight:normal}
span.office_phone_label {font-wight:bold}
span.office_fax {font-size:90%;color:#666;font-weight:normal}
span.office_fax_label {font-wight:bold}
/* sets a parent for some other positioning styles */
.ak-labels-above, .ak-labels-overlaid {
position: relative
}
.ak-labels-above input, .ak-labels-overlaid input,
.ak-labels-above textarea, .ak-labels-overlaid textarea, .ak-labels-above select, .ak-labels-overlaid select {
border: solid rgb(160,160,160) 1px;
margin: 3px 0px;
font-weight: bold;
font-weight: normal;
}
.ak-labels-above input, .ak-labels-overlaid input,
.ak-labels-above textarea, .ak-labels-overlaid textarea {
padding: 3px;
}
.ak-labels-above input, .ak-labels-above select, .ak-labels-above textarea,
.ak-no-js .ak-labels-overlaid input, .ak-no-js .ak-labels-overlaid select,
.ak-no-js .ak-labels-overlaid textarea {
margin-top: 0px;
}
.ak-err li {
line-height: 1.4em;
}
.ak-labels-overlaid input, .ak-labels-overlaid textarea, .ak-labels-overlaid select, .ak-labels-overlaid label,
.ak-labels-before input, .ak-labels-before textarea, .ak-labels-before select, .ak-labels-before label {
width: 100%;
box-sizing: border-box;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
-ms-box-sizing: border-box;
}
.ak-labels-overlaid input[type="radio"],
.ak-labels-overlaid input[type="checkbox"] {
width: auto;
}
.ak-labels-overlaid textarea {
vertical-align: top;
}
/* labels to left (right if RTL) */
.ak-labels-before label { width: 32%; float: left; display: inline-block; text-align: right; }
.ak-labels-before label:after { content: ":"; }
.ak-labels-before input, .ak-labels-before select, .ak-labels-before textarea, .ak-labels-before .ak-err { width: 65%; float: right; }
.ak-labels-before > * { clear: both; }
/* labels above */
.ak-labels-above label, .ak-labels-above .ak-checkbox-field, .ak-label-above, .ak-no-js .ak-labels-overlaid label { display: block; font-weight: bold; margin-top: 0.5em; color: rgb(100,100,100); }
/* labels overlaid */
.js .ak-labels-overlaid label {
position: absolute;
padding: 4px;
color: rgb(100,100,100);
/* These are redundant, but IE7 needs them */
left: 0px;
z-index: 1;
}
.js .ak-labels-overlaid label.active {
color: rgb(140,140,140);
}
.js .ak-labels-overlaid label.has-content {
display: none;
}
.ak-labels-overlaid > div {
position: relative;
}
.ak-required-flag { color: red; }
/* mirror the styles if RTL */
.ak-rtl { direction: rtl; }
.ak-rtl .ak-labels-before input, .ak-rtl .ak-labels-before select, .ak-rtl .ak-labels-before textarea { width: 65%; float: left; }
.ak-rtl .ak-labels-before label { float: right; text-align: left }
.taf-mailto { clear: both; }
#progress { text-align: center; position: relative; }
.progress-holder { margin-left: auto; margin-right: auto; height: 50px; width: 300px; max-width: 100%; position: relative; }
.progress-bar { position: absolute; height: 50px; z-index: 1; left: 0px; }
.progress-percent { position: relative; z-index: 2; font-weight: bold; padding-top: 10px; font-size: 20pt; line-height: 24pt; }
.progress-caption { padding-top: 2px; }
/* classic-progress: green gradient bar with images from actionkit day 1 */
.classic-progress .progress-holder { background-image: url(/samples/green-bar-0.png); }
.classic-progress .progress-bar { background-image: url(/samples/green-bar-100.png); }
/* rounded-progress: sort of a blingy css3 rounded bar (displays square on old browsers) */
.rounded-progress .progress-holder { border: solid #aaa 2px; background-color: white; border-style: inset; border-radius: 25px; }
.rounded-progress .progress-bar { background-color: #7a7; border-radius: 23px; }
/* basic-progress: neutral-looking grey bar */
.basic-progress .progress-holder { border: solid #aaa 2px; background-color: white; background-color: rgba(255,255,255,0.2); border-radius: 5px; }
.basic-progress .progress-bar { background-color: #777; border-radius: 3px; }
/* use an "ak-continued" link to jump to explanatory content on mobile */
.ak-mobile-lead, .ak-continued {
/* hiding this way keeps it visible to screenreaders which could also use the link */
position: absolute; left: -999em;
}
.ak-nodisplay { display: none; }
/* Explicit opt-in checkbox styles */
#id_subscription_consent_box { display: none; }
#id_subscription_consent { display: inline; width: auto; }
#id_subscription_consent_box label { display: inline; position: static; color: inherit; }
#id_subscription_consent_more { display: none; }
ak-look.css¶
/*
* Overall grid and layout
*/
/* Page types */
#call-form { width: 40%; }
#call-story { width: 60%; }
#donation-contact { width: 40%; }
#donation-details { width: 60%; }
#event-attend-form { width: 40%; }
#event-create-form { width: 50%; }
#letter-form { width: 40%; }
#letter-story { width: 60%; }
#letter-story .box { width: 100% }
#letter-story textarea { font-size: 1.2em; height: 14em; }
#lte-prelim { width: 40%; }
#lte-letter { width: 100%; }
#lte-help { width: 100%; }
#petition-box { width: 60%; }
#petition-story { width: 60%; }
#petition-form { width: 40%; }
#recurring-cancel { width: 60%; }
#recurring-update { width: 60%; }
#signup-form { width: 40%; }
#signup-story { width: 60%; }
#survey-contact { width: 40%; }
#survey-questions { width: 60%; }
#taf-form { width: 50%; }
#taf-preview { width: 50%; }
#thanks-notaf { width: 100%; }
#unsub-form { width: 50%; }
/* [whipcount/login/account tools/recurring cancel/update] */
/* Box sizing so percents work the way we want. Our JS makes it work on IE7 */
.container, .col, input, select, textarea {
box-sizing: border-box;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
}
/* Sizes and padding */
body { margin: 0px; }
.container {
width: 900px;
padding: 0px 20px;
max-width: 100%;
}
.col, .border.col { padding: 5px 15px; margin: 0px !important; }
.col { float: left; }
.col.end { float: right; }
.area { padding: 15px; }
/* Headers */
.header { border-bottom: solid #ddd 1px; padding: 10px; }
h1, h2, h3 { margin: 0px; font-weight: bold; line-height: 1.2em; padding: 15px; color: rgb(80, 80, 80); }
.header h1 { padding: 5px; }
.col h2, .col h2, .area h2, .area h3 { padding: 0px; }
/* Footer */
.footer-holder { padding-top: 15px; }
.footer { border-top: solid #ddd 1px;
padding: 15px;
margin-top: 25px;
text-align: right;
}
.footer span:before { content: "\00b7\00a0"; }
.footer span:first-child:before { content: ""; }
.footer-holder { clear: both; }
.ak-rtl .footer { text-align: left; }
.ak-rtl .col { float: right; }
.ak-rtl .col.end { float: left; }
/*
* Details: specific form elements, input styles, default font
*/
/* Emphasized box, para spacing, headers */
.box { background-color: rgb(200,200,200); padding: 20px; }
.col p, .box p, .area p { margin: 1em 0px 0px 0px; }
.col p:first-child, .box p:first-child, .area p:first-child { margin: 0px; }
/* Input and text styles */
fieldset { padding-top: 0.5em; border: 1px solid #aaa; border-radius: 10px; }
legend { margin-left: -5px; padding: 0px 5px; }
textarea { height: 4em; width: 100%; }
input, select, textarea, .taf_body { border-radius: 4px; }
select { padding: 3px 0px; }
p, div { line-height: 1.7em; }
p { margin-top: 1.5em; margin-bottom: 0em; }
label { font-weight: normal; }
button { float: none; /* Blueprint makes them float. */ }
button:hover { background-color: #DEDEDE; border-color: #CECECE; color: #464646; }
/* Thanks and tellafriend */
.fb-like { float:right; clear:right; border:none; overflow:hidden; width:300px; height:80px; padding-top: 5px; }
.floating-progress { float: right; clear: right; width: 300px /* f/ie7 */; margin-left: 0px; margin-right: 15px; }
#taf { clear: both; }
#id_comment, #id_taf_emails { height: 4em; width: 100%; }
#id_taf_note { height: 6em; }
.area #progress { margin-right: 0px; }
/* Donate */
#card_num { width: 100%; }
#card_code_box, #exp_date_box { width: 50%; float: left; }
#progress { margin: 15px; }
#product_list td, #candidate_list td { vertical-align: top; }
#product_list th, #candidate_list th { background-color: #eee; }
#products-label, #candidates-label { position: absolute; left: -999em; }
.candidate-portrait { float: left; margin: 0px 10px 0px 0px; }
.candidate-name, .product-name { font-weight: bold; }
.candidate-amount, .product-quantity, .product-amount { width: 1%; }
.donation-total { background-color: yellow; padding: 5px; font-weight: bold; }
/* LTE */
#lte-submit { clear: both; }
/* A default font */
p, body, input, select, textarea, button, div {
font-size: 13px;
font-family: Georgia, serif;
}
/* Changes for mobile */
@media (max-width:750px) {
body { background-image: none; }
.container, .area { padding: 0px; }
.col, .container, .area, .sidebar { width: 100% !important; }
.border { border-right: none !important; }
.ak-mobile-lead, .ak-continued { position: static !important; left: auto !important; }
/* a mobile screen isn't wide enough for two-column grid of labels/inputs, so flatten it */
.ak-labels-before label, .ak-labels-before input, .ak-labels-before select, .ak-labels-before textarea, .ak-labels-before .ak-err { width: 100%; }
.ak-labels-before label { text-align: left; }
.ak-rtl .ak-labels-before label { text-align: right; }
}
Social Plugins¶
Add links to Facebook and Twitter.