├── js
├── search.js
├── html5shiv.min.js
└── map.js
├── README.md
├── css
├── reset.css
└── style.css
└── index.html
/js/search.js:
--------------------------------------------------------------------------------
1 | $(function() {
2 | $( "#searchZip" ).click(function() {
3 | $("#searchZip").hide();
4 | $( ".zipSearch" ).show();
5 | });
6 | });
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | SeedTip
2 | =======
3 |
4 | Find your local farmers markets (U.S. only)
5 |
6 | I threw this together to learn the Google Map API. The script will pull data from the USDA API and use
7 | the Google Maps API to display the closest locations.
8 |
9 | A basic, responsive front end is included.
10 |
11 | See a live working sample at www.seedtip.com
12 |
13 | View the 4 part tutorial on YouTube
14 | Part 1 - https://www.youtube.com/watch?v=lVhDux1vmIU
15 | Part 2 - https://www.youtube.com/watch?v=ygNn7P-Fas4
16 | Part 3 - https://www.youtube.com/watch?v=vImMDfaqA2A
17 | Part 4 - https://www.youtube.com/watch?v=Hv76o8PEKwk
18 |
--------------------------------------------------------------------------------
/css/reset.css:
--------------------------------------------------------------------------------
1 | /**
2 | * Eric Meyer's Reset CSS v2.0 (http://meyerweb.com/eric/tools/css/reset/)
3 | * http://cssreset.com
4 | */
5 | html, body, div, span, applet, object, iframe,
6 | h1, h2, h3, h4, h5, h6, p, blockquote, pre,
7 | a, abbr, acronym, address, big, cite, code,
8 | del, dfn, em, img, ins, kbd, q, s, samp,
9 | small, strike, strong, sub, sup, tt, var,
10 | b, u, center,
11 | dl, dt, dd, ol, ul, li,
12 | fieldset, form, label, legend,
13 | table, caption, tbody, tfoot, thead, tr, th, td,
14 | article, aside, canvas, details, embed,
15 | figure, figcaption, footer, header, hgroup,
16 | menu, nav, output, ruby, section, summary,
17 | time, mark, audio, video {
18 | margin: 0;
19 | padding: 0;
20 | border: 0;
21 | font-size: 100%;
22 | font: inherit;
23 | vertical-align: baseline;
24 | }
25 | /* HTML5 display-role reset for older browsers */
26 | article, aside, details, figcaption, figure,
27 | footer, header, hgroup, menu, nav, section {
28 | display: block;
29 | }
30 | body {
31 | line-height: 1;
32 | }
33 | ol, ul {
34 | list-style: none;
35 | }
36 | blockquote, q {
37 | quotes: none;
38 | }
39 | blockquote:before, blockquote:after,
40 | q:before, q:after {
41 | content: '';
42 | content: none;
43 | }
44 | table {
45 | border-collapse: collapse;
46 | border-spacing: 0;
47 | }
--------------------------------------------------------------------------------
/js/html5shiv.min.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @preserve HTML5 Shiv 3.7.2 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed
3 | */
4 | !function(a,b){function c(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x",d.insertBefore(c.lastChild,d.firstChild)}function d(){var a=t.elements;return"string"==typeof a?a.split(" "):a}function e(a,b){var c=t.elements;"string"!=typeof c&&(c=c.join(" ")),"string"!=typeof a&&(a=a.join(" ")),t.elements=c+" "+a,j(b)}function f(a){var b=s[a[q]];return b||(b={},r++,a[q]=r,s[r]=b),b}function g(a,c,d){if(c||(c=b),l)return c.createElement(a);d||(d=f(c));var e;return e=d.cache[a]?d.cache[a].cloneNode():p.test(a)?(d.cache[a]=d.createElem(a)).cloneNode():d.createElem(a),!e.canHaveChildren||o.test(a)||e.tagUrn?e:d.frag.appendChild(e)}function h(a,c){if(a||(a=b),l)return a.createDocumentFragment();c=c||f(a);for(var e=c.frag.cloneNode(),g=0,h=d(),i=h.length;i>g;g++)e.createElement(h[g]);return e}function i(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return t.shivMethods?g(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+d().join().replace(/[\w\-:]+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(t,b.frag)}function j(a){a||(a=b);var d=f(a);return!t.shivCSS||k||d.hasCSS||(d.hasCSS=!!c(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),l||i(a,d),a}var k,l,m="3.7.2",n=a.html5||{},o=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,p=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,q="_html5shiv",r=0,s={};!function(){try{var a=b.createElement("a");a.innerHTML="",k="hidden"in a,l=1==a.childNodes.length||function(){b.createElement("a");var a=b.createDocumentFragment();return"undefined"==typeof a.cloneNode||"undefined"==typeof a.createDocumentFragment||"undefined"==typeof a.createElement}()}catch(c){k=!0,l=!0}}();var t={elements:n.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:m,shivCSS:n.shivCSS!==!1,supportsUnknownElements:l,shivMethods:n.shivMethods!==!1,type:"default",shivDocument:j,createElement:g,createDocumentFragment:h,addElements:e};a.html5=t,j(b)}(this,document);
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Find Local Farmers Markets
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
Find Local Farmers Markets
31 |
We'll help you locate your closest farmers markets. Simply choose an option below to begin...
32 |
42 |
43 |
If you've found SeedTip helpful, please help spread the word!
44 |
45 |
46 |
47 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
A project by Paul Dessert.
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
--------------------------------------------------------------------------------
/css/style.css:
--------------------------------------------------------------------------------
1 |
2 | /* Global styles */
3 | html, body {
4 | height: 100%;
5 | margin: 0px;
6 | padding: 0px
7 | }
8 |
9 |
10 | body {
11 | font-family: "Open Sans", sans-serif;
12 | /* font-family: 'Libre Baskerville', serif; */
13 | color: #686868;
14 | font-size: 15px;
15 | background-color: #6B7283;
16 | }
17 |
18 |
19 | .clearfix:after {
20 | content: " ";
21 | display: block;
22 | height: 0;
23 | clear: both;
24 | }
25 |
26 | .clear{
27 | clear: both;
28 | }
29 |
30 | a {
31 | text-decoration: none;
32 | color: #79accd;
33 | }
34 |
35 | a:hover {
36 | color: #79accd;
37 | text-decoration: underline;
38 | }
39 |
40 | h1, h2, h3, h4, h5, h6 {
41 | margin-bottom: 17px;
42 | font-weight: 300;
43 | /* color: #ff5400; */
44 | }
45 |
46 | h1 {
47 | font-size: 28px;
48 | }
49 |
50 | h2 {
51 | font-size: 26px;
52 | }
53 |
54 | h3 {
55 | font-size: 24px;
56 | margin-bottom: 15px;
57 | }
58 |
59 | ul{
60 | list-style-type: square;
61 | margin-left: 60px;
62 | margin-bottom: 30px;
63 | }
64 |
65 | ul li{
66 | line-height: 1.9;
67 | }
68 |
69 |
70 | .zipSearch{
71 | display: none;
72 | }
73 |
74 | /* Popup */
75 | .markerPop{
76 |
77 | }
78 |
79 |
80 | .twitter{
81 | float: left;
82 | }
83 |
84 | .facebook{
85 | float: left;
86 | width: 150px !important;
87 | height: 35px !important;
88 | }
89 |
90 | /* tablets and desktop */
91 | @media only screen and (min-width: 361px) {
92 |
93 | p {
94 | margin-bottom: 15px;
95 | line-height: 20px;
96 | }
97 |
98 | #map-canvas{
99 | height: 100%;
100 | }
101 | #control{
102 | float: left;
103 | color: #D8D8DD;
104 | width: 15%;
105 | padding: 50px 30px 10px 30px;
106 | border-right: 1px solid black;
107 | }
108 |
109 | #control input[type=text]{
110 | width: 100%;
111 | height: 40px;
112 | font-size: 24px;
113 | background-color: #6B7283;
114 | border: 1px solid #BE757E;
115 | }
116 |
117 | .learnButton {
118 | margin-top: 10px;
119 | margin-bottom: 20px;
120 | background: #BE757E;
121 | border: 0;
122 | color: #D8D8DD;
123 | height: 37px;
124 | line-height: 37px;
125 | width: 100%;
126 | text-align: center;
127 | cursor: pointer;
128 | }
129 |
130 | #mc_embed_signup{
131 | margin-top: 30px;
132 | float: left;
133 | width: 300px;
134 | }
135 |
136 | #mc_embed_signup form label{
137 | margin-bottom: 30px;
138 | line-height: 20px;
139 | clear: right;
140 | }
141 |
142 | #mc_embed_signup form input.email{
143 | width: 100%;
144 | height: 40px;
145 | font-size: 24px;
146 | background-color: #6B7283;
147 | border: 1px solid #BE757E;
148 | }
149 | }
150 |
151 | /* phones */
152 | @media only screen and (max-width: 360px) {
153 |
154 | p {
155 | margin-bottom: 10px;
156 | line-height: 26px;
157 | }
158 |
159 | #map-canvas{
160 | height: 100%;
161 | }
162 |
163 | #control{
164 | color: #D8D8DD;
165 | padding: 20px 30px 10px 30px;
166 | }
167 |
168 | #control input[type=text]{
169 | width: 100%;
170 | height: 40px;
171 | font-size: 24px;
172 | background-color: #6B7283;
173 | border: 1px solid #BE757E;
174 | }
175 |
176 | .learnButton {
177 | float: left;
178 | margin: 0px 10px 0px 10px;
179 | margin-top: 20px;
180 | margin-bottom: 20px;
181 | background: #BE757E;
182 | border: 0;
183 | color: #D8D8DD;
184 | height: 37px;
185 | line-height: 37px;
186 | width: 40%;
187 | text-align: center;
188 | }
189 |
190 | #mc_embed_signup{
191 | display: none;
192 | }
193 |
194 | #mc_embed_signup form label{
195 | margin-bottom: 30px;
196 | line-height: 20px;
197 | clear: right;
198 | }
199 |
200 | #mc_embed_signup form input.email{
201 | width: 100%;
202 | height: 40px;
203 | font-size: 24px;
204 | background-color: #6B7283;
205 | border: 1px solid #BE757E;
206 | }
207 | }
208 |
209 |
210 |
--------------------------------------------------------------------------------
/js/map.js:
--------------------------------------------------------------------------------
1 | /* Pull local Farers market data from the USDA API and display on
2 | ** Google Maps using GeoLocation or user input zip code. By Paul Dessert
3 | ** www.pauldessert.com | www.seedtip.com
4 | */
5 |
6 | $(function() {
7 |
8 | var marketId = []; //returned from the API
9 | var allLatlng = []; //returned from the API
10 | var allMarkers = []; //returned from the API
11 | var marketName = []; //returned from the API
12 | var infowindow = null;
13 | var pos;
14 | var userCords;
15 | var tempMarkerHolder = [];
16 |
17 | //Start geolocation
18 |
19 | if (navigator.geolocation) {
20 |
21 | function error(err) {
22 | console.warn('ERROR(' + err.code + '): ' + err.message);
23 | }
24 |
25 | function success(pos){
26 | userCords = pos.coords;
27 |
28 | //return userCords;
29 | }
30 |
31 | // Get the user's current position
32 | navigator.geolocation.getCurrentPosition(success, error);
33 | //console.log(pos.latitude + " " + pos.longitude);
34 | } else {
35 | alert('Geolocation is not supported in your browser');
36 | }
37 |
38 | //End Geo location
39 |
40 | //map options
41 | var mapOptions = {
42 | zoom: 5,
43 | center: new google.maps.LatLng(37.09024, -100.712891),
44 | panControl: false,
45 | panControlOptions: {
46 | position: google.maps.ControlPosition.BOTTOM_LEFT
47 | },
48 | zoomControl: true,
49 | zoomControlOptions: {
50 | style: google.maps.ZoomControlStyle.LARGE,
51 | position: google.maps.ControlPosition.RIGHT_CENTER
52 | },
53 | scaleControl: false
54 |
55 | };
56 |
57 | //Adding infowindow option
58 | infowindow = new google.maps.InfoWindow({
59 | content: "holding..."
60 | });
61 |
62 | //Fire up Google maps and place inside the map-canvas div
63 | map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
64 |
65 | //grab form data
66 | $('#chooseZip').submit(function() { // bind function to submit event of form
67 |
68 | //define and set variables
69 | var userZip = $("#textZip").val();
70 | //console.log("This-> " + userCords.latitude);
71 |
72 | var accessURL;
73 |
74 | if(userZip){
75 | accessURL = "http://search.ams.usda.gov/farmersmarkets/v1/data.svc/zipSearch?zip=" + userZip;
76 | } else {
77 | accessURL = "http://search.ams.usda.gov/farmersmarkets/v1/data.svc/locSearch?lat=" + userCords.latitude + "&lng=" + userCords.longitude;
78 | }
79 |
80 |
81 | //Use the zip code and return all market ids in area.
82 | $.ajax({
83 | type: "GET",
84 | contentType: "application/json; charset=utf-8",
85 | url: accessURL,
86 | dataType: 'jsonp',
87 | success: function (data) {
88 |
89 | $.each(data.results, function (i, val) {
90 | marketId.push(val.id);
91 | marketName.push(val.marketname);
92 | });
93 |
94 | //console.log(marketName);
95 |
96 | var counter = 0;
97 | //Now, use the id to get detailed info
98 | $.each(marketId, function (k, v){
99 | $.ajax({
100 | type: "GET",
101 | contentType: "application/json; charset=utf-8",
102 | // submit a get request to the restful service mktDetail.
103 | url: "http://search.ams.usda.gov/farmersmarkets/v1/data.svc/mktDetail?id=" + v,
104 | dataType: 'jsonp',
105 | success: function (data) {
106 |
107 | for (var key in data) {
108 |
109 | var results = data[key];
110 |
111 | //console.log(results);
112 |
113 | //The API returns a link to Google maps containing lat and long. This pulls it apart.
114 | var googleLink = results['GoogleLink'];
115 | var latLong = decodeURIComponent(googleLink.substring(googleLink.indexOf("=")+1, googleLink.lastIndexOf("(")));
116 |
117 | var split = latLong.split(',');
118 |
119 | //covert values to floats, to play nice with .LatLng() below.
120 | var latitude = parseFloat(split[0]);
121 | var longitude = parseFloat(split[1]);
122 |
123 | //set the markers.
124 | myLatlng = new google.maps.LatLng(latitude,longitude);
125 |
126 | allMarkers = new google.maps.Marker({
127 | position: myLatlng,
128 | map: map,
129 | title: marketName[counter],
130 | html:
131 | '' +
132 | '
' + marketName[counter].substring(4) + '
' + //substring removes distance from title
133 | '
' + results['Address'] + '
' +
134 | '
' + results['Products'].split(';') + '
' +
135 | '
' + results['Schedule'] + '
' +
136 | '
'
137 | });
138 |
139 | //put all lat long in array
140 | allLatlng.push(myLatlng);
141 |
142 | //Put the marketrs in an array
143 | tempMarkerHolder.push(allMarkers);
144 |
145 | counter++;
146 | //console.log(counter);
147 | };
148 |
149 | google.maps.event.addListener(allMarkers, 'click', function () {
150 | infowindow.setContent(this.html);
151 | infowindow.open(map, this);
152 | });
153 |
154 |
155 | //console.log(allLatlng);
156 | // Make an array of the LatLng's of the markers you want to show
157 | // Create a new viewpoint bound
158 | var bounds = new google.maps.LatLngBounds ();
159 | // Go through each...
160 | for (var i = 0, LtLgLen = allLatlng.length; i < LtLgLen; i++) {
161 | // And increase the bounds to take this point
162 | bounds.extend (allLatlng[i]);
163 | }
164 | // Fit these bounds to the map
165 | map.fitBounds (bounds);
166 |
167 |
168 | }
169 | });
170 | }); //end .each
171 | }
172 | });
173 |
174 | return false; // important: prevent the form from submitting
175 | });
176 | });
177 |
178 |
--------------------------------------------------------------------------------