Can I use seperate app.post requests for different divs on the same page? - node.js

I have a page with a sidebar that can change its function. Each different sidebar layout is a div. Two of the sidebars allow for text input. Right now I have one app.get statement that calls a handler that deals with all the sidebar layouts, but this solution is very messy. How would I go about splitting the different sidebars to work with different handler functions?
For example, I have this statement in app.js:
app.post('/', home.sidebarHandler);
sidebarHandler currently handles both logging in and registering as a new user, but I would like this to be done by two separate functions.
Here's part of my jade code, this is one of the divs:
form#sbCreateBox(method='post')
input.sbText(type='text', name= 'usernameReg', placeholder='Username', required)
input.sbText(type='text', name= 'acctHolderName', placeholder='Name')
input.sbText(type='email', name= 'useremail', placeholder='Email Address', required)
input.sbText(type='password', name= 'passwordReg', autocomplete='off', placeholder='Password', required)
input.sbText(type='password', name= 'passConfirm', autocomplete='off', placeholder='Confirm Password', required)
input#sbCreateButton(type='submit', value='Create Account')
How might I setup the routes to have separate app.post statements?

You could define two routes in your server side code:
app.post('/register', home.registerUser);
app.post('/login', home.loginUser);
And update your HTML to post to the correct URL (/register or /login) depending on the user's action.
EDIT
You can create two forms. One will post to /register and the other to /login (notice the action attribute on the form element):
Register Form
form#sbCreateBox(method='post' action='/register')
input.sbText(type='text', name= 'usernameReg', placeholder='Username', required)
input.sbText(type='text', name= 'acctHolderName', placeholder='Name')
input.sbText(type='email', name= 'useremail', placeholder='Email Address', required)
input.sbText(type='password', name= 'passwordReg', autocomplete='off', placeholder='Password', required)
input.sbText(type='password', name= 'passConfirm', autocomplete='off', placeholder='Confirm Password', required)
input#sbCreateButton(type='submit', value='Create Account')
Login Form
form#sbCreateBox(method='post' action='/login')
input.sbText(type='text', name= 'usernameReg', placeholder='Username', required)
input.sbText(type='password', name= 'passwordReg', autocomplete='off', placeholder='Password', required)
input#sbCreateButton(type='submit', value='Login')

Related

Node Express forwarding html

I was woundering how to forward user selected html (radios and checkboxes) that is posted by a user as is to a newly rendered website using nodejs
That means user selected radio buttons and checkboxes, as well as unselected buttons and radios would be as per user selection and with the html tags
Assuming you are using Express with Pug, here's an example.
form
input(type="checkbox" value="checked" name="checkbox" checked)
input(type="radio" value="checked" name="radio" checked)
input(type="submit", value="Submit")
When this form submits, the express handler will receive the form data, an example handler:
router.use(bodyParser().urlencoded({ extended: true }));
router.post('/form',(req,res) => {
//req.body: { checkbox: 'checked', radio: 'checked' }
res.render('anotherPage', {radio: req.body.radio, checkbox: req.body.checkbox});
})
Then in anotherPage.pug
form
input(type="checkbox" value="checked" name="checkbox" checked=checkbox)
input(type="radio" value="checked" name="radio" checked=radio)
input(type="submit", value="Submit")
This way, the data can be passed on to the anotherPage.pug while maintaining the fields from the original page. You can also do this with other input types, such as text, by simply taking their value and passing it to the pug renderer.

Resource was blocked due to MIME type mismatch using pug and node

