Toggle active link Bootstrap navbar - node.js

I've read a lot of posts on the subject, found almost always the same solution but it does not work for me...
My problem is as follows : I want to use Twitter Bootstrap 2.3.2 and its navbar, so I include the css and js files. Just before that, I also include jquery. I then take an example given on the bootstrap site which display very well. However, I now want to set the menu item clicked as active and remove the active class from all others. I saw in the bootstrap.js file that this function is built in, so no more script code to include. The problem is that the menu items do never toggle to active. I then tried to add a jquery script to force removing all active classes and add the active class to the one item that was clicked. Nothing happened.
So please, help !! I tried the same code in jsfiddle and it works fine, so does the problem comes from jade ? from express layout ? how to fix it ?
Here is the code I use :
server.js
var express = require('express');
var app = express();
var port = 3000;
app.set('view engine', 'jade');
app.set('view options', {layout: true});
app.set('views', __dirname + '/views');
app.configure(function () {
this.use(express.cookieParser());
this.use(express.session({ secret: 'shhhhhhhhh' }));
this.use(express.static(__dirname + '/public'));
this.use(app.router);
});
app.get('/', function (req, res) {
res.render('index')
});
});
app.get('/about', function (req, res) {
res.render('about')
});
});
app.listen(port, function () {
console.log('listening in http://localhost:' + port);
});
/views/layout.jade
!!! 5
html
head
title Test Application
link(type='text/css', rel='stylesheet', href='/css/site.css')
link(rel='stylesheet', href='//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap.min.css')
script(src='//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js')
script(src='//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/js/bootstrap.min.js');
body
div.navbar.navbar-inverse.navbar-fixed-top
div.navbar-inner
div.container
button.btn.btn-navbar(type='button', data-toggle='collapse', data- target='.nav-collapse')
span.icon-bar
span.icon-bar
span.icon-bar
a.brand(href='#') Login Test Application
div.nav-collapse.collapse
ul.nav
li.active
a(href='#') Home
li
a(href='#about') About
li
a(href='#Contact') Contact
div.container
block content
/views/index.jade
extends layout
block content
div.span6.offset3
h1 Test Application
div.span12
h2 Test application!
p This is a test application
button.btn.btn-success(type='button', onclick='')') Login
/views/about.jade
extends layout
block content
div.span6.offset3
h1 - About -

You can try with something like that in you jade layout :
li(class=title=='Home'?'active':undefined)
a(href="/") Home
li(class=title=='About'?'active':undefined)
a(href="/about") About
li(class=title=='Contact'?'active':undefined)
a(href="/contact") Contact
Then just add this to your server.js :
app.get('/', function (req, res) {
res.render('index', title: 'Home')
});
app.get('/about', function (req, res) {
res.render('about', title: 'About')
});
This way, you can also remove the hard coded title in your layout and modify it through this solution as :
title #{title} | Test Application
And it will render this as a title for your home :
Home | Test Application

Here the solution I've found (I dont have the link anymore, sorry for the code owner)
ul.nav
-var obj = { 'home':'Home', 'about':'About', 'contact':'Contact' }
-each val, key in obj
-if (id == key)
li.active
a(href='#{key}') #{val}
-else
li
a(href='#{key}') #{val}
and I set the server.js as
app.get('/about', function (req, res) {
res.render("about", {
title: 'About',
id: 'about',
user: JSON.stringify(req.user, 0, 2)
});
});

Related

href of static html called in router does not work as expected

First the index.pug: (located in /views/config)
html
head
some header
body
h1 some body
a("onepage") some text
In the app.ts: (only the important parts)
app.set("views", path.join(__dirname, "views"));
app.use("/config", configRouter);
In the configRouter.ts
const configRouter = express.Router();
configRouter.get("/", (req, res) => {
res.render("config/index.pug");
});
Can someone help me?
When I press on the "some text" link i get navigated to mainpage/onepage instead of mainpage/config/onepage as I would expect.

Getting a 404 on a live server but 304 on a localhost with Pug

