diff --git a/README.md b/README.md index 4471f667..1fe22819 100644 --- a/README.md +++ b/README.md @@ -1,100 +1,15 @@ Assignment 2 - Short Stack: Basic Two-tier Web Application using HTML/CSS/JS and Node.js -=== -Due: September 9th, by 11:59 AM. +NOTE: Prof. Roberts and Akim approved late extension -This assignment will 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. +link: https://a2-laurapellowski.glitch.me/ -Baseline Requirements ---- - -There are a 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 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 `
+ + + + + + + + +
RowTea TypeDay ConsumedRatingMeaning
diff --git a/public/js/main.js b/public/js/main.js index a569258f..e9a816d2 100644 --- a/public/js/main.js +++ b/public/js/main.js @@ -7,8 +7,12 @@ const submit = async function( event ) { // remains to this day event.preventDefault() - const input = document.querySelector( '#yourname' ), - json = { yourname: input.value }, + const inputType = document.querySelector( '#type' ), + inputDay = document.querySelector( '#day' ), + inputRating = document.querySelector( '#rating' ), + json = { type: inputType.value, + day: inputDay.value, + rating: inputRating.value }, body = JSON.stringify( json ) const response = await fetch( '/submit', { @@ -16,12 +20,106 @@ const submit = async function( event ) { body }) - const text = await response.text() + const data = await response.json() + showTable(data); - console.log( 'text:', text ) +} + +const showTable = function(data) { + const table = document.querySelector('table') + table.innerHTML = '' + + //for recreating the column titles + const tr = document.createElement('tr') + const th0 = document.createElement('th') + const th1 = document.createElement('th') + const th2 = document.createElement('th') + const th3 = document.createElement('th') + const th4 = document.createElement('th') + th0.innerText = "Row" + tr.appendChild(th0) + th1.innerText = "Tea Type" + tr.appendChild(th1) + th2.innerText = "Day Consumed" + tr.appendChild(th2) + th3.innerText = "Rating" + tr.appendChild(th3) + th4.innerText = "Meaning" + tr.appendChild(th4) + table.appendChild(tr) + + //filling in the data + data.forEach ( item => { + const tr = document.createElement('tr') + const td0 = document.createElement('td') + const td1 = document.createElement('td') + const td2 = document.createElement('td') + const td3 = document.createElement('td') + const td4 = document.createElement('td') + + //don't need the plus 1 bc we added the header row + td0.innerText = table.rows.length + tr.appendChild(td0) + td1.innerText = item.type + tr.appendChild(td1) + td2.innerText = item.day + tr.appendChild(td2) + td3.innerText = item.rating + tr.appendChild(td3) + td4.innerText = item.meaning + tr.appendChild(td4) + + table.appendChild(tr) + }) +} + + +const deleteRow = async function( event ) { + event.preventDefault() + + const inputRow = document.querySelector( '#row' ), + json = { row: inputRow.value }, + body = JSON.stringify( json ) + + const response = await fetch( '/delete', { + method:'DELETE', + body + }) + + const data = await response.json() + showTable(data) +} + +const update = async function( event ) { + event.preventDefault() + + const inputRow = document.querySelector( '#rowEdit' ), + inputType = document.querySelector( '#typeEdit' ), + inputDay = document.querySelector( '#dayEdit' ), + inputRating = document.querySelector( '#ratingEdit' ), + json = { row: inputRow.value, + type: inputType.value, + day: inputDay.value, + rating: inputRating.value }, + body = JSON.stringify( json ) + + const response = await fetch( '/patch', { + method:'PATCH', + body + }) + + const data = await response.json() + showTable(data) } window.onload = function() { - const button = document.querySelector("button"); + + const button = document.querySelector("#submit"); button.onclick = submit; + + const button2 = document.querySelector("#delete"); + button2.onclick = deleteRow; + + const button3 = document.querySelector("#update"); + button3.onclick = update; } \ No newline at end of file diff --git a/server.js b/server.js index 9ac27fb8..9f92e786 100644 --- a/server.js +++ b/server.js @@ -9,19 +9,22 @@ 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} -] + //{ 'type': 'green', 'day': 'sunday', 'rating': '8', 'meaning': 'very good! will drink often!' }, + ] const server = http.createServer( function( request,response ) { if( request.method === 'GET' ) { handleGet( request, response ) }else if( request.method === 'POST' ){ handlePost( request, response ) + }else if(request.method === 'DELETE'){ + handleDelete(request, response) + }else if(request.method === 'PATCH') { + handlePatch(request, response) } }) + const handleGet = function( request, response ) { const filename = dir + request.url.slice( 1 ) @@ -32,6 +35,27 @@ const handleGet = function( request, response ) { } } +const deriveField = function(dataParse) { + //logic for determining meaning from the rating + let meaning = 'default' + if (dataParse.rating < -10) { + meaning = 'EGGTTOMMESWFTCEP' + } else if (dataParse.rating <= 2) { + meaning = 'BAD, do not drink again' + } else if (dataParse.rating > 2 && dataParse.rating <5) { + meaning = 'not very good, probably will not drink again' + } else if (dataParse.rating >= 5 && dataParse.rating <=7) { + meaning = 'pretty average, maybe drink once in a while' + } else if (dataParse.rating > 7 && dataParse.rating <=9) { + meaning = 'very good! will drink often!' + } else if (dataParse.rating == 10) { + meaning = 'my favorite!!' + } else { + meaning = 'rating does not compute' + } + return meaning; +} + const handlePost = function( request, response ) { let dataString = '' @@ -40,12 +64,74 @@ const handlePost = function( request, response ) { }) request.on( 'end', function() { - console.log( JSON.parse( dataString ) ) + + dataParse = JSON.parse( dataString ) + + //only push data if at least one of the textboxes was filled with data + if (dataParse.type !== "" || dataParse.day !== "" || dataParse.rating !== "") { + const meaning = deriveField(dataParse) + dataParse.meaning = meaning; + appdata.push(dataParse) + } + + response.writeHead( 200, "OK", {'Content-Type': 'text/plain' }) + response.end( JSON.stringify (appdata)) + }) +} + +const handleDelete = function(request, response) { + let dataString = '' + + request.on( 'data', function( data ) { + dataString += data + }) - // ... do something with the data here!!! + request.on( 'end', function() { + + dataParse = JSON.parse( dataString ) + + const index = dataParse.row-1 + if (index < 0 || index > appdata.length-1) { + console.log("Row doesn't exist. Please enter a valid row number") + } else { + appdata.splice(index, 1); + } + + response.writeHead( 200, "OK", {'Content-Type': 'text/plain' }) + response.end( JSON.stringify (appdata)) + }) +} + +const handlePatch = function(request, response) { + let dataString = '' + + request.on( 'data', function( data ) { + dataString += data + }) + + request.on( 'end', function() { + + dataParse = JSON.parse( dataString ) + const index = dataParse.row-1 + + if (index < 0 || index > appdata.length-1) { + console.log("Row doesn't exist. Please enter a valid row number") + } else { + let obj = appdata[index] + if (dataParse.type !== "") { + obj.type = dataParse.type + } + if (dataParse.day !== "") { + obj.day = dataParse.day + } + if (dataParse.rating !== "") { + obj.rating = dataParse.rating + obj.meaning = deriveField(dataParse) + } + } response.writeHead( 200, "OK", {'Content-Type': 'text/plain' }) - response.end('test') + response.end( JSON.stringify (appdata)) }) }