Skip to content

Instantly share code, notes, and snippets.

@tmcw
Created August 4, 2016 18:33
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/f7e7c3a4e710a43291f884c4d613a577 to your computer and use it in GitHub Desktop.
Save tmcw/f7e7c3a4e710a43291f884c4d613a577 to your computer and use it in GitHub Desktop.
var state = {
choices: []
};
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 --'),
f('With Mapbox software'),
f('An error in our maps'),
f('A typo or content issue on our website or blog')
]),
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 --'),
f('Studio'),
f('iOS SDK'),
f('Android SDK'),
f('REST APIs'),
f('Other')
]),
q('Report missing 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');
var title = container.appendChild(document.createElement('h3'));
title.innerText = question.title;
var description = container.appendChild(document.createElement('textarea'));
var submit = container.appendChild(document.createElement('button'));
submit.innerText = 'Send';
return container;
}
function generateQuestion(depth, question, value) {
var container = document.createElement('div');
var title = container.appendChild(document.createElement('h3'));
title.innerText = question.title;
var select = container.appendChild(document.createElement('select'));
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.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>
</head>
<body>
<div class='limiter fill-darken0'>
<div class='pad4' id='app'>
</div>
</div>
</body>
<script src='contact.js'></script>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment