by Ian Schoonover
*See next slide for refactored version
From This
To This
<div class="container">
*You don't need the closing </div> yet, we will put that in the footer.ejs partial in the next slide...
</div><!-- /.container -->
Important note! Now that we have added the opening and closing .container div tags to the header and footer partials, we need to remove them from all of the views that have a .container div and also include a header and footer partial.
If you don't remove those tags then the grid will be offset.
This includes ALL of the views inside of:
/views/campgrounds & /views/comments
Be sure to go through all of those EJS files and remove <div class="container"> and its closing </div> tag.
<div class="row">
<h1 style="text-align: center">Login</h1>
<div style="width: 30%; margin: 25px auto;">
<form action="/login" method="post">
<div class="form-group">
<input class="form-control" type="text" name="username" placeholder="username">
</div>
<div class="form-group">
<input class="form-control" type="password" name="password" placeholder="password">
</div>
<div class="form-group">
<button class="btn btn-lg btn-primary btn-block">Login</button>
</div>
</form>
<a href="/campgrounds">Go Back</a>
</div>
</div>
<div class="row">
<h1 style="text-align: center">Sign Up</h1>
<div style="width: 30%; margin: 25px auto;">
<form action="/register" method="post">
<div class="form-group">
<input class="form-control" type="text" name="username" placeholder="username">
</div>
<div class="form-group">
<input class="form-control" type="password" name="password" placeholder="password">
</div>
<div class="form-group">
<button class="btn btn-lg btn-primary btn-block">Sign Up!</button>
</div>
</form>
<a href="/campgrounds">Go Back</a>
</div>
</div>
<nav class="navbar navbar-default">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="/">YelpCamp</a>
</div>
<div id="navbar" class="collapse navbar-collapse">
<ul class="nav navbar-nav">
<li class="<%= typeof page !== 'undefined' && page === 'campgrounds' ? 'active' : '' %>"><a href="/campgrounds">Home</a></li>
</ul>
<ul class="nav navbar-nav navbar-right">
<% if(!currentUser){ %>
<li class="<%= typeof page !== 'undefined' && page === 'login' ? 'active' : '' %>"><a href="/login">Login</a></li>
<li class="<%= typeof page !== 'undefined' && page === 'register' ? 'active' : '' %>"><a href="/register">Sign Up</a></li>
<% } else { %>
<li><a href="#">Signed In As <%= currentUser.username %></a></li>
<li><a href="/logout">Logout</a></li>
<% } %>
</ul>
</div>
</div>
</nav>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
You'll notice that the opening list item tags in the nav element now have a class attribute with EJS tags inside of it:
This is an example of ternary operators.
It's simply a single line if/else statement that says "if there is a local variable named page and it is equal to the string 'campgrounds' then give this list item a class of 'active' otherwise (else) don't give it any class at all.
We pass the local variable, 'page', into each view via the res.render() method (see next slide).
<%= typeof page !== 'undefined' && page === 'campgrounds' ? 'active' : '' %>
// show register form
router.get("/register", function(req, res){
res.render("register", {page: 'register'});
});
//show login form
router.get("/login", function(req, res){
res.render("login", {page: 'login'});
});
//INDEX - show all campgrounds
router.get("/", function(req, res){
// Get all campgrounds from DB
Campground.find({}, function(err, allCampgrounds){
if(err){
console.log(err);
} else {
res.render("campgrounds/index",{campgrounds: allCampgrounds, page: 'campgrounds'});
}
});
});
You may have also noticed that the nav element has some extra markup in it.
We've added code that allows us to turn the menu into a dropdown whenever the site is viewed on a smaller screen (e.g., phone or tablet)
Before this can work we will need to add a meta tag in our header partial then add jQuery and Bootstrap's JavaScript file to the footer partial
<!-- Make site responsive on mobile/tablet -->
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- jQuery CDN -->
<script
src="https://code.jquery.com/jquery-3.1.1.min.js"
integrity="sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8="
crossorigin="anonymous"></script>
<!-- Bootstrap JS CDN -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
Currently, when you try to register a new user with the same name as an existing user, the app should reload the register view and display a flash message. But the flash message doesn't appear unless you reload the register page a second time, or navigate to another page.
We'll fix that now.
if(err){
console.log(err);
return res.render("register", {error: err.message});
}
//handle sign up logic
router.post("/register", function(req, res){
var newUser = new User({username: req.body.username});
User.register(newUser, req.body.password, function(err, user){
if(err){
console.log(err);
return res.render("register", {error: err.message});
}
passport.authenticate("local")(req, res, function(){
req.flash("success", "Successfully Signed Up! Nice to meet you " + req.body.username);
res.redirect("/campgrounds");
});
});
});
If you have any questions then please create a thread in the Q&A