I'm trying to render a view with an id in the url:
router.get('/employee', authController.protect, viewsController.getOverviewEmployee);
router.get('/employee/:id', authController.protect, viewsController.getOneEmployee);
The /employee works fine, but when I get to the /employee/:id page the css and scripts won't load and the console shows me this error:
The resource from
“http://127.0.0.1:3000/employee/lib/bootstrap/css/bootstrapmin.css”
was blocked due to MIME type (“application/json”) mismatch
(X-Content-Type-Options: nosniff).
this is my index.pug header:
doctype html
head
meta(charset='utf-8')
meta(name='viewport' content='width=device-width, initial-scale=1.0')
meta(name='description' content='')
meta(name='author' content='Dashboard')
meta(name='keyword' content='Dashboard, Bootstrap, Admin, Template, Theme, Responsive, Fluid, Retina')
title Admin
// Favicons
link(href='img/favicon.png' rel='icon')
link(href='img/apple-touch-icon.png' rel='apple-touch-icon')
// Bootstrap core CSS
link(href='lib/bootstrap/css/bootstrap.min.css' rel='stylesheet')
link(rel='stylesheet', type='text/css', href='lib/bootstrap-fileupload/bootstrap-fileupload.css')
// external css
link(href='lib/font-awesome/css/font-awesome.css' rel='stylesheet')
// Custom styles for this template
link(href='dashcss/style.css' rel='stylesheet')
link(href='dashcss/style-responsive.css' rel='stylesheet')
getOneEmployee:
exports.getOneEmployee = catchAsync(async (req, res, next) => {
const employee = await Employees.findById(req.params.id);
if (!employee) {
return next(new AppError('No document found with that ID', 404));
}
res.status(200).render('admin/employeeManager',{
title: 'Employee',
employee
});
});
and the employeeManager.pug
extends index
block content
section#container
MAIN CONTENT
// main content start
section#main-content
section.wrapper
h3
i.fa.fa-angle-right
| Editar Colaborador
.row.mt
.col-lg-12
h4
.form-panel
.form
form.cmxform.form-horizontal.style-form#commentForm(method='get' action)
.form-group
label.control-label.col-lg-2(for='cname') Nome*
.col-lg-10
input.form-control#cname(name='name' minlength='2' type='text' required)
.form-group
label.control-label.col-lg-2(for='cphone') Telefone*
.col-lg-10
input.form-control#cemail(type='cphone' name='phone' required)
.form-group
label.control-label.col-lg-2(for='cdescription') Descrição*
.col-lg-10
input.form-control#curl(type='description' name='description' required)
.form-group
label.control-label.col-lg-2(for='ccomment') Your Comment (required)
.col-lg-10
textarea.form-control#ccomment(name='comment' required)
.form-group
label.control-label.col-md-3 Image Upload
.col-md-9
.fileupload.fileupload-new(data-provides='fileupload')
.fileupload-new.thumbnail(style='width: 200px; height: 150px;')
img(src='http://www.placehold.it/200x150/EFEFEF/AAAAAA&text=no+image', alt='')
.fileupload-preview.fileupload-exists.thumbnail(style='max-width: 200px; max-height: 150px; line-height: 20px;')
div
span.btn.btn-theme02.btn-file
span.fileupload-new
i.fa.fa-paperclip
| Select image
span.fileupload-exists
i.fa.fa-undo
| Change
input.default(type='file')
a.btn.btn-theme04.fileupload-exists(href='', data-dismiss='fileupload')
i.fa.fa-trash-o
| Remove
span.label.label-info NOTE!
span
| Attached image thumbnail is
| supported in Latest Firefox, Chrome, Opera,
| Safari and Internet Explorer 10 only
.form-group
.col-lg-offset-2.col-lg-10
button.btn.btn-theme(type='submit') Salvar
|
button.btn.btn-theme04(type='button') Cancelar
This is because you are using relative url's in your attributes.
Replace this:
link(href='img/favicon.png' rel='icon')
With this:
link(href='/img/favicon.png' rel='icon')
To explain this further, when you are viewing /employee then the relative link at img/123.jpg is correctly resolved as /img/123.jpg. However, as soon as you go to the url /employee/joeblow then the relative link is looking for /employee/img/123.jpg. You'll be able to confirm this by opening Developer Tools in your browser then looking at the requests made in the Network tab.
Adding the slash at the front of all img elements will ensure that they look for the images in the correct folder, the one off the root (/).
The bootstrap mime-type error must be coming from one of the libraries that is loading correctly but not finding a dependency due to the issue described above.

Passport local - Cannot read property 'email' of undefined

I am using Passport in my app. When I render views to display user information, I'm able to display user information (I'm using jade, btw) in that view:
#user
p #{user.fname} #{user.lname)
However, that view extends a layout, and in that layout, I am not able to access the user variable. My end goal is to have the nav bar in the layout and display a few user related items. I know I could set variables in my blocks, but I don't want to have to set them in every single view (that seems far more repetitious than it should be, and seems like the wrong way to do things). How can I make my user information available to my layout that my views extend and do it in one place?
layout.jade
...
#user
if(user != null)
ul.nav.navbar-right.navbar-nav
li.dropdown
a.dropdown-toggle(href='#', data-toggle='dropdown') #{user.email} <--BREAKS HERE
...
user.jade
extends layout
...
#user
h1.title Welcome #{user.email} <--WORKS FINE HERE
...
layout.jade
block header
#user
if(user != null)
ul.nav.navbar-right.navbar-nav
li.dropdown
a.dropdown-toggle(href='#', data-toggle='dropdown') #{user.email}
block content
or
layout.jade
block header
#user
if(user != null)
ul.nav.navbar-right.navbar-nav
li.dropdown
a.dropdown-toggle(href='#', data-toggle='dropdown')
| #{user.email}
block content
user.jade
extends layout
block content
#user
h1.title Welcome #{user.email}

