public
Last active

Submit data from html form to Google Doc Spreadsheet. Uses Bootstrap components for auto-complete region list and date selection.

  • Download Gist
form.js
JavaScript
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
$(function(){
 
var formUrl = '/* ex: https://docs.google.com/a/developmentseed.org/spreadsheet/formResponse?formkey=... */';
 
// Set up map
var m = mapbox.map('map').addLayer(mapbox.layer().id(' /* mapbox-account.id */ '));
 
// Set up map ui features with point selector
var ui = mapbox.ui().map(m).auto().pointselector(function(d) {
// Remove all points except the most recent
for (var i = 0; i < d.length - 1; i++) {
var locs = ui['_pointselector'].locations();
ui['_pointselector'].deleteLocation(locs[i]);
}
saveLatLon(d[0]);
});
 
// Get region data from google spreadsheet and set up LGA typeahead
mapbox.converters.googledocs('/* spreadsheet key */', '/* sheet number */', typeAhead);
 
// Set up date pickers
// Uses http://www.eyecon.ro/bootstrap-datepicker
var now = new Date();
now = now.getMonth() + '/' + now.getDate() + '/' + now.getFullYear();
$('/* Selectors for date fields */').val(now).datepicker();
 
// Handle form submission
$('form').submit(function(e) {
var button = $('input[type=submit]', this),
data = $(this).serialize();
 
e.preventDefault();
if (validate($(this))) {
button.button('loading');
$.ajax({
type: 'POST',
url: formUrl,
data: data,
complete: function() {
button.button('reset');
// After submission, redirect to main page
window.location = 'index.html#new';
}
});
}
 
// All fields are required
function validate(form) {
$('.control-group').removeClass('error');
$('input, textarea', form).each(function() {
var tag = $(this)[0].tagName.toLowerCase(),
type = $(this).attr('type');
 
// Validate radio buttons
if (tag === 'input' && type === 'radio') {
var name = $(this).attr('name');
if ($('[name="' + name + '"]:checked').length < 1) {
$(this).parent().parent().parent().addClass('error');
}
}
 
// Validate text fields
if ((tag === 'input' && type === 'text') || tag === 'textarea') {
if ($(this).val() === '' && !$(this).parent().hasClass('radio')) {
$(this).parent().parent().addClass('error');
}
}
});
 
if ($('.control-group.error').length < 1) return true;
$('.control-group.error').length
$('html, body').animate({
scrollTop: $('.control-group.error').offset().top - 20
}, 500);
 
return false;
}
});
 
// Use typeahead to select region
// Uses http://twitter.github.com/bootstrap/javascript.html#typeahead
function typeAhead(features) {
var lgas = [];
 
// Pluck `region, state` values
for (var i = 0; i < features.length; i++) {
lgas.push(features[i].properties.lgastate);
}
 
$('/* Element for typeahead */').typeahead({source: lgas}).change(function() {
var position = $.inArray($(this).val(), lgas);
if (position >= 0) {
var coords = features[position].geometry.coordinates,
loc = { lon: coords[0], lat: coords[1] };
 
saveLatLon(loc);
m.center(loc).zoom(7);
$('#map-control').show();
}
});
}
 
function saveLatLon(loc) {
$('#entry_1').val(loc.lon);
$('#entry_2').val(loc.lat);
}
});

Form markup should match id and name with a standard Google Doc form, and there should be no validation on the Google Doc form, so submissions will not be filtered. ex:

<input type="text" class="input-xlarge" id="entry_0" name="entry.0.single">

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.