react onSubmit not working using react + express - node.js

My onSubmit function is not working with a website I made using a bootstrap template, specifically this one https://wrapbootstrap.com/theme/unify-responsive-website-template-WB0412697. It just refreshes the page, deleting whatever is in there. I have tried all combinations of the following:
Replacing onSubmit with onSuccess.
Moving my function inside the render before the return statement.
Adding parentheses to the handleSubmit function within the
Replacing e.preventDefault() with e.stopPropagation()
I am using nodejs, express and react, and am new to all 3.
I find it worth mentioning that I do not require('react-dom') nor use ReactDOM anywhere, which is weird to me because I always used it when I did the tutorials to learn react.
I believe I have read every similar problem on stack overflow, but nothing seems to be working. Here are my files in the order in which they are executed
app.js
var routes = require('./routes/index');
app.use('/', routes);
routes/index.js file
var express = require('express');
var router = express.Router();
router.get('/', function(req, res, next) {
res.render('index');
});
module.exports = router;
views/index.fsx jsx
var React = require('react');
var LoginForm = React.createClass({
getInitialState: function() {
return {username: '', password: ''};
},
handleUsernameChange: function(e) {
this.setState({username: e.target.value});
},
handlePasswordChange: function(e) {
this.setState({password: e.target.value});
},
handleSubmit: function(e) {
e.preventDefault();
},
success : function () {
alert('Success');
},
fail : function () {
alert('Fail');
},
render: function() {
return (
<form onSubmit={this.handleSubmit} className="loginForm">
<div className="input-group">
<input type="text" className="form-control" placeholder="Username" value={this.state.username} onChange={this.handleUsernameChange} required autofocus />
<input type="password" className="form-control" placeholder="Password" value={this.state.password} onChange={this.handlePasswordChange} required />
<button type="submit" className="btn-u btn-u-lg col-xs-12 col-sm-offset-5 col-md-offset-1 col-lg-offset-2">
Sign in <i className="fa fa-sign-in" />
</button>
</div>
</form>
);
}
});
var Welcome = React.createClass({
render: function() {
return (
<html>
<head>
<link rel='stylesheet' type='text/css' href='//fonts.googleapis.com/css?family=Open+Sans:400,300,600&subset=cyrillic,latin' />
<link rel="stylesheet" href="assets/plugins/bootstrap/css/bootstrap.min.css" />
<link rel="stylesheet" href="assets/css/style.css" />
<link rel="stylesheet" href="assets/css/headers/header-default.css" />
<link rel="stylesheet" href="assets/css/footers/footer-v1.css" />
<link rel="stylesheet" href="assets/plugins/line-icons/line-icons.css" />
<link rel="stylesheet" href="assets/plugins/font-awesome/css/font-awesome.min.css" />
<link rel="stylesheet" href="assets/plugins/sky-forms-pro/skyforms/css/sky-forms.css" />
<link rel="stylesheet" href="assets/plugins/sky-forms-pro/skyforms/custom/custom-sky-forms.css" />
<link rel="stylesheet" href="assets/css/pages/page_search.css" />
<link rel="stylesheet" href="assets/css/theme-colors/teal.css" id="style_color" />
<link rel="stylesheet" href="assets/css/theme-skins/dark.css" />
<link rel="stylesheet" href="assets/css/custom.css" />
<link rel="stylesheet" href="assets/css/homepage-style.css" />
</head>
<body>
<div>
<LoginForm />
</div>
<script type="text/javascript" src="assets/plugins/jquery/jquery.min.js" />
<script type="text/javascript" src="assets/plugins/jquery/jquery-migrate.min.js" />
<script type="text/javascript" src="assets/plugins/bootstrap/js/bootstrap.min.js" />
<script type="text/javascript" src="assets/plugins/back-to-top.js" />
</body>
</html>
);
}
});
module.exports = WelcomePage; // I'm not entirely sure what module.exports does

You need to change e.stopPropagation(); with e.preventDefault(); This will stop the page refresh.
Also,
stopPropagation stops the event from bubbling up the event chain.
preventDefault prevents the default action the browser makes on that event.
Move your html code in a separate file and render your app like the jsfiddle example that I created for you. https://jsfiddle.net/antony_z/7jLqxm2p/

Maybe try adding .bind(this) to this.handleSubmit, to have this.handleSubmit.bind(this)
Keep :
onSubmit
e.preventDefault()

I am attempting to answer my own question here because it was too long for a comment. But regarding your suggestion to put my HTML in it's own file...
My view engine is setup for jsx files. I am going to try what you did by doing this:
npm install consolidate
npm install swig
In app.js I will put:
var cons = require('consolidate');
at the top. Then for my view engine setup I will configure it like:
app.engine('html', cons.swig);
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'html');
So now how do I setup my routes/index.js file? I'm guessing it should be something like:
var express = require('express');
var router = express.Router();
router.get('/', function(req, res) {
res.render('index');
});
So now I will have to create views/index.html (rather than views/index.jsx like before). I inserted the HTML from your JSfiddle into the index.html file, but where do I put the code containing the LoginForm and ReactDOM stuff? I think I would be able to create a file in public/js/welcome-page.jsx and then include it at the bottom, but then other people can see my react code and onSubmit function, which is insecure right?

Related

Does Tailwind CSS work with express sendFile?

I am trying to send a html file through express but it is not able to include tailwindcss
I did all the set up correctly (at least that's what I think)
Is sendFile not capable of sending tailwindcss
This is the express setup
// express setup
const app = express();
const port = 9000;
app.use('/static', express.static('static'))
the endpoint
app.get("/", (req, res)=>{
res.sendFile(path.join(__dirname, "/template/home.html"))
});
html file
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Website</title>
<link rel="stylesheet" href="../static/output.css" />
</head>
<body>
<h1 class="text-sm">Doesn't Works</h1>
</body>
</html>
css file
#tailwind base;
#tailwind components;
#tailwind utilities;
tailwind config file
module.exports = {
content: ["*"],
theme: {
extend: {},
},
plugins: [],
}
and yes the path are correct it works with normal css but not with tailwindcss
I also don't want to use pug for it
Is there a way around it?
You can simple Use the Play CDN to try Tailwind right in the browser without any build step.
Add the Play CDN script tag to the <head> of your HTML file, and
start using Tailwind’s utility classes to style your content.
But remember :
The Play CDN is designed for development purposes only, and is not the
best choice for production.
<script src="https://cdn.tailwindcss.com"></script>
Folder & file structure :
app.js
const express = require("express");
const path = require("path");
const app = express();
const port = 9000;
app.use(express.static("./public"));
app.get("/", (req, res) => {
res.sendFile(path.join(__dirname, "/public/home.html"));
});
app.listen(port, () => {
console.log(`Server is listening at http://localhost:${port}`);
});
home.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script src="https://cdn.tailwindcss.com"></script>
<title>Express & TailwindCss</title>
</head>
<body>
<div class="flex items-center justify-center h-screen flex-col gap-5">
<h1 class="text-5xl font-bold underline text-green-500">
Express with TailwindCss
</h1>
<h3 class="text-blue-900 text-3xl font-bold">It does works! ;-)</h3>
</div>
</body>
</html>
Output :

How to redirect to a different Window in ElectronJS without a new Window

