diff --git a/README.md b/README.md index 996cf12d..de372a96 100644 --- a/README.md +++ b/README.md @@ -1,97 +1,26 @@ -Assignment 2 - Short Stack: Basic Two-tier Web Application using HTML/CSS/JS and Node.js -=== +## A2 -- Andrew Kerekon -- WPI Student Preferences -- https://a2-akerekon.glitch.me/ +For this project, I created a small survey form using the flexbox layout to collect data on WPI students' favorite dorms, dining halls, and spots on campus by class year. I included a "yearsRemaining" field that is derived from both a student's class year (4 for first-year, 3 for sophomore, 2 for junior, 1 for senior, and N/A for graduate students) and their name (the name "Gompei" is an easter egg that results in staying at WPI for another 100 years!). Additionally, pressing the "Step On The Seal" button will add 1 additional year to all undergraduate students in the table and any undergraduate students added before the next reload. This website can be used by scrolling to "Add A Rating" and entering data in all fields (with additional notes being optional), then pressing "Add This Rating!". Additionally, each row can be deleted by pressing the "Delete!" button, which will persist on reload. -Due: September 9th, by 11:59 AM. - -This assignment aims to introduce you to creating a prototype two-tiered web application. -Your application will include the use of HTML, CSS, JavaScript, and Node.js functionality, with active communication between the client and the server over the life of a user session. - -Baseline Requirements ---- - -There is a large range of application areas and possibilities that meet these baseline requirements. -Try to make your application do something useful! A todo list, storing / retrieving high scores for a very simple game... have a little fun with it. - -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 `todo` dataset with `task`, `priority`, and `creation_date` may generate a new field `deadline` by looking at `creation_date` and `priority` - -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 -- A results page displaying all data currently available on the server. You will most likely use a `` tag for this, but `
+ + + + + + + + + + + +
Response IDNameAcademic YearYears Till GraduationBest Dorm?Best Dining Hall?Favorite Spot?Additional NotesChange Data
+ +

Add A Rating:

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

+ WPI Logo Used With Permission -- https://www.wpi.edu/sites/default/files/docs/Offices/Marketing-Communications/WPI_Institutional_9-4-12.pdf +
+ WPI Quadrangle Used With Permission Under Creative Commons License -- https://en.wikipedia.org/wiki/File:WPI_Quad.jpeg +