So, this is a strange one. I am running a Nodejs application using Express and Pug. I have all my static files in a Public folder and my Pug files in the Views folder. I set up the app.js file to grab all the static files from the Public folder. I am using Nginx to handle the server.
Here is the weird part, when i run it on a Ubuntu instance using AWS I get a 404 on all of my js and css files. When i run it on my local computer I get 304 errors, but everything loads and works.
Any ideas what I did wrong? I will Show some of my code beneath.
Pug File
doctype html
html
head
meta(charset='utf-8')
title Signature Pad
meta(name='description', content='Signature Pad - HTML5 canvas based smooth signature drawing using variable width spline interpolation.')
meta(name='viewport', content='width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=no')
meta(name='apple-mobile-web-app-capable', content='yes')
meta(name='apple-mobile-web-app-status-bar-style', content='black')
link(rel='stylesheet', href='stylesheets/signature-pad.css')
#signature-pad.signature-pad
.signature-pad--body
canvas
.signature-pad--footer
div
.description Sign Above
.signature-pad--actions
div
button.button.clear(type='button', data-action='clear') Clear
button.button(type='button', data-action='undo') Undo
div
form(action='', method='POST', onsubmit='completeAndRedirect();return false;')
label(for='fname') First name:
input#firstName(type='text', name='fname')
label(for='lname') Last name:
input#lastName(type='text', name='lname')
br
br
label(for='company') Company:
input#company(type='text', name='company')
br
br
input.button.save(type='submit', value='Submit', data-action='save-svg')
script(src='js/signature_pad.umd.js')
script(src='js/app.js')
App.js file
const express = require('express');
const path = require('path');
const NetSuiteOauth = require('netsuite-tba-oauth');
const bodyParser = require('body-parser');
const app = express();
//Parse incoming request
app.use(bodyParser.json());
//app.use(bodyParser.urlencoded({ extended: false }));
//View engine
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');
//Static Files
app.use(express.static(__dirname + '/Public'));
app.get('/', (req, res, next)=> {
return res.render('landing', {title: 'Home'})
});
app.get('/customer', (req, res, next)=> {
return res.render('signature', {title: 'Customer'})
});
app.get('/employee', (req, res, next)=> {
return res.render('signature', {title: 'Employee'})
});
app.post('/customer', (req, res, next)=>{
return res.render('entered', {title: 'Home'})
});
app.post('/employee', (req, res, next)=>{
return res.render('entered', {title: 'Home'})
});
app.listen(8080);
Folder Structure
Image of File Structure
Please let me know if I am not clear, first time posing on Stack
On nginx in your production server, you need to modify the sites_available file, to point to your static folder as default.
server {
root /www/data;
location / {
}
.....
}
please check attached link for serving static folder static nginx

Using Pug and expressjs routing, CSS wont display and image wont load, but the data is there [duplicate]

This question already has an answer here:
Resource was blocked due to MIME type mismatch using pug and node
(1 answer)
Closed 2 years ago.
This happens only when I use route.
./routes/users.js
const express = require('express');
const router = express.Router();
const dbQuery = require('../controllers/db_query');
router.get('/', async function(req, res) {
console.log('ROUTE - /');
const result = await dbQuery.getUsers();
res.render('users', {
data: result
});
});
router.get('/:id', async function(req, res) {
console.log('ROUTE - /id');
const result = await dbQuery.getUser(req.params.id);
console.log('result', result);
res.render('user', {
data: result
});
});
module.exports = router;
./App.js
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', indexRouter);
app.use('/users', usersRouter);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
next(createError(404));
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
./routes/users.js
const router = express.Router();
const dbQuery = require('../controllers/db_query');
router.get('/', async function(req, res) {
console.log('ROUTE - /');
const result = await dbQuery.getUsers();
res.render('users', {
data: result
});
});
router.get('/:id', async function(req, res) {
console.log('ROUTE - /id');
const result = await dbQuery.getUser(req.params.id);
console.log('result', result);
res.render('user', {
data: result
});
});
module.exports = router;
./views/users.pug
extends layout
block content
// Navigation
nav#mainNav.navbar.navbar-expand-lg.navbar-light.fixed-top
.container
a.navbar-brand.js-scroll-trigger(href='/') Node.js Excersise
button.navbar-toggler.navbar-toggler-right(type='button' data-toggle='collapse' data-target='#navbarResponsive' aria-controls='navbarResponsive' aria-expanded='false' aria-label='Toggle navigation')
| Menu
i.fas.fa-bars
// Masthead
header.masthead
.container.d-flex.h-100.align-items-center
.mx-auto.text-center
h1.mx-auto.my-0.text-uppercase Users List
h2.text-white-50.mx-auto.mt-2.mb-5 This is where you can find all the users.
// Projects
section#projects.projects-section.bg-light
.container
.col-md-10.col-lg-8.mx-auto.text-center
ul
each user in data
div(class='profile-tile')
img(class='img-rounded' src='images/profile/' + user.Uid + '.jpg' alt= user.Uid + ' image')
br
a(class='profile-name' href='/users/' + user.Uid)= user.Uname
li(style='list-style-type:none')= user.Uemail
// Contact
section.contact-section.bg-black
.container
.col-md-10.col-lg-8.mx-auto.text-center
button.btn.btn-primary.mx-auto(onclick="window.location.href='/'") Back
.social.d-flex.justify-content-center
a.mx-2(href='#!')
i.fab.fa-twitter
a.mx-2(href='#!')
i.fab.fa-facebook-f
a.mx-2(href='#!')
i.fab.fa-github
// Footer
footer.footer.bg-black.small.text-center.text-white-50
.container Copyright © : node.js.exercise 2020
// Bootstrap core JS
script(src='https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js')
script(src='javascript/bootstrap.bundle.min.js')
// Third party plugin JS
script(src='https://cdnjs.cloudflare.com/ajax/libs/jquery-easing/1.4.1/jquery.easing.min.js')
// Core theme JS
script(src='javascripts/scripts.js')
Below is my problem.
I tried to display the data I got from db and pass by route to render. (see h1 and img)
I have the result as expected, BUT the image(img) is not displaying and the CSS of the page.
by the way the code below is same with the ./views/users.pug, I did just display the data in simpler way.
./views/user.pug
extends layout
block content
nav#mainNav.navbar.navbar-expand-lg.navbar-light.fixed-top
.container
a.navbar-brand.js-scroll-trigger(href='/') Node.js Excersise
button.navbar-toggler.navbar-toggler-right(type='button' data-toggle='collapse' data-target='#navbarResponsive' aria-controls='navbarResponsive' aria-expanded='false' aria-label='Toggle navigation')
| Menu
i.fas.fa-bars
// Masthead
header.masthead
.container.d-flex.h-100.align-items-center
.mx-auto.text-center
h1.mx-auto.my-0.text-uppercase Users List
h2.text-white-50.mx-auto.mt-2.mb-5 This is where you can find all the users.
// Projects
section#projects.projects-section.bg-light
.container
.col-md-10.col-lg-8.mx-auto.text-center
div(class='profile-tile')
img(class='img-rounded' src='images/profile/' + data[0].Uid + '.jpg' alt='image')
h1= data[0].Uid
h1= data[0].Uname
h1= data[0].Uemail
// Contact
section.contact-section.bg-black
.container
.col-md-10.col-lg-8.mx-auto.text-center
button.btn.btn-primary.mx-auto(onclick="window.location.href='/'") Back
.social.d-flex.justify-content-center
a.mx-2(href='#!')
i.fab.fa-twitter
a.mx-2(href='#!')
i.fab.fa-facebook-f
a.mx-2(href='#!')
i.fab.fa-github
// Footer
footer.footer.bg-black.small.text-center.text-white-50
.container Copyright © : node.js.exercise 2020
// Bootstrap core JS
script(src='https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js')
script(src='javascript/bootstrap.bundle.min.js')
// Third party plugin JS
script(src='https://cdnjs.cloudflare.com/ajax/libs/jquery-easing/1.4.1/jquery.easing.min.js')
// Core theme JS
script(src='javascripts/scripts.js')
./views/layout.js
head
meta(charset='utf-8')
meta(name='viewport' content='width=device-width, initial-scale=1, shrink-to-fit=no')
meta(name='description' content='')
meta(name='author' content='')
title Node.js
link(rel='icon' type='image/x-icon' href='/images/favicon.ico')
// Font Awesome icons (free version)
script(src='https://use.fontawesome.com/releases/v5.13.0/js/all.js' crossorigin='anonymous')
// Google fonts
link(href='https://fonts.googleapis.com/css?family=Varela+Round' rel='stylesheet')
link(href='https://fonts.googleapis.com/css?family=Nunito:200,200i,300,300i,400,400i,600,600i,700,700i,800,800i,900,900i' rel='stylesheet')
// Core theme CSS (includes Bootstrap)
link(href='stylesheets/styles.css' rel='stylesheet')
body
block content
I'm trying to figure out why is it not rendering properly when i go to:
localhost/users/1
lastly, I notice that when i go to the route
localhost/users
i got the expected result. BUT if I place a '/' in the end
localhost/users/
I'll will have the problem above. No CSS and it's not reading my static defined in app for my images: app.use(express.static(path.join(__dirname, 'public')));
I'm 2 weeks in learning node.js, I'm trying to learn PUG with it now.
Thank you all in advance.
Manage to get the answers for this from my colleague(Thanks to Kevin).
The cause of the issue is, I did not place a '/' in from of my link(href='stylesheets/styles.css' rel='stylesheet') at ./views/layout.pug. This cause the browser to assume the path is relative to the document.
note: This can be checked in the browser's network debugging tab.
When I'm in localhost:port/users, the relative path would be okay since the current URL doesn't have '/'. so the stylesheet would work in URLs
localhost:port/users
localhost:port/edit
and so on...
stylesheet's relative path would be:
localhost:port/stylesheets/styles.css (which is correct)
BUT when this encounters a '/' in the path. the relative path will change base on its current location's/URL's path.
In that case.
e.g
localhost:port/users/
localhost:port/users/1
localhost:port/edit/abc
...
Stylesheet would now be relative to these paths above or document path:
localhost:port/users/stylesheets/styles.css (which is NOT correct)
FIX
If we place '/' at start, the browser will look for that page relative to the root of the website (referred to as an absolute URL).
I also got ideas from this issue:
https://github.com/pugjs/pug/issues/2662

Node.js Pug - CSS won't load on one specific page

Im building my first node.js app with express and pug as view/template eingine. A problem I am experiencing atm is the following:
Issue: Same CSS file loads on other routes & template.pugs but won't load on one specific route/template. Get a 404 error.
my server.js:
var express = require('express');
var path = require('path');
var app = express();
var bodyParser = require("body-parser");
app.set('views', './templates');
app.set('view engine', 'pug');
app.use(express.static(path.join(__dirname, './public')));
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
require('./router')(app);
var listener = app.listen(process.env.PORT, function() {
console.log('Server is live on PORT : ' + listener.address().port);
});
my router.js (css loads for "/" & "/events", not for /events/new"):
var controller = require ('./controller');
module.exports = function (app) {
//start
app.get('/', controller.index);
// All Events View
app.get('/events', controller.show_events);
app.get('/events/new', controller.new_event_form);
};
my controller.js (css loads for "index" & "show_events", not for "new_event_form" )
module.exports = {
index: index,
show_events: show_events,
new_event_form: new_event_form
};
function index (req, res) {
res.render('index');
}
function show_events(req, res) {
res.render('show_events');
};
function new_event_form(req, res) {
res.render('new_event_form');
};
Now comes the odd part. For this template "show_events.pug" it loads the css file. route: /events
doctype
html
head
title Database
link(rel='stylesheet', href='./css/main.css')
link(rel='stylesheet', href='https://fonts.googleapis.com/css?family=Roboto:400,400i,700')
body
div#wrapper
header
h1 Database: Events
menu
a(href='/')
h2 Back
a(href='/events/new')
h2 Create New Event
But for this template "new_event_form.pug" it won't load the css file. Route: /events/new
doctype
html
head
title Database
link(rel='stylesheet', href='./css/main.css')
link(rel='stylesheet', href='https://fonts.googleapis.com/css?family=Roboto:400,400i,700')
body
div#wrapper
header
h1 Event: New
menu
a(href='/events')
h2 Cancel
Css perfectly loads as well for the index "/" route.
Folder/file structure so far
controller.js
router.js
server.js
public
- - css
- - - - main.css
templates
- - index.pug
- - show_events.pug
- - new_event_form.pug
Kind find any mistake so far, don't get why it loads on the index route and the show_events route, but not on the new_event_form route.
Thanks for any hints or solution !
Update
when comparing the routes i noticed some differencies:
- for https://terminal.glitch.me/events the request adress for the css file is https://terminal.glitch.me/css/main.css
- for https://terminal.glitch.me/events/new the request adress for the css
file is https://terminal.glitch.me/events/css/main.css
So simple:
In the pug file for the events/new route the link ref should contain
2 dots before /css/main.css, not 1
So I changed this
link(rel='stylesheet', href='./css/main.css')
to this
link(rel='stylesheet', href='../css/main.css')
now it's working
It was just not clear for me how to use ../ this type of things for absolute paths ...

Express JS not rendering jade template

I'm going to keep this short, I'm just trying to render a jade template using express js.
I'm using express 3.0.0rc5 and jade 0.27.6.
Here's my jade templates, the layout:
// test-layout.jade
doctype 5
html
head
title My title
block head
body
#content
block content
And the index:
// test-index.jade
extends test-layout
block head
script(src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js")
block content
h1 My page
Here's some excerpts from app.js:
var app = express();
// Configuration
app.configure(function(){
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(app.router);
app.use(express.static(__dirname + '/public'));
});
app.get('/test-jade', function(req, res) {
res.render('test-index', {}, function(err, html) {
});
});
app.get('/test', function(req, res) {
res.send('this works');
});
Now whenever I try to go to http://myurl.com/test-jade the browser just hangs and timesout without showing any output in the console (even though I'm in dev mode).
However when I go to http://myurl.com/test I see 'this works'.
I feel like I'm missing something really simple here, I'm currently upgrading from 2.5 to 3.0.
Thanks in advance if anyone has advice.
Is it the blank call back?
res.render('test-index', {}, function(err, html) {
});
In my app I'm using
res.render('test-index', {});

Resources