{"id":15549599,"url":"https://github.com/mrlynn/30-min-data-web-form","last_synced_at":"2026-04-15T16:06:05.193Z","repository":{"id":137876255,"uuid":"247764880","full_name":"mrlynn/30-min-data-web-form","owner":"mrlynn","description":"30 Minutes to a Data Enabled Web Form with MongoDB","archived":false,"fork":false,"pushed_at":"2020-10-28T10:55:33.000Z","size":45,"stargazers_count":3,"open_issues_count":1,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-02-03T11:30:56.317Z","etag":null,"topics":["beginner","data","html","html-form","javascript","mongodb","mongodb-atlas","mongodb-database","web","webforms"],"latest_commit_sha":null,"homepage":null,"language":"HTML","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mrlynn.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-03-16T16:31:37.000Z","updated_at":"2024-01-28T08:15:57.000Z","dependencies_parsed_at":null,"dependency_job_id":"3e70c0d1-f831-406c-945f-11798b68f47d","html_url":"https://github.com/mrlynn/30-min-data-web-form","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mrlynn%2F30-min-data-web-form","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mrlynn%2F30-min-data-web-form/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mrlynn%2F30-min-data-web-form/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mrlynn%2F30-min-data-web-form/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mrlynn","download_url":"https://codeload.github.com/mrlynn/30-min-data-web-form/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246124524,"owners_count":20727266,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["beginner","data","html","html-form","javascript","mongodb","mongodb-atlas","mongodb-database","web","webforms"],"created_at":"2024-10-02T13:40:57.501Z","updated_at":"2026-04-15T16:06:04.483Z","avatar_url":"https://github.com/mrlynn.png","language":"HTML","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 30 Minutes to a Data-Enabled Web Form with MongoDB\n\nPosting a form, capturing data and storing that in a database is a requirement as old as the web itself. Let’s take 30 minutes and build a short, but sweet solution using the MongoDB Platform. We’ll be creating a basic web form using HTML, a bit of JavaScript and storing the data in a MongoDB database. We’ll need a few things before we get moving so take a few minutes and make sure you’ve got the following items in place.\n\n\n## MongoDB Atlas\n\nTo get started, you’ll need to have a MongoDB Atlas account - check out this article on [getting started with MongoDB Atlas](https://docs.atlas.mongodb.com/getting-started/) for some quick information to get you up and running. If you haven’t done this, [register for an account on MongoDB Atlas](https://docs.atlas.mongodb.com/tutorial/create-atlas-account/) and then deploy a free tier instance. Follow these linked guides.\n\n## Basic HTML\n\nYou will also need a basic understanding of HTML, more specifically, forms. Thankfully, this is readily available [at many places on the web](https://www.w3schools.com/html/html_forms.asp). We’ll be using some very basic tags such as `\u003cform\u003e`, `\u003cinput\u003e`, `\u003cselect\u003e` to capture input in a form.\n\n## JavaScript\n\nFor this brief tutorial, if you can copy/paste JavaScript and tweak a few lines, you should be good to go. But you will want to understand some basics of how JavaScript works. For that, you can head over to [W3Schools](https://www.w3schools.com/js/) for a basic introduction. The key thing here to understand is that JavaScript runs in the browser. We’re going to put some pre-written code that leverages the MongoDB SDK into an HTML file.\n\n## Code Editor\n\nI use [Visual Studio Code](https://code.visualstudio.com/), but you can use just about any editor as long as you can edit and save your code files.\n\n## Outline\n\nHere’s an outline of what we’re going to accomplish:\n\n1. Launch a MongoDB Atlas Cluster.\n   1. [Add a database user](https://docs.atlas.mongodb.com/security-add-mongodb-users/#add-database-users)\n   2. [Add a whitelist](https://docs.atlas.mongodb.com/security-whitelist/)\n   3. [Add a Stitch App](https://docs.mongodb.com/stitch/procedures/create-stitch-app/)\n   4. [Add an Anonymous User Provider](https://docs.mongodb.com/stitch/authentication/anonymous/)\n   5. [Add a Database Rule to allow access to your database for your Stitch App](https://docs.mongodb.com/stitch/mongodb/define-roles-and-permissions/#procedure)\n2. Build an HTML Form with some basic input fields.\n3. Send the contents of those input fields to MongoDB\n4. **BONUS**: Display a chart with the value of those fields.\n\nIf you’ve followed the above Atlas Getting Started Guide, you should have a free tier cluster launched. Be sure you follow the guidelines to add a whitelist entry, and create a database user. You’ll need these things to connect to your MongoDB Database.\n\n## Putting it all together\n\nWe're going to be building a web page with HTML tags - the following is a shell, or a template if you like of the html page without the actual content. This will give you a good idea about the various sections we're going to be building in the page.\n\n```\n\u003c!DOCTYPE html\u003e\n\u003chtml lang=\"en\"\u003e\n  \u003chead\u003e\n    \u003c!-- Meta Stuff\n    --\u003e\n\n    \u003c!-- Head links\n    --\u003e\n  \u003c/head\u003e\n\n  \u003cbody\u003e\n    \u003c!-- Navigation --\u003e\n\n    \u003c!-- Form --\u003e\n\n    \u003c!-- Footer --\u003e\n\n    \u003c!-- Bootstrap core JavaScript --\u003e\n  \u003c/body\u003e\n\u003c/html\u003e\n```\n\n### HEAD SECTION\n\nThe HEAD section is where we configure some basic information about the page such as the description, and title and we link to some additional libraries that will help us style the page and pull in some additional JavaScript frameworks. We're going to use jQuery helpers in our project. JQuery is a framework that simplifies manipulation of HTML document elements. In this project, we're going to use it specifically to simplify grabbing the elements that users put into the fields in our form so that we can use the MongoDB Stitch SDK to insert that data into the database.\n\n```\n    \u003c!-- Some basic META information - helps with SEO --\u003e\n    \u003cmeta name=\"author\" content=\"Michael Lynn\" /\u003e\n    \u003ctitle\u003e30 Minutes to a Data Enabled Webform\u003c/title\u003e\n\n    \u003c!-- Bootstrap core CSS --\u003e\n    \u003clink href=\"https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css\" rel=\"stylesheet\" /\u003e\n\n    \u003c!-- Custom styles for this template --\u003e\n    \u003clink href=\"styles.css\" rel=\"stylesheet\" /\u003e \u003c!-- optional additional css styles if'n y'like --\u003e\n    \u003cscript src=\"https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js\"\u003e\u003c/script\u003e\n\n    \u003c!-- \u003cscript src=\"https://s3.amazonaws.com/stitch-sdks/js/bundles/4.4.0/stitch.js\"\u003e\u003c/script\u003e --\u003e\n    \u003cscript src=\"https://s3.amazonaws.com/stitch-sdks/js/bundles/4.9.0/stitch.js\"\u003e\u003c/script\u003e\n\n    \u003c!-- Our configuration JavaScript - with reference to our Stich App ID --\u003e\n    \u003cscript src=\"./config.js\"\u003e\u003c/script\u003e\n```\n\n### BODY SECTION\n\nThis section is where we leverage the HTML form tags to prompt our user for the data we'll store in MongoDB. I'm using Bootstrap to make things look pretty - but you really only need the HTML tags.\n\n```\n    \u003csection class=\"bg-light\"\u003e\n      \u003cdiv class=\"container\"\u003e\n        \u003ch2 class=\"mb-5 jumbotron text-center\"\u003e30 Minutes to a Data Enabled Web Form\u003c/h2\u003e\n        \u003cdiv class=\"col-md-12 mx-auto\"\u003e\n          \u003cform\u003e\n            \u003cdiv class=\"form-group\"\u003e\n              \u003cdiv class=\"form-row\"\u003e\n                \u003clabel for=\"name\"\u003eName:\u003c/label\u003e\n                \u003cinput\n                  type=\"text\"\n                  placeholder=\"Your Full Name\"\n                  name=\"name\"\n                  id=\"name\"\n                  class=\"form-control\"\n                /\u003e\n              \u003c/div\u003e\n                \u003cdiv class=\"row\"\u003e\n                  \u003cdiv class=\"col-md-4 form-group\"\u003e\n                      \u003clabel for=\"lat\"\u003eMy Location - Latitude\u003c/label\u003e\n                      \u003cinput type=\"text\" id=\"lat\" name=\"lat\" value=\"\" class=\"form-control\" disabled\u003e\n                  \u003c/div\u003e\n                  \u003cdiv class=\"col-md-4\"\u003e\n                      \u003clabel for=\"lon\"\u003eMy Location - Longitude\u003c/label\u003e\n                      \u003cinput type=\"text\" id=\"lon\" name=\"lon\" value=\"\" class=\"form-control\" disabled\u003e\n                  \u003c/div\u003e\n                  \u003cdiv class=\"col-md-4 text-middle\"\u003e\n                      \u003cinput type=\"geolocation\" type=\"hidden\" id=\"geolocation\" name=\"geolocation\" hidden\u003e\u003cbr\u003e\n                      \u003cbutton type=\"button\" class=\"btn btn-lg btn-primary\" onclick=\"showPosition();\"\u003eShare Location\u003c/button\u003e\n                  \u003c/div\u003e\n              \u003c/div\u003e\n                \u003cdiv class=\"form-row\"\u003e\n                        \u003clabel for=\"exp\"\u003eMy experience with MongoDB:\u003c/label\u003e\n                        \u003cdiv class=\"col-lg-12 col-md-12\"\u003e\n                            \u003cselect name=\"exp\" id=\"select_exp\" class=\"form-control\"\u003e\n                                \u003coption value=\"Brand new to MongoDB\"\u003eBrand new to MongoDB\u003c/option\u003e\n                                \u003coption value=\"Played with it\"\u003ePlayed with it\u003c/option\u003e\n                                \u003coption value=\"Used in the past\"\u003eUsed in the past\u003c/option\u003e\n                                \u003coption value=\"Company Uses\"\u003eMy company uses it\u003c/option\u003e\n                                \u003coption value=\"Advanced\"\u003eAdvanced MongoDB User\u003c/option\u003e\n                            \u003c/select\u003e\n                        \u003c/div\u003e\n                    \u003c/div\u003e\n                \u003cdiv class=\"form-row\"\u003e\n                    \u003clabel for=\"role\"\u003eI am a:\u003c/label\u003e\n                    \u003cdiv class=\"col-lg-12 col-md-12\"\u003e\n                        \u003cselect name=\"role\" id=\"role\" class=\"form-control\"\u003e\n                            \u003coption value=\"Student\"\u003eStudent\u003c/option\u003e\n                            \u003coption value=\"Gamer\"\u003eGamer\u003c/option\u003e\n                            \u003coption value=\"Developer\"\u003eDeveloper/Engineer\u003c/option\u003e\n                            \u003coption value=\"DevRel\"\u003eDeveloper Advocate/Relations\u003c/option\u003e\n                            \u003coption value=\"DevOps\"\u003eDevOps/SRE\u003c/option\u003e\n                            \u003coption value=\"Data Scientist/Analyst\"\u003eData Analyst/Scientist\u003c/option\u003e\n                            \u003coption value=\"None/Other\"\u003eOther\u003c/option\u003e\n                        \u003c/select\u003e\n                    \u003c/div\u003e\n                \u003c/div\u003e\n            \u003cdiv class=\"form-row\"\u003e\n              \u003cdiv class=\"col-12 col-md-3\"\u003e\u003cp\u003e\u003c/p\u003e\n                \u003cbutton class=\"btn btn-block btn-lg btn-primary\"\n                    onclick=\"sendResponse();return false;\"\n                    class=\"btn btn-lg btn-success\"\n                    \u003e\n                  Send Response\n                \u003c/button\u003e\n              \u003c/div\u003e\n            \u003c/div\u003e\n          \u003c/form\u003e\n        \u003c/div\u003e\n      \u003c/div\u003e\n    \u003c/section\u003e\n```\n\n### POST BODY SCRIPT SECTION\n\nWe'll place our JavaScript elements after the body of our HTML page. This ensures that the entire page loads prior to any of the script elements. In this section, notice we have several functions.\n\n- sendResponse() - No parameters. This invokes a method on our Stitch SDK Client to authenticate with the anonymous credential provider. Then, it calls another function called insertData();\n- insertData() - No parameters. This function uses jQuery to obtain the values of the fields in the html form, builds a JSON document and uses the Stitch SDK to send those to the database.\n- recordSuccess() - No parameters. This function simply redirects the browser to a new page - where we'll display the data we collected.\n\n```\n\u003c!-- Bootstrap core JavaScript --\u003e\n\u003cscript src=\"https://code.jquery.com/jquery-3.4.1.min.js\"\nintegrity=\"sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=\"\ncrossorigin=\"anonymous\"\u003e\u003c/script\u003e\n\u003cscript src=\"https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.bundle.min.js\"\u003e\u003c/script\u003e\n\n\u003cscript\u003e\n    const { Stitch, AnonymousCredential } = stitch;\n\n    function sendResponse() {\n        client.auth\n            .loginWithCredential(new stitch.AnonymousCredential())\n            .then(() =\u003e insertData())\n            .catch(err =\u003e console.error(`login failed with error: ${err}`));\n    }\n\n    function insertData() {\n        var n = new Date();\n        var obj = {};\n        obj.mdb_created = n;\n\n        obj.name = $(\"#name\").val();\n        obj.role = $(\"#role\").val();\n        obj.exp = $(\"#exp\").val();\n\n        if ($(\"#lat\").val().length \u003e 0) {\n            var lat = $(\"#lat\").val();\n            var lon = $(\"#lon\").val();\n            lat = parseFloat(lat).toFixed(2);\n            lon = parseFloat(lon).toFixed(2);\n            var location = {};\n            location.type = \"Point\";\n            location.coordinates = new Array(1,2);\n            location.coordinates[0] = parseFloat(lon);\n            location.coordinates[1] = parseFloat(lat);\n\n            obj.location = location;\n            console.log(obj);\n        }\n        obj.browser = {};\n        obj.browser.ua = navigator.userAgent || undefined;\n        obj.browser.lang = navigator.language || undefined;\n        obj.browser.plat = navigator.platform || undefined;\n        obj.owner = client.auth.authInfo.userId;\n\n        db.collection(\"responses\")\n            .insertOne(obj)\n            .then(recordSuccess)\n            .catch(err =\u003e console.error(`login failed with error: ${err}`));\n    }\n\n    function recordSuccess() {\n        window.location = \"thankyou.html\";\n    }\n\n    function showPosition() {\n        if (navigator.geolocation) {\n            navigator.geolocation.getCurrentPosition(function(position) {\n            var lat = position.coords.latitude;\n            var lon = position.coords.longitude;\n            document.getElementById(\"lat\").value = lat;\n            document.getElementById(\"lon\").value = lon;\n            });\n        } else {\n            alert(\"Sorry, your browser does not support HTML5 geolocation.\");\n        }\n    }\n\n\u003c/script\u003e\n```\n\n## The Magic\n\nNotice the button in the HTML form has a tag called `onClick`. This tag is configured with the name of a JavaScript function that is called when the user clicks the button on the HTML form. This is how we're calling the JavaScript function sendResponse() which in turn calls the function insertData() which sends the data to MongoDB. The Stitch SDK is configured with a reference to the Stitch App ID, which is configured with rules to enable an anonymous user to insert data into the database.\n\nOnce the data is inserted into the database, the JavaScript function insertData() completes and if it was successful, it calls recordSuccess() and sends the browser to the location `thankyou.html`.\n\n## Displaying Data\n\nIn our `thankyou.html` page, we're doing some interesting things with charts.\n\nIn the body of this page, we have a div.\n\n```\n\u003csection class=\"features-icons bg-light text-center\"\u003e\n    \u003cdiv class=\"container\"\u003e\n        \u003cdiv class=\"jumbotron\"\u003e\n        \u003ch2\u003eThanks for contributing!\u003c/h2\u003e\n        \u003cp\u003e\n            Here's what the responses look like...\n        \u003c/p\u003e\n        \u003c/div\u003e\n        \u003cdiv id=\"charts\"\u003e\u003c/div\u003e\n    \u003c/div\u003e\n\u003c/section\u003e\n```\n\nNotice the div with the id `charts`. We're going to reference that in the next stage.\n\n## Scripts\n\nWe're first pulling in jquery which will make the job much more efficient. Next, we're creating an array of Chart URI's - these are the URIs for each chart we want to display on the page. We then take the array of URIs and we append those to the div labeled charts from above. This effectively, embeds or inserts the charts into that section of the page.\n\n```\n\u003cscript\n    src=\"https://code.jquery.com/jquery-3.4.1.min.js\"\n    integrity=\"sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=\"\n    crossorigin=\"anonymous\"\u003e\u003c/script\u003e\n    \u003cscript src=\"https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.bundle.min.js\"\u003e\u003c/script\u003e\n\n\u003cscript\u003e\n    const CHARTSURIS = [\n    \"https://charts.mongodb.com/charts-lynn-qercf/embed/charts?id=ff115d78-429a-4857-a284-279e84447ba5\u0026theme=light\",\n    \"https://charts.mongodb.com/charts-lynn-qercf/embed/charts?id=48d13c56-cc25-475d-8112-eb2ac080c889\u0026theme=light\",\n    \"https://charts.mongodb.com/charts-lynn-qercf/embed/charts?id=5589b35a-7a08-438e-9dc8-623a36304e3d\u0026theme=light\"\n    ];\n\n    $(function() {\n        $.each(CHARTSURIS, function(index, uri) {\n            $(\"#charts\").append(\n            '\u003ciframe style=\"border: none;border-radius: 2px;box-shadow: 0 2px 10px 0 rgba(70, 76, 79, .2);margin-top:20px;\" width=\"100%\" height=\"480\" src=\"' +\n                uri +\n                '\"\u003e\u003c/iframe\u003e'\n            );\n        });\n    });\n    function toSignup() {\n        window.location = \"signup.html\";\n    }\n\u003c/script\u003e\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmrlynn%2F30-min-data-web-form","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmrlynn%2F30-min-data-web-form","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmrlynn%2F30-min-data-web-form/lists"}