Skip to content

Instantly share code, notes, and snippets.

@tmcw
Created August 4, 2016 20:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tmcw/1632f74c5ee4d3458c63c911a7c6df04 to your computer and use it in GitHub Desktop.
Save tmcw/1632f74c5ee4d3458c63c911a7c6df04 to your computer and use it in GitHub Desktop.
// arbitrary counter for ids and for attributes
var counter = 0;
var state = {
choices: []
};
var products = [
f('Studio'),
f('iOS SDK'),
f('Android SDK'),
f('Atlas'),
q('REST APIs', [
f('Maps'),
f('Static Maps'),
f('Geocoding'),
f('Directions'),
f('Uploads'),
f('Distance'),
f('Analytics'),
f('Map Matching')
]),
f('Studio Classic'),
f('TileMill')
];
var root = [q('How can we help you?', [
q('-- Select a topic --'),
q('Billing, signing in, and payments'),
q('Report a bug', [
q('-- Select a type of bug --'),
q('With Mapbox software',
[q('-- Select the relevant software --')]
.concat(products)
.concat(f('Other'))
),
f('Incorrect geocoding results', { custom: 'geocoder-feedback' }),
q('Missing or low-quality satellite imagery'),
q('An error in our maps', [
f('A place is incorrectly titled, a road missing, or other data errors', { custom: 'map-feedback' }),
f('Another problem')
]),
f('A typo or content issue on our website or blog', { custom: 'typo' })
]),
q('Logging in and managing your account', [
q('-- Tell us more... --'),
f('Logging in and out'),
f('Resetting a password'),
f('Multi-factor Authentication'),
f('Other')
]),
q('Using Mapbox',
[q('-- Select the relevant software --')]
.concat(products)
.concat(f('Other'))
),
f('Report missing attribution', { custom: 'attribution' })
])];
function q(t, options) {
return {
title: t,
type: 'select',
options: options || []
};
}
function f(t, options) {
return {
title: t,
type: 'form',
options: options || {}
};
}
function generateForm(depth, question, value) {
var container = document.createElement('div');
container.className = 'pad1y';
container.innerHTML = $('#' + (question.options.custom || 'default-form')).html();
return container;
}
function generateQuestion(depth, question, value) {
var id = 'form-' + counter++;
var container = document.createElement('div');
container.className = 'space-bottom2';
if (depth == 0) {
var title = container.appendChild(document.createElement('label'));
title.innerText = question.title;
title.setAttribute('for', id);
}
var select = container.appendChild(document.createElement('select'));
select.className = 'funny-select col12';
select.id = id;
question.options.forEach(function(opt) {
var elem = select.appendChild(document.createElement('option'));
elem.value = opt.title;
elem.innerText = opt.title;
if (opt.title.match(/^--/)) elem.disabled = true;
});
select.onchange = function() {
dispatch({
type: 'ANSWER_QUESTION',
depth: depth,
value: this.value
});
};
if (value) select.value = value;
return container;
}
function generateQuestions(state) {
var container = document.createElement('div');
var node = root[0];
state.choices.concat([undefined]).forEach(function (choice, i) {
if (!node) return;
switch (node.type) {
case 'select':
container.appendChild(generateQuestion(i, node, choice));
break;
case 'form':
container.appendChild(generateForm(i, node, choice));
break;
}
node = node.type === 'select' && node.options.filter(function (o) {
return o.title === choice;
})[0];
});
return container;
}
function dispatch(action) {
state = reducer(state, action);
render(state);
}
function reducer(state, action) {
switch (action.type) {
case 'ANSWER_QUESTION':
if (action.depth < state.choices) {
state.choices = state.choices.slice(0, action.depth);
}
state.choices[action.depth] = action.value;
}
return state;
}
function render(state) {
$('#app')
.html('')
.append(generateQuestions(state));
}
render(state);
<html>
<head>
<link href='https://www.mapbox.com/base/latest/base.css' rel='stylesheet' />
<script src='https://code.jquery.com/jquery-3.1.0.js'></script>
<style>
.funny-select {
font: 12px/20px 'Open Sans Bold', sans-serif;
background: rgba(0,0,0,0.25);
color: #fff;
border: none;
height: 40px;
margin: 0;
padding: 10px;
cursor: pointer;
line-height: 19px;
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
}
</style>
</head>
<body>
<div class='limiter fill-darken0 clearfix'>
<div class='col8'>
<div class='pad4'>
<form id='app' />
</div>
</div>
</div>
<script type='template' id='default-form'>
<textarea class='col12 clean round space-top0' placeholder='Write your message here. Please include lots of details - being very specific helps us help you faster!'></textarea>
<button class='button col12 space-top0'>Send</button>
</script>
<script type='template' id='typo'>
<label>What's the URL of the page where you saw an issue?</label>
<input type='url' id='website-url' class='col12 clean round' />
<textarea class='col12 clean round space-top0' placeholder='Describe the issue you found.'></textarea>
<button class='button col12 space-top0'>Send</button>
<div class='small quiet'>We might send a thank you, but don't always respond
to small typo or error reports. Thanks for helping us improve!</div>
</script>
<script type='template' id='geocoder-feedback'>
<a class='button col12' href='https://www.mapbox.com/geocoder-feedback/'>Use our Geocoder Feedback interface to report an issue.</a>
</script>
<script type='template' id='map-feedback'>
<a class='button col12' href='https://www.mapbox.com/map-feedback/'>Use our Map Feedback interface to report an issue.</a>
</script>
<script type='template' id='attribution'>
<label>What's the URL of a page that's missing attribution?</label>
<input type='url' id='website-url' class='col12 clean round' />
<button class='button col12 space-top0'>Send</button>
<div class='small quiet'>
If the attribution is with a mobile app
or something else, please add a link to the App Store or Play Store
page for that app, or another reference.
We might respond to you if we need more
information.</div>
</script>
</body>
<script type='text/javascript' src='contact.js'></script>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment