document is not defined Node.js - javascript

I have a small e-commerce project where i am trying to build cart
I am using the following stack Node.js, Express.js, Ejs(templating)
The issue is I have 2 js Files
Index.js (the main controller file for node js)
showProducts.js (Normal Js File)
So Basically i want to export a function or module from show Products.js file to call it in index.js. The error i am getting is document is not defined.
I am a newbie on Node js. I have roughly looked into Browserify and JSDOM but i am confused are those the Solution to the problem.
I have been stuck onto this problem since 2 days please help.
// Index.js File the Controller
const express = require("express");
const app = express();
const mysql = require("mysql");
const bodyParser = require("body-parser");
const fileUpload = require("express-fileupload");
const uuid = require("uuid");
const kam = require("./public/js/showProducts"); // I am requring it here
kam(); // calling the function
//Showproducts Normal Js file
function kam() {
console.log("kamran is the best in the world");
}
module.exports = kam;
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<!-- Latest compiled and minified CSS -->
<link
rel="stylesheet"
href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css"
/>
<!-- jQuery library -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-3-typeahead/4.0.2/bootstrap3-typeahead.min.js"></script>
<!-- Popper JS -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
<!-- Latest compiled JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="scss/all.css" />
<title>Products</title>
</head>
<style>
.product-box li {
float: left;
list-style-type: none;
width: 300px;
border: 1px solid rgba(0, 0, 0, 0.2);
padding: 10px;
text-align: center;
}
.filter-cat {
display: none;
}
.show {
display: block;
}
/* Add a light grey background on mouse-over */
.btn:hover {
background-color: #ddd;
}
/* Add a dark background to the active button */
.btn.active {
background-color: #666;
color: white;
outline: 0;
box-shadow: none;
}
.bag-btn {
background: black;
color: white;
border: transparent;
padding: 5px 10px;
}
</style>
<body>
<nav class="navbar navbar-expand-sm bg-dark navbar-dark">
<div class="container">
<div class="row">
<div class="col-3">
<!-- Brand -->
<a class="navbar-brand" href="#">Kamran</a>
</div>
<!-- Links -->
<div class="col-9">
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link" href="/">Home </a>
</li>
<li class="nav-item">
<a class="nav-link" href="products">Products</a>
</li>
<li class="nav-item">
<a class="nav-link" href="cart"
>Cart <span class="badge"></span
></a>
</li>
<button>
<a style="float: right;" href="addProducts">Backend </a>
</button>
</ul>
</div>
</div>
</div>
</nav>
<div class="space-50"></div>
<div class="container">
<h1>Our Products</h1>
<div class="space-50"></div>
<div class="search-bar text-center">
<input
type="text"
id="search-bar"
placeholder="Search Products"
onkeyup="searchProducts()"
/>
</div>
<div class="space-30"></div>
<div id="myBtnContainer" class="text-center">
<button class="btn active" onclick="filterSelection('all')">
All Products
</button>
<button class="btn" onclick="filterSelection('cable')">Cables</button>
<button class="btn" onclick="filterSelection('charger')">
Car Charger
</button>
<button class="btn" onclick="filterSelection('powerbank')">
Power Bank
</button>
<button class="btn" onclick="filterSelection('glass')">
Tempered Glass
</button>
</div>
<div class="space-50"></div>
<div class="products-area">
<div class="row">
<% for (var i = 0; i < data.length; i++) { %>
<ul class="product-box text-center filter-cat">
<li class="single-product">
<p><%= data[i].id %></p>
<img src="<%= data[i].productImage %>" width="50%" />
<h3><%= data[i].productName %></h3>
<h4>Rs. <%= data[i].productPrice %></h4>
<div class="space-20"></div>
<button class="bag-btn" onclick="addCart();">Add To Bag</button>
</li>
</ul>
<% } %>
</div>
</div>
</div>
<script src="./js/showProducts.js"></script>
</body>
</html>

The issue is document is not available in node.js environment. You have 2 options to solve this issue.
Option 1. Create 2 files
Create a file for server side part (for nodejs) and another file for client side (and access document here). You can include second file in your html file.
Option 2. Split node.js part of the file
You can check if the file is running on server side and run specific code here. Here's an example:
const isNode = typeof window === 'undefined';
if (isNode) {
function kam() {
console.log("kamran is the best in the world");
}
// Note that module.exports is not available on browser js
module.exports = kam;
} else {
function filterSelection() {
document.doSomething();
}
}
Conclusion
I prefer to place server side and client side code in different files (1st option) because it will make its easy to maintain code, also it will not leak server-side code to clients (users will not able to view server code by using developer tools).

Related

How to get information id of outer container from event listener set on inner list items

I am trying to learn about javascript so this might be quite a noob question. I would appreciate if someone with more experience could see what I am attempting and correct any problems I have with the approach, so if this looks weird please let me know!
I have a side navigation bar that divides into different groups. Within each group there is an ul that contains some li, which themselves contain an a with two p tags nested. The reason for this nesting is that I want to have each side nav "button" look like it has a label (the first p) on the left and a number (the second p) on the right (like a number of notifications or something).
I want to add an event listener to each li.nav-task-list so that if that li or any of its descendants is clicked then it selects that li and gives access to the "group" that it belongs to (defined by the id in the div that is the grandparent to the selected li). I had problems with this because the e.target in the click event would return any of the li, a, or p elements.
I have pasted my solution and it seems to do what I want. But the problem is that this took a lot of effort and testing compared to the examples of event listeners that I was reading from, and this makes me think I have either misunderstood something or overcomplicated it somehow. This also seems like such a common thing to do, so I want to know if I have overlooked something.
Here is my code:
const sideBar = document.getElementById('sidebar');
const navTaskLists = document.getElementsByClassName('nav-task-list');
Array.from(navTaskLists).forEach(function(e) {
e.addEventListener('click', function() {
console.log(e.querySelector('p.label').innerText);
if (e.classList.contains('active')) {
return;
}
removeAllActive(navTaskLists);
let parentLi = e.closest('li.nav-task-list')
parentLi.classList.toggle('active');
let parentGroup = e.closest('div.nav-task-list-group')
if (parentGroup.id != '') {
console.log(`clicked in the ${parentGroup.id} group.`)
}
});
})
function removeAllActive(elements) {
// Loops over all elements and removes active class
Array.from(elements).forEach(function(e) {
e.classList.remove('active');
})
}
#sidebar {
min-width: 300px;
max-width: 300px;
}
.nav-group-header {
cursor: pointer;
}
.nav-task-list:hover {
background-color: #eee;
}
.nav-task-list.active {
background-color: #bed;
}
<!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">
<!-- Bootstrap CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.2.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-Zenh87qX5JnK2Jl0vWa8Ck2rdkQ2Bzep5IDxbcnCeuOxjzrPF/et3URy9Bv1WTRi" crossorigin="anonymous">
<!-- Fontawesome -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.0/css/all.min.css" integrity="sha512-xh6O/CkQoPOWDdYTDqeRdPCVd1SpvCA9XXcUnZS2FmJNp1coAFzvtCN9BmamE+4aHK8yyUHUSCcJHgXloTyT2A==" crossorigin="anonymous" referrerpolicy="no-referrer"
/>
<title>Document</title>
</head>
<body>
<div class="container-fluid">
<div class="row">
<div class="col border" id="sidebar">
<div class="nav-task-list-group" id="group-one">
<ul class="nav flex-column">
<li class="nav-item nav-task-list">
<a class="nav-link flex-grow-1 d-flex" href="#" id="today-task-list">
<p class="flex-grow-1 mb-0 label">G1 Item 1</p>
<p class="num-tasks mb-0 fs-6">3</p>
</a>
</li>
<li class="nav-item nav-task-list">
<a class="nav-link flex-grow-1 d-flex" href="#" id="upcoming-task-list">
<p class="flex-grow-1 mb-0 label">G1 Item 2</p>
<p class="num-tasks mb-0 fs-6">21</p>
</a>
</li>
</ul>
</div>
<hr>
<div class="nav-task-list-group" id="group-two">
<ul class="nav flex-column">
<li class="nav-item nav-task-list">
<a class="nav-link flex-grow-1 d-flex" href="#" id="today-task-list">
<p class="flex-grow-1 mb-0 label">G2 Item 1</p>
<p class="num-tasks mb-0 fs-6">3</p>
</a>
</li>
<li class="nav-item nav-task-list">
<a class="nav-link flex-grow-1 d-flex" href="#" id="upcoming-task-list">
<p class="flex-grow-1 mb-0 label">G2 Item 2</p>
<p class="num-tasks mb-0 fs-6">21</p>
</a>
</li>
</ul>
</div>
</div>
<div class="col border">
Stuff
</div>
</div>
</div>
<!-- JavaScript Bundle with Popper -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.2.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-OERcA2EqjJCMA+/3y+gxIOqMEjwtxJY7qPCqsdltbNJuaOe923+mo//f6V8Qbsw3" crossorigin="anonymous"></script>
</body>
</html>

Can't save an API as an object

NETWORK TABWith the code I have I want the console log to pass 6983839 to the console but it stays empty the whole time and the page refreshes. The endpoint of the API is here. The function is executed by a button press which I'm 99% sure isnt the issue as it works when a change the function to do something else and I have jQuery in my folder for the project aswell and linked in the html file. The code is my JS file is below,
function showCard() {
var cardName = document.getElementById('un').value;
var cardNameProper = cardName.replace(/\s/g,'');
$.getJSON("https://db.ygoprodeck.com/api/v7/cardinfo.php?name=Tornado%20Dragon", null, function(info){
var result = info["data"][0]["id"]
console.log(result)
})
}
Also including the HTML code incase its relevant
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="jquery-3.5.1.js"></script>
<script type="text/javascript" src="javascript.js"></script>
<style>
.title{
color: white;
}
.cardSearch{
text-color: white;
}
#searchBox{
margin-right: 20px;
}
#chosenCard{
width: 177px;
height: 254px;
}
</style>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
</head>
<body>
<div class="container">
<div id="header-img" class="container-fluid">
<div class="card card-body bg-dark">
<div class="rows">
<div class="col-ms-8">
<img src="yugioh.png" class = "img-responsive mx-auto d-block"/>
</div>
<div class="col-ms-4 text-center">
<h4 class="title">Combo Builder</h4>
<div id="searchBox">
<form id="cardSearch">
<input type="text" size="12" id="un" />
<input type="submit" onclick="showCard();" value="Submit Card"/>
</form>
<img id="chosenCard" scr="cardBack.jpg">
</div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>

Open HTML file in same Chrome app window?

Aloha,
I am trying to a make a Chrome App that replaces the Chrome Dev Editor. Here is what I have currently:
background.js
chrome.app.runtime.onLaunched.addListener(function() {
chrome.app.window.create('backstage.html', {
'outerBounds': {
'width': 1036,
'height': 583
}
});
});
backstage.html
<!DOCTYPE html>
<html>
<head>
<title>Celestia Pro</title>
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
<link rel = "stylesheet" href = "material.css">
<link rel = "stylesheet" href = "material.min.css">
<link rel = "stylesheet" href = "styles.css">
</head>
<body>
<!-- The drawer is always open in large screens. The header is always shown,
even in small screens. -->
<div class="mdl-layout mdl-js-layout mdl-layout--fixed-drawer
mdl-layout--fixed-header">
<header class="mdl-layout__header">
<div class="mdl-layout__header-row">
<div class="mdl-layout-spacer"></div>
<div class="mdl-textfield mdl-js-textfield mdl-textfield--expandable
mdl-textfield--floating-label mdl-textfield--align-right">
<label class="mdl-button mdl-js-button mdl-button--icon"
for="fixed-header-drawer-exp">
<i class="material-icons">search</i>
</label>
<div class="mdl-textfield__expandable-holder">
<input class="mdl-textfield__input" type="text" name="sample"
id="fixed-header-drawer-exp">
</div>
</div>
</div>
</header>
<div class="mdl-layout__drawer">
<span class="mdl-layout-title">Title</span>
<nav class="mdl-navigation">
<a class="mdl-navigation__link" href="">Link</a>
<a class="mdl-navigation__link" href="">Link</a>
<a class="mdl-navigation__link" href="">Link</a>
<a class="mdl-navigation__link" href="">Link</a>
</nav>
</div>
<main class="mdl-layout__content">
<div class="page-content">
<style>
.demo-card-wide.mdl-card {
width: 100%;
}
.demo-card-wide > .mdl-card__title {
color: #fff;
height: 176px;
background: url('welcome-card.jpg') center / cover;
}
.demo-card-wide > .mdl-card__menu {
color: #fff;
}
div.start-cards {
padding-top: 25px;
padding-left: 50px;
padding-right: 50px;
}
</style>
<div class="start-cards" align = center>
<div class="demo-card-wide mdl-card mdl-shadow--2dp">
<div class="mdl-card__title">
<h2 class="mdl-card__title-text">Welcome to Celestia Pro</h2>
</div>
<div class="mdl-card__supporting-text">
Celestia Pro is a new integrated development environment (IDE) that allows developers to create Chrome apps quickly and efficiently. We're still in our baby stages, but we hope this tool works for you.
</div>
<div class="mdl-card__actions mdl-card--border">
<a class="mdl-button mdl-button--colored mdl-js-button mdl-js-ripple-effect" onclick="runWizard()">
Get Started
</a>
<script>
</script>
</div>
</button>
</div>
</div>
</div>
</main>
</div>
</div>
<script src = "./material.min.js">
<script src = "./material.js">
</body>
</html>
This seems all fine and dandy until I try to make the Get Started button I mention actually open something. I want it to open a page called 'backstage2.html', but no matter what combination I try, it doesn't seem to work. Here is what I have tried.
The <a href=""> method
Using the chrome.app.window.current and/or chrome.app.window.create script by adding a script to the button ("runWizard()")
None of these seem to work. I want to be able to open backstage2.html in the same Chrome app windows! How can I do this, if it is even possible? Any help is extremely appreciated.
You may want to use web components and import the file in your main file. Then you can use it as regular web component.
Other option is to send the request to the background page where you can hold a reference to opened window. This reference has contentWindow property which is a JavaScript's window object. You can use it to replace the content of man window (after you read new file data using e.g. fetch).
You may use webview into backstage.html (or in a new window).
Could be...
backstage.html:
<a id="wizard" class="···">Get Started</a>
<!-- onclick doesn't work by CSP (see note bellow) ··· -->
<webview></webview>
<!-- ··· -->
<script src="./main.js"></script>
main.js:
onload = function {
// ···
document.querySelector('#wizard').addEventListener('click', runWizard);
// ···
};
// ···
function runWizard() {
// ···
document.querySelector('webview').src = 'backstage2.html';
// ···
};
CSP -Content Security Policy-, note:
"You can’t use inline scripting..."
#abarisone: Thanks!
Use href ="your html file" target = "_self"