+
+ - diff --git a/public/js/scripts.js b/public/js/scripts.js index de052eae..5566e9a1 100644 --- a/public/js/scripts.js +++ b/public/js/scripts.js @@ -1,3 +1,163 @@ -// Add some Javascript code here, to run on the front end. +let numberOfElements = 1; +let seal = false; -console.log("Welcome to assignment 2!") \ No newline at end of file +function stepOnSeal() { + seal = true; + let table = document.getElementById("ratings"); + table.rows[0].cells[3].innerHTML = "Years Till Graduation (Seal Stepped!)" + updateTable(); + alert("You stepped on the seal! All students now graduate 1 year later than their expected graduation year until the next reload!\n\nFirst-Years: 4 --> 5 years\nSophomores: 3 --> 4 years\nJuniors: 2 --> 3 years\nSeniors: 1 --> 2 years"); +} + +function updateTable() { + let table = document.getElementById("ratings"); + if (seal) { + table.innerHTML = 'Response IDNameAcademic YearYears Till Graduation (Seal Stepped!)Best Dorm?Best Dining Hall?Favorite Spot?Additional NotesChange Data'; + } else { + table.innerHTML = 'Response IDNameAcademic YearYears Till GraduationBest Dorm?Best Dining Hall?Favorite Spot?Additional NotesChange Data'; + } + fetch('/getData', { + method: 'GET' + }) + .then(response => response.json()) + .then(function(json) { + console.log(json); + let rowIndex = 0; + for (let rowData of json) { + numberOfElements = rowData.responseID; + let row = table.insertRow(-1); + + let responseID = row.insertCell(0); + let name = row.insertCell(1); + let studentYear = row.insertCell(2); + let yearsRemaining = row.insertCell(3); + let favoriteDorm = row.insertCell(4); + let favoriteDining = row.insertCell(5); + let favoriteSpot = row.insertCell(6); + let notes = row.insertCell(7); + let modify = row.insertCell(8); + + row.cells[0].innerHTML = rowData.responseID; + row.cells[1].innerHTML = rowData.name; + row.cells[2].innerHTML = rowData.studentYear; + row.cells[3].innerHTML = rowData.yearsRemaining + sealIncrement(rowData.studentYear); + row.cells[4].innerHTML = rowData.favoriteDorm; + row.cells[5].innerHTML = rowData.favoriteDining; + row.cells[6].innerHTML = rowData.favoriteSpot; + row.cells[7].innerHTML = rowData.notes; + + row.cells[8].innerHTML = "" + + rowIndex++; + } + }) +} + +function sealIncrement(studentYear) { + let increment = ''; + + if (seal) { + switch (studentYear) { + case 'First-Year': + increment = 1; + break; + case 'Sophomore': + increment = 1; + break; + case 'Junior': + increment = 1; + break; + case 'Senior': + increment = 1; + break; + case 'Graduate Student': + increment = ''; + break; + default: + increment = ''; + break; + } + } + + return increment; +} + +const submit = function( e ) { + // prevent default form action from being carried out + e.preventDefault(); + + /*const input = document.querySelector( '#name' ), + json = { yourname: input.value }, + body = JSON.stringify( json ) */ + + const name = document.getElementById('name').value; + const studentYear = document.getElementById('studentYear').value; + const favoriteDorm = document.getElementById('favoriteDorm').value; + const favoriteDining = document.getElementById('favoriteDining').value; + const favoriteSpot = document.getElementById('favoriteSpot').value; + const notes = document.getElementById('notes').value; //Can be blank + + if (name.trim() === '' || studentYear.trim() === '' || favoriteDorm.trim() === '' || favoriteDining.trim() === '' || favoriteSpot.trim() === '') { + alert("To obtain accurate data, please be sure to respond to every question (except for additional notes)!") + return false; + } else { + numberOfElements++; + + const jsonData = { + responseID: numberOfElements, + name: name, + studentYear: studentYear, + favoriteDorm: favoriteDorm, + favoriteDining: favoriteDining, + favoriteSpot: favoriteSpot, + notes: notes + } + + let body = JSON.stringify(jsonData); + + fetch( '/submit', { + method:'POST', + body + }) + .then( function( response ) { + updateTable(); + clearForm(); + }) + + return true; + } +} + +function clearForm() { + document.getElementById('name').value = ''; + document.getElementById('studentYear').value = 'First-Year'; + document.getElementById('favoriteDorm').value = 'Daniels Hall'; + document.getElementById('favoriteDining').value = 'Campus Center'; + document.getElementById('favoriteSpot').value = ''; + document.getElementById('notes').value = ''; +} + +function deleteRow(rowIndex) { + let confirmDelete = confirm("Are you sure you'd like to delete this row?"); + if (confirmDelete) { + const json = { + deletingItem: rowIndex + } + + let body = JSON.stringify(json); + fetch('/delete', { + method: 'POST', + body + }) + .then( function() { + updateTable(); + }) + } +} + +window.onload = function() { + const button = document.querySelector( 'button' ); + button.onclick = submit; + + updateTable(); +} \ No newline at end of file diff --git a/server.improved.js b/server.improved.js index 26673fc0..acface31 100644 --- a/server.improved.js +++ b/server.improved.js @@ -7,9 +7,16 @@ 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} + { + responseID: 1, + name: 'Andrew', + studentYear: 'Sophomore', + yearsRemaining: 3, + favoriteDorm: 'Morgan Hall', + favoriteDining: 'Campus Center', + favoriteSpot: 'Salisbury', + notes: 'Morgan 4 Best Floor!' + } ] const server = http.createServer( function( request,response ) { @@ -25,7 +32,11 @@ const handleGet = function( request, response ) { if( request.url === '/' ) { sendFile( response, 'public/index.html' ) - }else{ + } else if (request.url === '/getData') { + response.writeHeader( 200, { 'Content-Type': 'text/plain' }) + response.end(JSON.stringify(appdata)); + } + else{ sendFile( response, filename ) } } @@ -38,15 +49,61 @@ const handlePost = function( request, response ) { }) request.on( 'end', function() { - console.log( JSON.parse( dataString ) ) + if (request.url === '/submit') { + appdata.push(JSON.parse(dataString)); + } else if (request.url === '/delete') { + deleteItem(JSON.parse(dataString)); + } + // ... do something with the data here!!! + + for(let i = 0; i < appdata.length; i++) { + let row = appdata[i]; + row.yearsRemaining = getYearsRemaining(row.studentYear, row.name); + } - // ... do something with the data here!!! + console.log( appdata ) response.writeHead( 200, "OK", {'Content-Type': 'text/plain' }) response.end() }) } +const deleteItem = function(jsonData) { + appdata.splice(jsonData['deletingItem'], 1); +} + +function getYearsRemaining(studentYear, name) { + let years = -1; + + console.log(name); + + switch (studentYear) { + case 'First-Year': + years = 4; + break; + case 'Sophomore': + years = 3; + break; + case 'Junior': + years = 2; + break; + case 'Senior': + years = 1; + break; + case 'Graduate Student': + years = 'N/A'; + break; + default: + years = 'N/A'; + break; + } + + if (name === 'Gompei') { + years = 100; + } + return years; +} + const sendFile = function( response, filename ) { const type = mime.getType( filename )