I have a question on how to redirect to a different page with ElectronJs.
The documentation only covered how to open a new window. But in my case, I do not wish to open a new window. This is what I've been trying so far but it's not responding:
login.js
const {BrowserWindow} = require('electron')
const loginBtn = document.getElementById('loginBtn')
loginBtn.addEventListener('click', () => {
let win = BrowserWindow
win.on('close', () => { win = null })
win.loadURL('file:///Users/cadellteng/Desktop/Timetrack/main_page.html')
win.show()
})
The above codes are modified from existing open a new page in a new browser window codes. I tried the following without much success too
loginBtn.addEventListener('click', () => {
window.location.href = 'main_page.html'
})
Hoping for someone to assist. I wasn't able to find helpful assistance on StackOverflow so I'm opening this thread, but if someone did indeed has asked this before, I'll be happy to delete this thread too. Just let me know. Thanks.
If you need to see my HTML, here it is:
login.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
<title>Timetrack</title>
<link rel="stylesheet" href="assets/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto">
<link rel="stylesheet" href="assets/fonts/fontawesome-all.min.css">
<link rel="stylesheet" href="assets/fonts/ionicons.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.5.2/animate.min.css">
<link rel="stylesheet" href="assets/css/Login-Form-Clean.css">
<link rel="stylesheet" href="assets/css/styles.css">
</head>
<body style="background-color: rgb(241,247,252);">
<nav class="navbar navbar-light navbar-expand-md" style="background-color: black;">
<div class="container-fluid"><a class="navbar-brand app-name" id="app-name" href="#" style="font-family: Roboto, sans-serif;width: 165px;color: white;"><b>Timetrack <sub>by Pyxel Inc</sub></b></a></div>
</nav>
<div class="flex-fill login-clean" style="background-size: auto;">
<form method="post">
<h2 class="sr-only">Login Form</h2>
<div class="illustration"><i class="icon ion-ios-clock"></i></div>
<div class="form-group"><input class="form-control" type="email" name="email" placeholder="Email"></div>
<div class="form-group"><input class="form-control" type="password" name="password" placeholder="Password"></div>
<div id="loginBtn" class="form-group"><button class="btn btn-primary btn-block" type="submit">Log In</button></div><a class="forgot" href="#">Forgot your email or password?</a></form>
</div>
<script src="assets/js/jquery.min.js"></script>
<script src="assets/bootstrap/js/bootstrap.min.js"></script>
<script src="login.js"></script>
</body>
</html>
You can use an electron.js file to setup the electron window and import in this file an app.js server with express. In this way you can use express for redirect to other page as a web application.
This is the electron.js file
const server = require('./app');
var path= require('path')
const { app, BrowserWindow } = require('electron')
var mainWindow
function createWindow() {
mainWindow = new BrowserWindow({
width: 1280,
height: 720,
icon: path.join(__dirname, 'public/img/icona-app.png'),
autoHideMenuBar: true,
useContentSize: true,
resizable: true,
webPreferences: {
devTools: false
}
});
mainWindow.loadURL('http://localhost:8080/');
}
app.on('ready', createWindow)
And this is the app.js file
var express = require('express')
var app = express()
app.listen(8080, function () {
console.log('Your application is listening on port 8080!')
})
app.get('/', function(req, res){
res.sendFile(__dirname + "/public/login.html");
})
module.exports=app
And then you must edit your package.json file
You must edit this two attributes:
"main": "electron.js",
"scripts": {
"start": "npm install && electron electron.js --no-sandbox"
},
To start the application write npm start

why my css not finding?