Laravel 5 : JQuery error

I'm Having a problem with a JQuery I pass the links like:
<link href="{{asset('plugins/archivos_admin/bjqs-1.js')}}">
<link href="{{asset('plugins/archivos_admin/organictabs.js')}}">
them I make the script:
<script>
$(function() {
$("#example-one").organicTabs();
$("#example-two").organicTabs({
"speed": 200
});
});
</script>
and I used in the index.blade.php:
<div id="example-one" align="center"> <-- It's called here.
<ul class="nav">
<!--
<li class="fecha-nav">
<span class="tit_fecha_num" align="center"> 22 </span>
<span class="tit_fecha" align="center"> DE OCTUBRE DE 2015 </span>
</li>
-->
<li class="espacio-nav"> </li>
<li class="nav-one">MAÑANA</li>
<li class="nav-two"><a href="#tarde" class="current" >TARDE</a></li>
<li class="nav-three">NOCHE</li>
</ul>
<div id="prueba" align="center">
<div class="list-wrap" align="center">
<ul style="position: relative; top: 0px; left: 0px; display: none;" id="manana" >
</ul>
<ul id="tarde">
</ul>
<!--- noche -->
<ul style="position: relative; top: 0px; left: 0px; display: none;" id="noche" >
<!---->
</ul>
</div> <!-- END List Wrap -->
</div> <!-- prueba -->
</div> <!-- END Organic Tabs (Example One) -->
It didn't work and it show me in the browser this error:
Uncaught TypeError: $(...).organicTabs is not a function
Any idea who can i fix this problem.
Script files (.js files) can't be loaded by the browser when called by a <link> tag, for this you need to use the <script> tag like so:
<script src="{{asset('plugins/archivos_admin/bjqs-1.js')}}"></script>
<script src="{{asset('plugins/archivos_admin/organictabs.js')}}"></script>
In this answer on SO, it's being explained a bit more.
Using this should cause the error to disappear.
Hope this helps!
Apparently the system cannot find the JS file. So, try to change the calls to:
<script src="{{asset('/plugins/archivos_admin/bjqs-1.js')}}">
<script src="{{asset('/plugins/archivos_admin/organictabs.js')}}">
Check if the file is correctly found.

How to using different background when routes to different angular page

