Foundation of web programming
DOM
Web page is a document. This document can be either displayed in the browser window or as the HTML source. But it is the same document regardless of how you interact with it.
DOM — Document Object Model is an abstraction which represents the structure of the content on the web. We can manipulate DOM based on user behavior.
Pillars of Web Programming
According to flatiron school methodology web programming stands on thee pillars:
- Recognize Events
- Communicate with the Server
- Manipulate the DOM
For our examples we are going to use javascript because it most popular language for web programming, but you can apply the same methodology using other languages.
Events
By events we understand any user action with we want to react to. For example if user click on button, we want to change the DOM.
First we need to select HTML element which represents button user click.
let categoriesLI = document.querySelector(‘#categories’)categoriesLI.addEventListener(‘click’, event => {renderCategoryList(event)})
In this example we select LI element with ID categories and assign it to variable categoriesLI. Then we add an event listener to this element. And we specified type of event, it this case its click.
When user click on element with ID categories it will trigger function renderCategoryList and we passing event data to the argument of this function.
Communicate with the Server
After event triggered we need to describe what is going to happen after. We will probably want to manipulate the DOM. But first let’s get some new data from server which we are going to insert into the DOM.
fetch(‘http://localhost:3000/categories').then(r => r.json()).then(respond => {…………}
We are going to use fetch to send GET request to target URL. After sending request we will get back respond from the server. Also we are going to use ‘then’ function to wait till server return as response because the return value of the fetch is ‘promise’. We need to convert this data into something readable, in our case we are going to convert data into json. And when we got json, we can use it to manipulate the DOM.
Manipulate the DOM
Great, we recognized event, send a request to the server and got readable data from the server. Now it’s time to change the DOM.
fetch('http://localhost:3000/categories')
.then(r => r.json())
.then(respond => {
respond.forEach(item => {
let li = document.createElement('LI')
li.innerText = item.name
li.setAttribute('data-id' , item.id)
li.addEventListener('click', event => {renderProductsList(event)})
categoriesUl.append(li)
})
})
After conversion we got array of objects. In order to get access to all objects and insert it to the DOM we need to iterate over this array user forEach function. And then we can create new HTML elements, insert data from server respond into it and its attributes and then append it to the DOM.
Example with different type of requests
So far we were sending only GET request. But how we can send POST or PATCH request to server and see new data dynamically without need to refresh the page.
POST
Let’s say we have this form where user can submit some input:
<form id="new-quote-form">
<div class="form-group">
<label for="new-quote">New Quote</label>
<input type="text" class="form-control" id="new-quote" placeholder="Learn. Love. Code.">
</div>
<div class="form-group">
<label for="Author">Author</label>
<input type="text" class="form-control" id="author" placeholder="Flatiron School">
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
Selecting input form and sending POST request to the server:
const selectForm = document.querySelector('#new-quote-form')selectForm.addEventListener('submit', e => {
e.preventDefault()let author = e.target.author.value
let input = document.querySelector('#new-quote')
input.name = "pavel"let newQuote = e.target['new-quote'].valuefetch(getUrl, {
method: 'POST',
headers: {
'Content-type':'application/json',
'Accept':'application/json'
},
body: JSON.stringify({
author: author,
quote: newQuote,
likes: '0'
})
})
Manipulating DOM after user submit it’s input:
.then(r => r.json())
.then(resp => {
debugger
let li = document.createElement('LI')
let pLike = document.createElement('P') li.innerText = resp.quote
pLike.innerText = `Likes: ${resp.likes.length}` selectUl.append(li, pLike)
})
})
PATCH
PATCH request is very similar with POST but instead of creating new row in database we modify specific cell of selected row.
In following example we simply change current boolean value of the ‘isGooddog’ attribute of the ‘dog’ object on opposite if event listener has been triggered.
dogButton.addEventListener("click", (event) => {dog.isGooddog = !dog.isGooddogfetch(`http://localhost:3000/pups/${event.target.id}`, {
method: "PATCH",
headers: {
"Content-Type": "application/json",
"Accept": "application/json"
},
body: JSON.stringify({
isGooddog: dog.isGooddog
})
})
.then(r => r.json())
.then(response => {
if (response.isGooddog) {
dogButton.innerText = "Good Dog!"
} else {
dogButton.innerText = "Bad Dog!"
}
})
})
DELETE
Delete request pretty straight forward. Most important to specify ‘method’ and hit correct RESTful rout. And, of course, we shouldn’t forget to manipulate DOM after request has been processed.
function deleteReview(event){
fetch(`http://localhost:3000/reviews/${event.target.id}`, {
method: 'DELETE'
})
let button = document.getElementById(event.target.id)
button.parentElement.remove()
}
Conclusion
JavaScript is like a fire, if you know how to talk to it, it will help you go through the next winter, if not, it will burn down your DOM.