Bummer! This is just a preview. You need to be signed in with a Basic account to view the entire video.
Start a free Basic trial
to watch this video
I'll guide you through how I merged the design files with the app we built.
Bonus Challenge
You may have noticed the finished app in the video has a feature we did not create in this course. In the video, the hints are hidden until the user clicks a button to show them. The challenge described below will be to implement this feature!
Server-Side vs Client-Side
This course has been about writing JavaScript to assemble and serve webpages to browsers. But, as you know, you can run JavaScript in the browser too, to add interactivity to the pages an Express app serves. These two environments, the server-side and the client-side, are worth knowing about and understanding. You have probably written client-side JavaScript already, in previous treehouse courses, for example. That's the JavaScript that is loaded into HTML and manipulates the DOM, among other things.
The Challenge
When our users are studying flashcards, they will likely want to try to guess the answer before they see the hint, and then show the hint if they get stuck. The challenge is to write some JavaScript to hide the hint by default and present a button the user can click to reveal the hint.
Setup
You can serve JavaScript files from the public folder, the same way you're doing with CSS.
- Create a new folder in
public
, next tostylesheets
, and name itjs
. - Inside, create a new file called
app.js
. This is where you'll write the client-side JavaScript.
Writing the Feature
You'll need to
- Hide the hint.
- Create and append a button element to the DOM.
- Add an event listener to the button to unhide the hint when the button is clicked.
- Also, make sure the code only runs on the question side of the flashcard.
Below is a snippet of HTML for use as a guide to what structure the DOM should have after it's manipulated. Try to match this if you want the page to be styled correctly.
<div id="content">
<h2>What is one way a website can store data in a user's browser?</h2>
<button>Show hint</button>
<p class="hint" style="display: none;"><i>They are delicious with milk</i></p>
</div>
Solution
Wen you're ready to see a solution to this problem, look at the completed app in the downloadable project files.
Getting Started with Databases at Treehouse
Documentation
Design Files
Here are the assets from the designer. They model the HTML you'll need to replicate with Pug templates. This can be a difficult, non-linear project, and there aren't necessarily right or wrong answers.
HTML to Pug
HTML to Pug converters may still refer to Pug's old name, Jade. These tools aren't absolutely failsafe, but they will get you close. In most cases, they will probably get you close enough to be helpful.
-
0:00
In the last video,
-
0:01
I offered you a challenge of merging the design files into the final app.
-
0:06
This is not a straight forward task.
-
0:09
So, don't feel bad if you weren't able to complete it.
-
0:12
It actually took me sometime to complete too.
-
0:15
I'm going to show you how I did it.
-
0:17
But for the sake of clarity,
-
0:19
I'm going to skip a lot of the circular paths that I took to get there.
-
0:24
I mentioned it because development is a messy process.
-
0:27
So you shouldn't feel bad if you feel like you're going in circles.
-
0:31
Everyone does, it's all part of the journey.
-
0:35
That being said, let's dive in.
-
0:37
I googled and find an HTML_2_Jade converter tool.
-
0:42
I took the HTML And translated it into Pug files.
-
0:47
I've linked to a couple of different ones in the teacher's notes.
-
0:54
You might see in some of the output these pipe characters.
-
0:58
This is part of Pug that we haven't discussed, and
-
1:01
it's a way to add plain text to HTML.
-
1:04
You don't need to worry about it too much for now.
-
1:07
If you want to know more, you can find a link in the teacher's notes,
-
1:11
to the documentation that discusses it.
-
1:13
I compared the layout file I created with all the files I got back from design.
-
1:18
I found that all the top seven lines were in comment,
-
1:23
so I put this into my new layout file called layout.pug.
-
1:27
Then I called the block where I wanted to place my content main.
-
1:34
I notice that non of the files had a footer.
-
1:37
While many apps have footers, this one won't.
-
1:41
So I got read of the photo partial from the previous version of the app.
-
1:46
I did need a header though.
-
1:48
That's actually where the content wound up, so
-
1:52
I just modified the header.pug file inside.
-
1:56
Next I looked at the body content for the design files.
-
2:00
They all began with the section that had the class of name card, except for
-
2:04
the error page.
-
2:06
The error page has a different structure to any other page, so
-
2:10
I didn't need to try and cut that up.
-
2:13
When I pasted the contents in,
-
2:16
I replaced the dummy text with the locals sent from my app.
-
2:22
I put error message, the error status and the error.stack.
-
2:28
When the error page was out of the way,
-
2:30
I didn't have to focus on as many pages, which made it easier.
-
2:35
I did come across a tricky part though.
-
2:38
When I looked at the body elements of the remaining designs,
-
2:42
I noticed that they all started with a name card section.
-
2:45
The name card section is a little different for each one.
-
2:48
So, I decided to create a new template to hold the common code.
-
2:53
I called it app.pug.
-
2:55
Inside the app.pug, I started to extend the layout and declaring the main block.
-
3:04
And then in the name card section.
-
3:07
And a div inside.
-
3:08
I compared the contents of this name card login div among the designs.
-
3:14
This is where the user will see hello student, or
-
3:18
greeted by their name and a goodbye.
-
3:24
So I used an if else block.
-
3:31
To show those whether if the name was present or not.
-
3:35
The design file then has the form inside the name card section,
-
3:39
while the other design files don't.
-
3:43
That's why I declared the intro block nested in the name card.
-
3:49
Then I created a hello.pug file, and extended from the app.
-
3:54
Notice I extended from the app, and not layout.
-
3:59
When the hello template is rendered, it will extend the app, and
-
4:04
then it will extend the layout.
-
4:09
Training templates together can be a useful way to shear code.
-
4:14
After extending the app, I declare the intro block with the form nested inside.
-
4:22
Looking in the index design file.
-
4:24
It was one heading with an anchor tag in the place of the hello templates form.
-
4:29
So, I just save the hello template as the index.pug,
-
4:32
and then replace the block with those elements.
-
4:37
After that, the card front and card back with the less design files to work with.
-
4:44
They were really just the same template with the unique content inside
-
4:49
this section, which is outside of the name card section.
-
4:53
In the app template, I put a block with card to place the content as
-
4:58
the next sibling of the name card section.
-
5:04
In the card.pug template file, I extend the app and
-
5:09
declare the card block with the remaining content.
-
5:15
Once I pasted in the design file content,
-
5:18
I replaced all the dummy text with the variables that our app could provide.
-
5:29
Starting with the divs classes, the class could either be card question or
-
5:35
card answer, so replace the parts after the hyphen with the side variable.
-
5:42
Looking at the card title heading 1.
-
5:48
The text content is capitalized, but when I discovered this page when I viewed it in
-
5:53
a web browser, that the capitalization didn't matter.
-
5:57
The text is converted by the CSS to be all caps.
-
6:02
That will make our code simpler.
-
6:04
We were supplying a separate variable
-
6:07
to this template to show the display version of the string that was capsulized.
-
6:13
Now, we can just use the same local variable
-
6:16
that we're using to set the class.
-
6:20
I replaced the dummy hint with a hint local variable.
-
6:24
To provide the link to the view to the other side of the card,
-
6:27
I just modified the link here.
-
6:30
Now let's look at the app in the browser.
-
6:32
I can enter my name and
-
6:37
see the greeting, then I can launch the flash cards.
-
6:43
I can uncover the hints, and flip the answer over.
-
6:50
Hitting the forward button gives me a random card.
-
6:57
Finally, I can click on the X to clear the cookie with my name in it.
-
7:03
Cool, this looks really good.
-
7:07
In this course,
-
7:08
you've learned how to create a dynamic web application in express.
-
7:12
You've also learned about HTTP and
-
7:15
other concepts that are common to many other web frameworks.
-
7:18
Now that you have the basics, feel free to take this out further and
-
7:22
expand your knowledge.
-
7:23
Here's a few ideas to get you started.
-
7:27
Right now, our app only has one set of flash cards.
-
7:31
You could add the ability to switch between different sets,
-
7:34
which could be organized by a theme.
-
7:37
There could be an astronomy set, for example, or an anatomy of physiology set.
-
7:44
The app is getting the data from a flat JSON file.
-
7:47
But normally this kind of app would be connected to a database.
-
7:51
A database would allow you to store new flash cards through the app itself.
-
7:55
As it stands, you need to edit the JSON file manually to create a new cards.
-
8:01
We have several courses at Treehouse to get you started with databases.
-
8:05
Check the teacher's notes for links.
-
8:08
We have a simple greeting functionality in the app,
-
8:10
this is a far cry away from any sort of login and authentication.
-
8:15
We have a course on authentication at Treehouse if you'd like to learn how to
-
8:19
create users for your app.
-
8:21
I hope you've enjoyed this course, and that I will see you again soon.
-
8:25
Til then, happy coding.
You need to sign up for Treehouse in order to download course files.
Sign up