So, I am working angular project using yeoman angular-generator. I have a.png. I want this image to be the background for login page only. after I click the submit button then it will redirect to #/about.html and using body class as fullscreen background style. How can I do that?
Here’s my css:
body {
padding-top: 50px;
background-color: #EEF2F5;
font-family: 'Montserrat', sans-serif;
}
body2,
.body2 {
background: url(powercube-09.png);
background-repeat: no-repeat;
font-family: 'Montserrat', sans-serif;
}
Here’s my index.html:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width">
<!-- Place favicon.ico and apple-touch-icon.png in the root directory -->
<!-- build:css(.) styles/vendor.css -->
<!-- bower:css -->
<link rel="stylesheet" href="bower_components/bootstrap/dist/css/bootstrap.css" />
<!-- endbower -->
<!-- endbuild -->
<!-- build:css(.tmp) styles/main.css -->
<link rel="stylesheet" href="styles/dashboard.css">
<link rel="stylesheet" href="bower_components/font-awesome/css/font-awesome.css">
<!-- endbuild -->
</head>
<body ng-app="loginApp" class="body2">
<!--[if lte IE 8]>
<p class="browsehappy">You are using an <strong>outdated</strong> browser. Please upgrade your browser to improve your experience.</p>
<![endif]-->
<!-- Add your site or application content here -->
<div ng-view=“"></div>
Here’s my view/main.html:
<div class="row">
<div class="col-md-4"></div>
<div class="col-md-4"><br><br><br><br><br><br><br>
<div class="widget2 widget_tally_box">
<div class="x_panel" style="background:#edf1f4;">
<div class="x_content"><br>
<center>
<br><br>
<div class="col-md-12 form-group has-feedback">
<input type="text" class="form-control has-feedback-left" id="inputSuccess2" placeholder="Username">
<span class="fa fa-user form-control-feedback left" aria-hidden="true"></span>
</div>
<div class="col-md-12 form-group has-feedback">
<input type="password" class="form-control has-feedback-left"
id="inputSuccess2" placeholder="Password">
<span class="fa fa-lock form-control-feedback left" aria-hidden="true"></span>
</div>
<div class="col-md-12">
<a ng-href="#/about"><button type="submit" class="btn2 btn-success3"><h15>SIGN IN</h15></button></a><br>
</div>
<div class="col-md-12 form-group has-feedback"> <br/>
<h32><strong>Forgot your password?</strong></h32>
<div class="divider"></div>
<h32>Not on PowerCube? <strong>Get started here.</strong></h32>
</div>
</center>
</div>
</div>
</div>
</div>
<div class="col-md-4"></div>
</div>
Here’s my view/about.html:
<p>This is the about view.</p>
<div class="footer">
<div class="container">
<p><span class="glyphicon glyphicon-heart"></span> from the Yeoman team</p>
</div>
</div>
Add css at the end of view/main.html.
<style>
body {
padding-top: 50px;
background-color: #EEF2F5;
font-family: 'Montserrat', sans-serif;
}
body2,
.body2 {
background: url(powercube-09.png);
background-repeat: no-repeat;
font-family: 'Montserrat', sans-serif;
}
</style>
This style will effect to view/main.html.
Well first you would want to correct your css. 'body2' isn't a tag.
I'm not entirely sure where you want that 'body2' css class to appear, but deciding what class to apply based on the route you are on (this is pb what you want to do) can be done with controller logic:
main.controller('MainCtrl', function($scope, $location) {
$scope.getClass = function(path) {
if ($location.path().substr(0, path.length) == path) {
return "active";
} else {
return "";
}
}
});
Html code :
<ul class="nav nav-pills">
<li ng-class="getClass('/main')">Phone List
</li>
<li ng-class="getClass('/module1')">Phone details
</li>
<li ng-class="">Module 2
</li>
</ul>
Here is the wrking plunker code
http://plnkr.co/edit/16iOyo6dz5RBNI91AD28?p=preview
Do it with ng-style (or ng-class), add a controller to check when you are in login page or not and use a scope variable to change the style, example:
<div class="row" ng-controller="MainController>
<div class="col-md-4"></div>
<div class="col-md-4"><br><br><br><br><br><br><br>
<div class="widget2 widget_tally_box">
<div class="x_panel" ng-style="loginBackground">
MainController:
$scope.loginBackground = null;
If (islogin) {
$scope.loginBackground = "background:#edf1f4;"
}
Use the following css to set background image to the largest div of the routed homepage. It might be easier to simply include it in the HTML rather than separating it. Once other pages are loaded, the background-image will return to the default.
#bigDiv {
background-image: url("paper.gif");
background-color: #cccccc;
}
I encounter this issue yesterday and turn out with this solution, not so smart but it's working.
+ Assign each page with custom directive: changebg
+ Name the body in index.html with a id (#example)
+ Now hook up angular body and change background style.
angular.module('app').directive('changebg',function(){
return{
restrict:'C',
controller:'changebgctrl'
}
}).controller('changebgctrl',changebgctrl);
changebgctrl.$inject =['$location','$scope'];
function changebgctrl($location,$scope){
angular.element("#example").removeClass(); // remove any class exist
angular.element("#example").addClass("whitebody");
}
You can give directive a data if you want to use this directive multiple time across pages, or try modify .css() if you don't want .addClass()

Categories

Resources