jade form does not seem to post

Folks,
The following code does not seem to have the form submitting properly. Please correct
block main
.container
form.form-signin(name='signin', action='/auth' method='post')
h2.form-signin-heading Please sign in
input.form-control(type='text', placeholder='Email address', autofocus='autofocus', id='username')
input.form-control(type='password', placeholder='Password', id='password')
label.checkbox
input(type='checkbox', value='remember-me')
| Remember me
button.btn.btn-lg.btn-primary.btn-block(type='submit') Sign in
Fixed, was not creating
.container
form.form-signin(action='/auth' method='post')
h2.form-signin-heading Please sign in
input.form-control(type='text', placeholder='Email address', autofocus='autofocus', name='username')
input.form-control(type='password', placeholder='Password', name='password')
label.checkbox
input(type='checkbox', value='remember-me')
| Remember me
button.btn.btn-lg.btn-primary.btn-block(type='submit',name='submit') Sign in

Show Activities Tab when clicking on a custom navigation link

I am working on a customisation for CRM 2011. I have created a custom entity (which is based on activity so is an activity type aswell), created the relationship to account and on the account form created a custom navigation link pointing to a web resource which will power the custom display (this is just a html page with JavaScript).
The Web resource is used instead of a standard relationship link because it is doing a listings and preview display and not just the list view that the out of the box feature provides.
What i am trying to do is show the activities tab (the activities ribbon tab) on the accounts form, whenever the custom navigation link is pressed and a user goes into that section, in the same way it displays when you click the activities navigation link. I can't seem to find that much information on Tab Display Rules as i think that is the place (if this is possible) that it should be done.
Also, if there is a JavaScript way of doing it (although i have not found any) then that would work as well.
We have a solution.
DISCLAIMER This solution is not recommended (or supported) as it is a complete hack of epic proportions, but it solved the issue for us. this is a temporary bit of functionality as we build out a custom solution which will better fit the client, so it will not be there moving forwards which is why the hack worked for us. Additionally, a scripts could be written much better, we simply wanted to get it out the door.
NOTE: This solution will use some external libraries such as JQuery & CRM FetchKit
1) Adding a relationship to the custom object and account
We have a custom entity, and we created a 1:N relationship from the Account entity to our custom entity. What this does enables us to do is create a navigation link on the account form which points to an associated view of our custom entity. Once the link is in, we save and publish changes.
2) Get the id of the new navigation link created
The link above should now be on the form, so after saving and publishing we go to the live view and using the IE developer tools we get the id of the link as we need to catch the onclick and do some things with it later.
3) Decorating the onclick of the navigation link created
We have the id so and we want to decorate the onclick with some additional functionality. We create 2 new web resources:
"YourCustomEntity"_init : Javascript Web Resource: this will be used in the onload of the account form to get the link we created and alter the onclick to do some additional things
YourCustomEntity_page : HTML Page Web Resource: As per the original question, we have a additional requirement of showing a preview pane which is why we couldn't use the standard grid
Code for "YourCustomEntity"_init
Code is pretty basic and doesn't have any object caching or the like it was simply written to solve our problem. I have added comments to the code. Also Entity is a generic name, this was the name of our custom type. We set the original associated view to hidden instead of display:none because we still need it to load in the background as this is where the ribbon gets updated and loads, so there is definitely some script going on to do this, wish we knew it so we could just use that :)
function previewEntityInit(){
//Catch any navigation link click, we need this because we need to hide our
//grid when we are not on the custom entity page
$('.ms-crm-Nav-Subarea-Link, .ms-crm-FormSelector-SubItem').click(function () {
//Get the id of the link clicked and the frame injected object
var id = $(this).attr('id'),
cFrame = $('#entity_frame_preview');
//if the frame has already been injected
if(cFrame.length !== 0) {
//If we are not in the correct section
//(i.e. activities nav link was clicked) hide it
if (id !== 'nav_new_account_new_entity') {
cFrame.attr('style', 'display:none;');
}
else{
//The correct link was clicked, so show it
cFrame.attr('style', 'display:block; width:100%; height:100%;');
$('#new_account_new_entityFrame').attr('style', 'visibility: hidden;');
}
}
else{
//This is the first time the correct link has been clicked
//So we hide the default associated view and inject our
//own iframe point to the YourCustomEntity_page embedded resource we created
var src = Xrm.Page.context.getServerUrl();
if (id === 'nav_new_account_new_entity') {
$('#new_account_new_entityFrame').attr('style', 'visibility: hidden;');
$('<iframe />', {
id: 'entity_frame_preview',
src: src + '/WebResources/new_entity_page',
width: '100%',
height: '100%'
}).prependTo('#tdAreas');
}
}
});
YourCustomEntity_page
Not going to show all the code here, but we based ours on this link:
Preview Form Link
We changed it in the following ways:
Only the view name is hardcodes, the rest is taken via code (code below)
We don't use the second iframe opting instead to have a simple HTML section which loaded this (code for this and our load function below)
No Hard Coded Values
var server = Xrm.Page.context.getServerUrl();
var orgName = "";
// grid related settings
var entityId = window.parent.Xrm.Page.data.entity.getId();
var entityType = "1";
var areaView = "new_account_new_entity";
var internalGridElement = "crmGrid_new_account_new_entity";
var timeoutKey = null;
HTML For Preview
<div id="previewForm" style="display: none;">
<ol>
<li><span class="lbl">Account:</span><span id="lblAccount"></span></li>
<li><span class="lbl">Created:</span><span id="lblDate"></span></li>
<li><span class="lbl">Regarding:</span><span id="lblRegarding"></span></li>
<li><span class="lbl">Owner:</span><span id="lblOwner"></span></li>
</ol>
<div id="subject">
<span class="lbl">Subject:</span><span id="lblSubject" class="value"></span>
</div>
<div>
<span id="lblMsg"></span>
</div>
</div>
LoadPreview Code
This uses an external library called CRMFetchKit. The code actually does three fetch calls, this is not ideal and it should be one really (using joins, google it :)), but this wasn't working and was dragging so we decided just to go with three as this whole section will be replaced with a managed solution soon.
function LoadPreviewPane(entity) {
if (entity != null) {
$('#previewForm').show();
var fetchxml = ['<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="false">',
' <entity name="new_entity">',
'<attribute name="subject" />',
'<attribute name="description" />',
'<attribute name="createdon" />',
'<attribute name="new_account" />',
'<attribute name="ownerid" />',
' <filter type="and">',
' <condition attribute="activityid" operator="eq" value="' + entity.Id + '" />',
' </filter>',
' </entity>',
'</fetch>'].join('');
CrmFetchKit.Fetch(fetchxml).then(function (results) {
var account = window.parent.Xrm.Page.getAttribute("name").getValue(),
subject = results[0].getValue('subject'),
desc = results[0].getValue('description'),
created = new Date(results[0].getValue('createdon')),
theDate = created.getDate() + "/" + (created.getMonth() + 1) + "/" + created.getFullYear(),
owner = '',
regarding = '';
var fetchxml2 = ['<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="false">',
' <entity name="systemuser">',
'<attribute name="fullname" />',
' <filter type="and">',
' <condition attribute="systemuserid" operator="eq" value="' + results[0].getValue('ownerid') + '" />',
' </filter>',
' </entity>',
'</fetch>'].join('');
CrmFetchKit.Fetch(fetchxml2).then(function (users) {
owner = users[0].getValue('fullname');
$('#lblOwner').html(owner);
});
var fetchxml3 = ['<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="false">',
' <entity name="account">',
'<attribute name="name" />',
' <filter type="and">',
' <condition attribute="accountid" operator="eq" value="' + results[0].getValue('new_accountname') + '" />',
' </filter>',
' </entity>',
'</fetch>'].join('');
CrmFetchKit.Fetch(fetchxml3).then(function (regardings) {
regarding = regardings[0].getValue('name');
$('#lblRegarding').html(regarding);
});
$('#lblAccount').html(account);
$('#lblSubject').html(subject);
$('#lblMsg').html(nl2br(desc));
$('#lblDate').html(theDate);
});
}
}

Resources