I have attached my css file to my html file. And then i run and open page using express in node js. However, the css file does not open when i run the webserver through node js.
html(show.ejs)
<html>
<head>
<link rel="stylesheet" type="text/css" href="assets/css/style.css" media="screen" />
</head>
<body>
<h1> Value is <%= detail %></h1>
</body>
</html>
node js
//required npm
var express = require('express');//express 4.*
var path = require('path');
// define app
var app = express();
// set up template engine
app.set('view engine', 'ejs');
//static files
//app.use('/static', express.static('/public')); //not working
app.use('', express.static(path.join(__dirname, 'public'))); //not working
//app.use(express.static(__dirname + '/public')); //not working
//app.use('/public/assets', express.static('public/assets')); //not working
app.get('/show/:id', function (req, res) {
res.render('./panel/show', {
detail: req.params.id ,
});
//port
app.listen(3000);
my project folder
node_modules
views
panel
show.ejs
public
assets
css
style.css
app.js
package.json
By entering <link rel="stylesheet" type="text/css" href="assets/css/style.css" media="screen" /> You are trying to find the assets folder in your out of public directory.
So, when you / it will find public directory which is statically defined in express server.
<html>
<head>
<link type="text/css" href="/assets/css/styles.css" rel="stylesheet">
</head>
<body>
<h1> Value is <%= detail %></h1>
</body>
</html>

Localhost test: can't get resource using http://localhost:8888

For test purposes I run Apache local web server and I'm setting up a node.js app listening on port 8888 serving as image preprocessor, but unfortunately I'm experiencing problems as described below.
The node app.js is running in the web root directory:
'use strict';
let express= require('express')
,multer = require('multer')
,upload = multer()
,app = express()
//Import imgProcessor module which we would implement later
,imgProc = require('./imgProcessor');
app.get ('/', (req, res, next)=>{
res.sendFile(__dirname+'/appmain.html');
});
app.post('/uploadImg', upload.array('pics'),
(req, res, next)=>{
//Call the convertImgs method and pass the image files as its argument
imgProc.convertImgs(req.files).then(
(imageStringArray)=>{
//After all image processing finished, send the base64 image string to client
res.json(imageStringArray)})});
app.listen(8888, ()=>{
console.log('Hosted on Port 8888')});
The appmain.html page resides in the same web root directory:
<html>
<head>
<title>Upload Image Demo</title>
<link rel="shortcut icon" href="">
<script src="node_modules/jquery/dist/jquery.min.js"></script>
<script src="node_modules/materialize-css/dist/js/materialize.min.js"></script>
<link rel="stylesheet" href="node_modules/materialize-css/dist/css/materialize.min.css">
</head>
<body class="container">
<div class="row">
<form id="form1" class="col m4 offset-m4" action="/uploadImg" enctype="multipart/form-data" method="post">
<div class="file-field input-field">
<div class="btn">
<span>File</span>
<input type="file" multiple="" accept="image/jpeg,png" name="pics">
</div>
<div class="file-path-wrapper">
<input class="file-path validate" type="text" placeholder="Upload one or more files">
</div>
</div>
<div class="input-field">
<button type="submit" class="waves-effect waves-light btn">Submit</button>
</div>
<div class="progress" style="display:none">
<div class="indeterminate"></div>
</div>
</form>
</div>
<div class="row img-preview"></div>
<script>
$(function(){
$('#form1').on('submit', function(event){
event.preventDefault();
var data = new FormData(this);
$.each(
$('input[name="pics"]')[0].files,
function(i, file){
data.append('file-'+i, file);
});
$('.progress').css({
display:'block'
});
$.ajax({
type:'POST',
url: $(this).attr('action'),
data:data,
cache:false,
contentType: false,
processData: false,
success:function(data){
for(var i=0;i<data.length;i++){
var template =
'<div class="col m4">
<div class="card">
<div class="card-image">
<img src="'
+ data[i]
+ '"></div></div></div>';
$('.img-preview').append(template);
}
$('.progress').css({
display:'none'
});
},
error: function(err){
$('.progress').css({
display:'none'
});
}
});
})
})
</script>
</body>
</html>
When I use the URL http://localhost:8888 in the browser the html page is loaded (i.e. I can see the buttons and input fields of the form) but the resources requested in the <script> (ex.: node_modules/jquery/dist/jquery.min.js or node_modules/materialize-css/dist/js/materialize.min.js) are not loaded. By the same way the page can't benefit from the unloaded CSS stylesheet.
As opposite, if I try to use the URL http://localhost/appmain.html the page is loaded as expected (I mean: with the correct resources and CSS).
It seems that my Apache Web Server can't serve resources when handling the port number inside the URL. How can I resolve this?
EDIT
Just to simplify: let'say the node app2.js is listening on port 8888 and it has just a method (get) that send to the client the 'Hello World!' page app2main.html. No files to serve. The app2main.html page need only to load a couple of Javascript script and a CSS stylesheet.
app2.js
'use strict';
let express= require('express')
,app = express();
app.get ('/', (req, res, next)=>{
res.sendFile(__dirname+'/app2main.html');
});
app.listen(8888, ()=>{
console.log('Hosted on Port 8888')});
app2main.html
<html>
<head>
<title>Upload Image Demo</title>
<link rel="shortcut icon" href="">
<script src="node_modules/jquery/dist/jquery.min.js"></script>
<script
src="node_modules/materialize-css/dist/js/materialize.min.js"></script>
<link rel="stylesheet"
href="node_modules/materialize-css/dist/css/materialize.min.css">
</head>
<body class="container">
<h2> Hello World! </h2>
</body>
</html>
When accessing the URL http://localhost:8888 the 'Hello World!' message appears, but I get the following error (visibile by inspecting the page):
http://localhost:8888/node_modules/jquery/dist/jquery.min.js Failed to load resource: the server responded with a status of 404 (Not Found)
http://localhost:8888/node_modules/materialize-css/dist/js/materialize.min.js Failed to load resource: the server responded with a status of 404 (Not Found)
http://localhost:8888/node_modules/materialize-css/dist/css/materialize.min.css Failed to load resource: the server responded with a status of 404 (Not Found)
http://localhost:8888/node_modules/materialize-css/dist/css/materialize.min.css Failed to load resource: the server responded with a status of 404 (Not Found)
Instead I get no error (and the expected style) when accessing the URL http://localhost/app2main.html
As discussed in comments, you should use express.static to serve static content in node.js app. In your case, your static content lies in node_modules directory itself. You can try the following code to load all resources,
e.g. http://localhost:8888/node_modules/jquery/dist/jquery.min.js
app.use('/node_modules', express.static('node_modules'));
Also, you mentioned that when you access http://localhost/app2main.html, then it worked without express.static, because apache web server to serve static files similar to express.static in node.js. That's why
http://localhost/node_modules/jquery/dist/jquery.min.js was working.
Hope it clears your doubt.

ExpressJS route not working?

I am using express with hoganjs templating instead of jade.
When I try to access one of my routes, it wont work though...
In app.js, I have the following (relevant to the route):
var awesome = require('./routes/awesome.js');
app.use('/awesome', awesome);
In the routes/awesome.js file, I have the following:
var express = require('express');
var router = express.Router();
/* GET awesome page. */
router.get('/awesome', function(req, res, next) {
res.render('awesome', { title: "awesome", message: "awesome"});
});
module.exports = router;
And lastly, here is my awesome template (located in ./views/awesome.hjs).
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{{title}}</title>
<meta name="Author" content="{{author}}"/>
<link rel="shortcut icon" href="" />
<!-- Bootstrap CSS-->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">
<!-- jQuery -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.2/jquery.min.js"></script>
<!-- Bootstrap JS -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js" integrity="sha384-0mSbJDEHialfmuBBQP6A4Qrprq5OVfW37PRR3j5ELqxss1yVqOtnepnHVP9aJ7xS" crossorigin="anonymous"></script>
</head>
<body>
<div class="container">
<div class="row">
<div class="col-xs-12">
<div class="jumbotron">
<h1>{{ title }}</h1>
<p>Welcome to {{ title }}, here is your message: {{message}}</p>
</div>
</div>
</div>
</div>
</body>
</html>
I have basically the same code for the index route so why wont this one work too?
In awesome.js change the router path location to /
router.get('/', function(req, res, next) {
res.render('awesome', { title: "awesome", message: "awesome"});
});
Now localhost:3000/awesome should be available.
app.use('/awesome', ...) matches all the routes starting with awesome. Paths specified in router.get('/awesome', ...) acts as sub-paths. The path URL will be localhost:3000/awesome/awesome.

Resources