diff --git a/README.md b/README.md index 2c6e21e2..b0d05a95 100755 --- a/README.md +++ b/README.md @@ -1,89 +1,33 @@ Assignment 2 - Short Stack: Basic Two-tier Web Application using HTML/CSS/JS and Node.js === +Kaitlin McDermott +http://a2-kaitlinmcdermott.glitch.me -Due: September 9th, by 11:59 AM. +## Start Your Fitness Journey +My project calculates a user's Body Mass Index(BMI) after getting the user's name, height, and weight as input. +The project takes the users height and weight and outputs their BMI. +Unfortunately, I had difficulty producing a list of the all of the results that displayed on the page. +While working to get a list populated on the page, the functionality of printing the BMI was lost. +I am aware that this project is not complete with all requirements, but after running into issues this is my submission. -This assignment aims to introduce you to the concepts and practice involved in creating a prototype (i.e. not deployment ready) two-tiered web application. -The baseline aims of this assignment involve creating an application that demonstrates the use of several specific pieces of HTML, CSS, JavaScript, and Node.js functionality. -Another aim of this assignment is to establish creative boundaries in which you and your partner can explore designing, implementing, and evaluating usable, useful, novel, and technically efficient web applications. -Baseline Requirements ---- -Note that there is a very large range of application areas and possibilities that meet these baseline requirements. -Games, internet of things, organizational tools, commerce, media - all are possibilities with a two-tiered form-focused web application. -Do not limit yourselves to any of the examples given below. -Examples like the upcoming `efficiency_ratio` idea for the `cars` dataset are meant to be illustrative and easy to understand. -They are not intended to be sensible or useful ideas. -Your application is required to implement the following functionalities: - -- a `Server` which not only serves files, but also maintains a tabular dataset with 3 or more fields related to your application -- a `Results` functionality which shows the entire dataset residing in the server's memory -- a `Form/Entry` functionality which allows a user to add, modify, or delete data items residing in the server's memory -- a `Server Logic` which, upon receiving new or modified "incoming" data, includes and uses a function that adds at least one additional derived field to this incoming data before integrating it with the existing dataset - - the `Derived field` for a new row of data must be computed based on fields already existing in the row. For example, a `cars` dataset with `year`, `horsepower`, and `fuel_efficiency` may create a new field `efficiency_ratio` by dividing `fuel_efficiency` by `horsepower` - -Your application is required to demonstrate the use of the following concepts: - -HTML: -- One or more [HTML Forms](https://developer.mozilla.org/en-US/docs/Learn/HTML/Forms), with any combination of form tags appropriate for the user input portion of the application - - Clarification: the results page can be implemented in any way. `
`s, `table`s, and `list`s are common choices - -CSS: -- CSS styling of the primary visual elements in the application -- Various CSS Selector functionality must be demonstrated: - - Element selectors - - ID selectors - - Class selectors -- CSS positioning and sizing of the primary visual elements in the application: - - CSS to cause at least one element to be horizontally centered on the page - - CSS to cause at least one pair of elements to appear side-by-side - - CSS defined in a maintainable, readable form, in external stylesheets - -JavaScript: -- At minimum, a small amount of front-end JavaScript to get / fetch data from the server; a sample is provided in this repository. - -Node.js: -- An HTTP Server that delivers all necessary files and data for the application. A starting point is provided in this repository. - -Deliverables ---- - -Do the following to complete this assignment: - -1. Fork the starting project code. This repo contains some starter code that may be used or discarded as needed. -2. Implement your project with the above requirements. -3. Test your project to make sure that when someone goes to your main page, it displays correctly. -4. Deploy your project to Glitch, and fill in the appropriate fields in your package.json file. -5. Ensure that your project has the proper naming scheme `a2-yourname` so we can find it. -6. Modify the Readme to the specifications below. -7. Create and submit a Pull Request to the original repo. Only one member needs to submit a pull request. - -Sample Readme (delete the above when you're ready to submit, and modify the below so with your links and descriptions) ---- +## Technical Achievements +- **Tech Achievement 1**: Using a combination of javascript and html as seen in scripts.js +- **Tech Achievement 2**: In index.html, I used select options for the units entered by the user. -## Your Web Application Title -Include a very brief summary of your project here. -Images are encouraged, along with concise, high-level text. +### Design/Evaluation Achievements +- **Design Achievement 1**: Shown in `style.css`, the code includes a background image, background color, a second image, and padding to move the text to the +right side of the page. -Here is a sample formula for summarizing your activities, talk about: -- the domain area the project pertains to -- the main challenges or problems the application addresses -- the key innovations that make it possible to address the problem -- the main results of the implementation, does it really address the problem? -- any additional implications of the resulting application, or possibly areas for future work that have been discovered as part of the design and implementation activities -(Note that when I use the above formula, I aim to have only one sentence per thought in order to remain concise.) -http://a2-charlieroberts.glitch.me +https://www.w3schools.com/html/html_images.asp +I referred to the w3schools website for a lot of pointers on my css file, js files, and my html file. -## Technical Achievements -- **Tech Achievement 1**: Using a combination of... -- **Tech Achievement 2**: ... -### Design/Evaluation Achievements -- **Design Achievement 1**: Shown in `style.css`, the code... -- **Design Achievement 2**: We tested the application with n=X users, finding that... +https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Client-side_storage +I referenced this website when trying to figure out how to store data going to the server. diff --git a/public/css/style.css b/public/css/style.css index d5f842ab..91bdf7b0 100755 --- a/public/css/style.css +++ b/public/css/style.css @@ -1 +1,41 @@ -/*Style your own assignment! This is fun! */ \ No newline at end of file +body { + background-image: url("https://media.istockphoto.com/photos/picture-of-people-running-on-treadmill-in-gym-picture-id879180126?k=6&m=879180126&s=612x612&w=0&h=81vgt7by52wvcmU56mqKuObm8DeB7qtWqI8y3S-zTqI="); + background-repeat: no-repeat; + background-position: left; + background-color: darkseagreen; +} + +h1{ + padding-left: 700px; + font-family: American Typewriter, serif; + } +h2{ + padding-left: 700px; + font-family: Avantgarde, TeX Gyre Adventor, URW Gothic L, sans-serif; +} +.function{ + padding-left: 700px; +} +p{ + padding-left: 700px; +} +form{ + padding-left: 700px; + font-family: Avantgarde, TeX Gyre Adventor, URW Gothic L, sans-serif; +} +button{ + align-content: flex-end; +} +div { + display: block; + padding-left: 700px; +} +label{ + padding-left: 700px; +} +output{ + display: inline; +} +submit{ + padding-left: 700px; +} diff --git a/public/index.html b/public/index.html index c56d620e..00f96dd1 100755 --- a/public/index.html +++ b/public/index.html @@ -2,22 +2,149 @@ CS4241 Assignment 2 + + + + -
- - -
+ planking +

Start Your Fitness Journey Now

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Enter your name:

+

Enter your height: + +

+

Enter your weight: + +

+ +

Your BMI is: ?

+ + + + + + + + + diff --git a/public/js/scripts.js b/public/js/scripts.js index de052eae..b01a4459 100755 --- a/public/js/scripts.js +++ b/public/js/scripts.js @@ -1,3 +1,70 @@ -// Add some Javascript code here, to run on the front end. +const form = document.querySelector('form') +const ul = document.querySelector('ul') +const button = document.querySelector('button') +const input = document.getElementById('name') +let itemsArray = localStorage.getItem('names') ? JSON.parse(localStorage.getItem('names')) : [] -console.log("Welcome to assignment 2!") \ No newline at end of file +localStorage.setItem('names', JSON.stringify(itemsArray)) +const data = JSON.parse(localStorage.getItem('names')) + +const liMaker = text => { + const li = document.createElement('li') + li.textContent = text + ul.appendChild(li) +} + +form.addEventListener('submit', function(e) { + e.preventDefault() + + itemsArray.push(input.value) + localStorage.setItem('names', JSON.stringify(itemsArray)) + liMaker(input.value) + input.value = '' +}) + +data.forEach(item => { + liMaker(item) +}) + +button.addEventListener('click', function() { + localStorage.clear() + while (ul.firstChild) { + ul.removeChild(ul.firstChild) + } +}) + +function getBMI () { + //Obtain user inputs + var height=Number(document.getElementById("height").value); + var heightunits=document.getElementById("heightunits").value; + var weight=Number(document.getElementById("weight").value); + var weightunits=document.getElementById("weightunits").value; + + + //Convert all units to metric + if (heightunits=="inches") height/=39.3700787; + if (weightunits=="lb") weight/=2.20462; + + //Perform calculation + var BMI=weight/Math.pow(height,2); + + //Display result of calculation + document.getElementById("output").innerText=Math.round(BMI*100)/100; + +} +var submissions=[]; +function saveSubmissions(){ + var submission = document.getElementById("name").value; + submissions.push("name"); + console.log(submissions); + document.getElementById("finalBMI").value=submissions; + console.log(document.getElementById("finalBMI").value); +} +document.getElementById("name").innerHTML = submissions; + +function write_below(form) +{ + var output = document.forms.write.output_towrite.value; + document.getElementById('write_here').innerHTML="Your input was:"+output; + return false; +} diff --git a/server.improved.js b/server.improved.js index 26673fc0..15a2af50 100644 --- a/server.improved.js +++ b/server.improved.js @@ -1,3 +1,8 @@ +const list = document.querySelector('ul'); +const nameInput = document.querySelector('#name'); +const finalBMI = document.querySelector('#finalBMI'); +const form = document.querySelector('form'); +const submitBtn = document.querySelector('form button'); const http = require( 'http' ), fs = require( 'fs' ), // IMPORTANT: you must run `npm install` in the directory for this assignment @@ -7,9 +12,9 @@ const http = require( 'http' ), port = 3000 const appdata = [ - { 'model': 'toyota', 'year': 1999, 'mpg': 23 }, - { 'model': 'honda', 'year': 2004, 'mpg': 30 }, - { 'model': 'ford', 'year': 1987, 'mpg': 14} + { 'name': 'kaitlin', 'height': 68, 'weight': 160 }, + { 'name': 'cass', 'height': 61, 'weight': 120 }, + { 'name': 'mike', 'height': 72, 'weight': 150 } ] const server = http.createServer( function( request,response ) { @@ -41,7 +46,9 @@ const handlePost = function( request, response ) { console.log( JSON.parse( dataString ) ) // ... do something with the data here!!! - + //response.send('You are ${context}') + document.write(response); + console.log(request.output) response.writeHead( 200, "OK", {'Content-Type': 'text/plain' }) response.end() }) @@ -68,5 +75,126 @@ const sendFile = function( response, filename ) { } }) } +let db; server.listen( process.env.PORT || port ) +window.onload(function () { + let request = window.indexedDB.open("bmiDB", 1); + request.onerror = function () { + console.log('Database failed to open!'); + }; + request.onsuccess = function () { + console.log('Database opened!'); + + db = request.result; + + displayData(); + } + // Setup the database tables if this has not already been done + request.onupgradeneeded = function (e) { + // Grab a reference to the opened database + let db = e.target.result; + + // Create an objectStore to store our notes in (basically like a single table) + // including a auto-incrementing key + let objectStore = db.createObjectStore('bmiOS', {keyPath: 'id', autoIncrement: true}); + + // Define what data items the objectStore will contain + objectStore.createIndex('name', 'name', {unique: false}); + objectStore.createIndex('bmi', 'result', {unique: false}); + + console.log('Database setup complete'); + }; + form.onsubmit = addData; + + function addData(e) { + // prevent default - we don't want the form to submit in the conventional way + e.preventDefault(); + + // grab the values entered into the form fields and store them in an object ready for being inserted into the DB + let newItem = {name: nameInput.value, bmi: result.value}; + + // open a read/write db transaction, ready for adding the data + let transaction = db.transaction(['bmiOS'], 'readwrite'); + + // call an object store that's already been added to the database + let objectStore = transaction.objectStore('bmiOS'); + + // Make a request to add our newItem object to the object store + var request = objectStore.add(newItem); + request.onsuccess = function () { + // Clear the form, ready for adding the next entry + nameInput.value = ''; + result.value = ''; + }; + // Report on the success of the transaction completing, when everything is done + transaction.oncomplete = function() { + console.log('Transaction completed: database modification finished.'); + + // update the display of data to show the newly added item, by running displayData() again. + displayData(); + }; + + transaction.onerror = function() { + console.log('Transaction not opened due to error'); + }; + } +// Define the displayData() function + function displayData() { + // Here we empty the contents of the list element each time the display is updated + // If you didn't do this, you'd get duplicates listed each time a new note is added + while (list.firstChild) { + list.removeChild(list.firstChild); + } + + // Open our object store and then get a cursor - which iterates through all the + // different data items in the store + let objectStore = db.transaction('bmiOS').objectStore('bmiOS'); + objectStore.openCursor().onsuccess = function(e) { + // Get a reference to the cursor + let cursor = e.target.result; + + // If there is still another data item to iterate through, keep running this code + if(cursor) { + // Create a list item, h3, and p to put each data item inside when displaying it + // structure the HTML fragment, and append it inside the list + let listItem = document.createElement('li'); + let h3 = document.createElement('h3'); + let para = document.createElement('p'); + + listItem.appendChild(h3); + listItem.appendChild(para); + list.appendChild(listItem); + + // Put the data from the cursor inside the h3 and para + h3.textContent = cursor.value.name; + para.textContent = cursor.value.bmi; + + // Store the ID of the data item inside an attribute on the listItem, so we know + // which item it corresponds to. This will be useful later when we want to delete items + //listItem.setAttribute('data-note-id', cursor.value.id); + + // Create a button and place it inside each listItem + let deleteBtn = document.createElement('button'); + listItem.appendChild(deleteBtn); + deleteBtn.textContent = 'Delete'; + + // Set an event handler so that when the button is clicked, the deleteItem() + // function is run + deleteBtn.onclick = deleteItem; + + // Iterate to the next item in the cursor + cursor.continue(); + } else { + // Again, if list item is empty, display a 'No notes stored' message + if(!list.firstChild) { + let listItem = document.createElement('li'); + listItem.textContent = 'No items stored.'; + list.appendChild(listItem); + } + // if there are no more cursor items to iterate through, say so + console.log('Notes all displayed'); + } + }; + } +})