Code Snippets
Find below a list of code snippets that can be used in your projects. These are all snippets that we already use in our projects and are tested.
Email Button
A simple email button that allows users to email their selected city councillor.
Basic Email Structure
The email template is defined in the emailCouncillor
function using two main components:
const subject = "Constituent Feedback - [Your Issue]";
const body = `Dear ${councillor.name},
// ... rest of the email content
`;
How to Modify the Template
1. Changing the Subject Line
Locate the subject
constant in the emailCouncillor
function:
2. Modifying the Email Body
Find the body
template string (marked with backticks `) and modify its content:
3. Available Variables
The following variables are available for use in your template:
- ${councillor.name}
- Councillor's full name
- ${councillor.ward}
- Ward name
- ${councillor.title}
- Councillor's title
- ${councillor.email}
- Councillor's email address
4. Special Characters and Formatting
- Use
\n
for line breaks - Avoid using special characters like
"
or'
directly - escape them if needed - Remember that HTML formatting will not work in email clients
Example Templates
General Inquiry Template
const subject = "General Inquiry from Constituent";
const body = `Dear ${councillor.name},
I am a constituent from ${councillor.ward} seeking information about...`;
Specific Issue Template
const subject = "Urgent: Traffic Safety Concern";
const body = `Dear ${councillor.name},
I am writing regarding a safety concern at the intersection of...`;
Meeting Request Template
const subject = "Meeting Request from ${councillor.ward} Constituent";
const body = `Dear ${councillor.name},
I would like to schedule a meeting to discuss...`;
Implementation Tips
- Keep subject lines concise and specific
- Include clear calls to action in the body
- Maintain professional formatting
- Test the template with various email clients
- Consider mobile device compatibility
Technical Notes
- The template uses
encodeURIComponent()
to properly encode special characters - Maximum email length may vary by email client
- Some email clients may have limitations on mailto link functionality
Edmonton Council Emailer Code
<!-- Begin Edmonton Council Emailer -->
<div id="edmonton-council-emailer" class="ece-container">
<style>
#edmonton-council-emailer,
#edmonton-council-emailer * {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: inherit;
}
#edmonton-council-emailer.ece-container {
position: relative;
width: 100%;
max-width: 1200px;
margin: 20px auto;
padding: 30px;
font-family: Arial, sans-serif;
font-size: 16px;
line-height: 1.5;
color: #fff;
background: #1e2124;
border-radius: 12px;
isolation: isolate;
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2);
}
#edmonton-council-emailer .ece-button-container {
display: flex;
align-items: center;
gap: 20px;
background: #2a2d31;
padding: 20px;
border-radius: 8px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}
#edmonton-council-emailer .ece-button {
padding: 15px 30px;
font-size: 18px;
background-color: #ffc107;
color: #000;
border: none;
border-radius: 8px;
cursor: pointer;
transition: all 0.3s ease;
font-weight: bold;
text-transform: uppercase;
letter-spacing: 1px;
}
#edmonton-council-emailer .ece-button:hover {
background-color: #ffcd38;
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(255, 193, 7, 0.3);
}
#edmonton-council-emailer .ece-modal {
display: none;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0,0,0,0.8);
z-index: 2147483647; /* Set to maximum value */
}
#edmonton-council-emailer .ece-modal-content {
position: relative;
background-color: #1e2124;
margin: 5% auto;
padding: 30px;
width: 80%;
max-width: 1200px;
max-height: 80vh;
overflow-y: auto;
border-radius: 12px;
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);
border: 1px solid #ffc107;
}
#edmonton-council-emailer .ece-close {
position: absolute;
right: 20px;
top: 20px;
font-size: 28px;
cursor: pointer;
color: #ffc107;
text-decoration: none;
line-height: 1;
transition: all 0.3s ease;
width: 40px;
height: 40px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 50%;
background: #2a2d31;
}
#edmonton-council-emailer .ece-close:hover {
background: #ffc107;
color: #000;
transform: rotate(90deg);
}
#edmonton-council-emailer .ece-councillor-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
gap: 20px;
margin-top: 20px;
}
#edmonton-council-emailer .ece-councillor-card {
border: 1px solid #2a2d31;
border-radius: 12px;
padding: 15px;
cursor: pointer;
transition: all 0.3s ease;
background-color: #2a2d31;
}
#edmonton-council-emailer .ece-councillor-card:hover {
transform: translateY(-5px);
box-shadow: 0 8px 24px rgba(255, 193, 7, 0.2);
border-color: #ffc107;
}
#edmonton-council-emailer .ece-councillor-card img {
width: 100%;
height: 200px;
object-fit: cover;
border-radius: 8px;
transition: all 0.3s ease;
}
#edmonton-council-emailer .ece-councillor-card:hover img {
transform: scale(1.02);
}
#edmonton-council-emailer .ece-councillor-card h3 {
margin: 15px 0 5px;
color: #fff;
font-size: 1.2em;
font-weight: bold;
}
#edmonton-council-emailer .ece-councillor-card p {
margin: 5px 0;
color: #ffc107;
font-size: 1em;
}
#edmonton-council-emailer .ece-modal h2 {
color: #ffc107;
font-size: 2em;
margin-bottom: 30px;
font-weight: bold;
text-align: center;
}
@keyframes countUp {
from {
transform: translateY(20px);
opacity: 0;
}
to {
transform: translateY(0);
opacity: 1;
}
}
#edmonton-council-emailer {
position: static; /* Remove any positioning if unnecessary */
z-index: auto; /* Reset z-index */
}
</style>
<div class="ece-button-container">
<button class="ece-button" onclick="ECE.openModal()">Email Your Councillor</button>
</div>
<div class="ece-modal" id="ece-modal">
<div class="ece-modal-content">
<span class="ece-close" onclick="ECE.closeModal()">×</span>
<h2>Select Your City Councillor</h2>
<div class="ece-councillor-grid" id="ece-councillor-grid"></div>
</div>
</div>
<script>
const ECE = {
count: 0,
councillors: [
{
name: "Mayor Amarjeet Sohi",
title: "City-Wide Mayor",
email: "[email protected]",
image: "https://www.edmonton.ca/sites/default/files/public-files/feature-images/Mayor-Sohi-800x494.jpg",
ward: "City-Wide"
},
{
name: "Councillor Erin Rutherford",
title: "Ward Anirniq Councillor",
email: "[email protected]",
image: "https://www.edmonton.ca/sites/default/files/public-files/feature-images/Anirniq-councillor_800x494.jpg",
ward: "Anirniq"
},
{
name: "Councillor Aaron Paquette",
title: "Ward Dene Councillor",
email: "[email protected]",
image: "https://www.edmonton.ca/sites/default/files/public-files/feature-images/Dene-councillor_800x494.jpg",
ward: "Dene"
},
{
name: "Councillor Jennifer Rice",
title: "Ward Ipiihkoohkanipiaohtsi Councillor",
email: "[email protected]",
image: "https://www.edmonton.ca/sites/default/files/public-files/feature-images/Ipiihkoohkanipiaohtsi-councillor_800x494.jpg",
ward: "Ipiihkoohkanipiaohtsi"
},
{
name: "Councillor Keren Tang",
title: "Ward Karhiio Councillor",
email: "[email protected]",
image: "https://www.edmonton.ca/sites/default/files/public-files/feature-images/Karhiio-councillor_800x494.jpg",
ward: "Karhiio"
},
{
name: "Councillor Ashley Salvador",
title: "Ward Métis Councillor",
email: "[email protected]",
image: "https://www.edmonton.ca/sites/default/files/public-files/feature-images/Métis-councillor_800x494.jpg",
ward: "Métis"
},
{
name: "Councillor Andrew Knack",
title: "Ward Nakota Isga Councillor",
email: "[email protected]",
image: "https://www.edmonton.ca/sites/default/files/public-files/feature-images/Nakota-Isga-councillor_800x494.jpg",
ward: "Nakota Isga"
},
{
name: "Councillor Anne Stevenson",
title: "Ward O-day'min Councillor",
email: "[email protected]",
image: "https://www.edmonton.ca/sites/default/files/public-files/feature-images/O-day'min-councillor_800x494.jpg",
ward: "O-day'min"
},
{
name: "Councillor Michael Janz",
title: "Ward papastew Councillor",
email: "[email protected]",
image: "https://www.edmonton.ca/sites/default/files/public-files/feature-images/papastew-councillor_800x494.jpg",
ward: "papastew"
},
{
name: "Councillor Tim Cartmell",
title: "Ward pihêsiwin Councillor",
email: "[email protected]",
image: "https://www.edmonton.ca/sites/default/files/public-files/feature-images/pihêsiwin-councillor_800x494.jpg",
ward: "pihêsiwin"
},
{
name: "Councillor Sarah Hamilton",
title: "Ward sipiwiyiniwak Councillor",
email: "[email protected]",
image: "https://www.edmonton.ca/sites/default/files/public-files/feature-images/sipiwiyiniwak-councillor_800x494.jpg",
ward: "sipiwiyiniwak"
},
{
name: "Councillor Jo-Anne Wright",
title: "Ward Sspomitapi Councillor",
email: "[email protected]",
image: "https://www.edmonton.ca/sites/default/files/public-files/feature-images/Sspomitapi-councillor_800x494.jpg",
ward: "Sspomitapi"
},
{
name: "Councillor Karen Principe",
title: "Ward tastawiyiniwak Councillor",
email: "[email protected]",
image: "https://www.edmonton.ca/sites/default/files/public-files/feature-images/tastawiyiniwak-councillor_800x494.jpg",
ward: "tastawiyiniwak"
}
],
init: function() {
if (window.ECEInitialized) return;
window.ECEInitialized = true;
document.getElementById('ece-modal').addEventListener('click', function(event) {
if (event.target === this) {
ECE.closeModal();
}
});
},
createCouncillorCards: function() {
const grid = document.getElementById('ece-councillor-grid');
if (!grid) return;
this.councillors.forEach(councillor => {
const card = document.createElement('div');
card.className = 'ece-councillor-card';
card.innerHTML = `
<img src="${councillor.image}" alt="${councillor.name}">
<h3>${councillor.name}</h3>
<p>${councillor.ward}</p>
`;
card.onclick = () => this.emailCouncillor(councillor);
grid.appendChild(card);
});
},
openModal: function() {
const modal = document.getElementById('ece-modal');
if (!modal) return;
modal.style.display = 'block';
if (!document.getElementById('ece-councillor-grid').children.length) {
this.createCouncillorCards();
}
},
closeModal: function() {
const modal = document.getElementById('ece-modal');
if (modal) modal.style.display = 'none';
},
emailCouncillor: function(councillor) {
this.closeModal();
const subject = "Constituent Feedback - [Your Issue]";
const body = `Dear ${councillor.name},
I am a constituent in ${councillor.ward} and I am writing to you regarding [describe your issue].
[Describe how this issue affects you and your community]
I would appreciate if you could [describe your requested action].
Thank you for your time and consideration.
Sincerely,
[Your Name]
[Your Address]
[Your Phone Number]`;
const encodedSubject = encodeURIComponent(subject);
const encodedBody = encodeURIComponent(body);
window.location.href = `mailto:${councillor.email}?subject=${encodedSubject}&body=${encodedBody}`;
}
};
// Initialize the component when the document is ready
document.addEventListener('DOMContentLoaded', function() {
ECE.init();
});
</script>
</div>
<!-- End Edmonton Council Emailer -->