Add custom view to jhipster app - jhipster

I would like to add a custom view to jhipster app on index.html
I already created the link in navbar.html and added the html file on path src/main/webapp/scripts/app/custom/newView.html
<a ui-sref="newView" data-toggle="collapse" data-target=".navbar-collapse.in">
<span class="glyphicon"></span>
<span class="hidden-sm">new view</span>
</a>
When I click on the link it doesn't work. Probably it needs a custom route in angular but I can't figure out how to create it. What else should I do?

In addition to the other answer, here is another piece of information. Maybe somebody else will find it useful. I had a similar problem with a custom view but only in production. Everything was fine in dev mode. In production mode, nothing would display and I had this javascript error that read "could not resolve ... from state ...".
It turns out that my javascript file (where the state was declared) was declared like this in index.html
<!-- build:js({.tmp,src/main/webapp}) scripts/app.js -->
<script src="scripts/app/app.js"></script>
<script src="scripts/app/app.constants.js"></script>
...
<!-- endbuild -->
<!-- custom -->
<script src="scripts/app/pages/quizz/quizz.js"></script>
<script src="scripts/app/pages/quizz/quizz.controller.js"></script>
I had created the separation on purpose, just to make it easier to read. Once I moved it up to have it before endbuild, the problem disappeared. I guess this is related to how the app is packaged somehow? I haven't looked at how it does it.

I've figured it out:
I had to add a angularjs route. Created a js file
src/main/webapp/scripts/app/custom/newv.js with the following content:
angular.module('jCrudApp')
.config(function ($stateProvider) {
$stateProvider
.state('newView', {
parent: 'site',
url: '/newView',
views: {
'content#': {
templateUrl: 'scripts/app/custom/newView.html',
//controller: 'MainController'
}
}
});
});
and import the new script in index.html
<script src="scripts/app/custom/newv.js"></script>

Related

Set up Pendo in Next.js

We're using Next.js 12 with SSR in our project. I've read through the Pendo documentation but I'm still not sure where to place the install snippet in our code, as Next.js doesn't provide an index.html file. We're using layouts however, is the top of the layout a good place to place Pendo?
I was trying to put the snippet as a function inside of the layout component's return, but it apparently doesn't work like this.
Thanks for any help!
Your _app.tsx should start with something like this and this will work:
function MyApp({ Component, pageProps }: AppProps) {
return (
<>
{/* Pendo Offsite MPA setup code snippet */}
<script
dangerouslySetInnerHTML={{
__html: `
(function(apiKey){
...
...
});
});`,
}}
/>
<sometag />
</>
);
}
Paste your Pendo script code as is into the placeholder above as a comment block.
The _app.js file works as index.js, the entry point for the whole application including every sub-page of it.

PouchDB and SvelteKit

I want to use PouchDB with SvelteKit. I have copied pouchdb-7.2.1.js to /src/libd in SvelteKit and renamed it to pouchdb.js. Pouchdb should run in the browser. Therefore I have used ssr=false to suppress server side rendering. I get the first error at the import statement. This is my first very short page (couchdb.svelte):
<script context="module">
export const ssr = false;
</script>
<script>
import PouchDB from '$lib/pouchdb.js';
</script>
I get an error 500
import not found: PouchDB
I have tried a lot of diffent version without any success. For example:
import PouchDB from 'pouchdb-browser'; (After npm i pouchdb-browser)
import PouchDB from 'pouchdb'; (After npm i pouchdb)
What is the correct way to use pouchdb?
Here is a work-around that uses PouchDB via a script tag:
index.svelte:
<script>
import { onMount } from 'svelte'
// Ensure execution only on the browser, after the pouchdb script has loaded.
onMount(async function() {
var db = new PouchDB('my_database');
console.log({PouchDB})
console.log({db})
});
</script>
<svelte:head>
<script src="//cdn.jsdelivr.net/npm/pouchdb#7.2.1/dist/pouchdb.min.js"></script>
</svelte:head>
When imported, PouchDB seems to expect a certain environment that Svelte/Vite/Rollup does not provide. (Svelte/Vite is happiest with proper ESM modules; PouchDB seems to be a "window.global" script that was converted to a JS module.)
There may be a way to modify the configuration to create the environment expected by PouchDB. I think you would have to modify the svelte.config.cjs file. (Specifically the vite section that determines the rollup configuration.)
You might find some hints in this related issue for PouchDB + Angular.
I would just use the <script> work-around above.
For future googlers trying to integrate pouchdb-browser and/or RxDB with sveltekit here are the changes to "fix" the enviornment for pouchdb in the browser when using vite.
Add to your <head> section before %svelte.head%
<script>
window.process = window.process || {env: {NODE_DEBUG:undefined, DEBUG:undefined}};
window.global = window;
</script>
In svelte.config.js add the optimizeDeps to config.kit.vite.optimizeDeps
optimizeDeps: {
allowNodeBuiltins: ['pouchdb-browser', 'pouchdb-utils', 'base64id', 'mime-types']
}
Here is a commit that makes these changes to my app:
https://github.com/TechplexEngineer/bionic-scouting/commit/d1c4a4dcdc7096ae40937501d97a7ef9ee10ab66
Thanks to:
pouchdb/pouchdb#8266 (comment)
I have been battling this very same problem for a while. I decided to go a different route. This may not be right, but it is working.
I added two scripts to my app.html head:
<head>
<meta charset="utf-8" />
<meta name="description" content="" />
<link rel="icon" href="%svelte.assets%/favicon.png" />
<meta name="viewport" content="width=device-width, initial-
scale=1" />
<!-- Call the Pouchdb import -->
<script type="text/javascript" src="../src/lib/pouchdb.js">
</script>
<!-- create new databases for use in the app -->
<script>
const user = new PouchDB('user');
</script>
%svelte.head%
</head>
Then in any component that I want to use the database, I add an additional script tag to define the variable "user":
<script lang="ts" context="module">
//Declare the database name so that it is recognized.
declare const user;
</script>
<script lang="ts">
//Example use of database.
const addUser = () => {
//Call the database by name established in app.html
user.put({
_id: 'someid',
firstName: 'Jon',
lastName: 'doe'
});
};
</script>
That has been the easiest method for me to employ PouchDB with SvelteKit. Every other solution required significant modifications to configuration files, changes to environment variables, and unnecessary adaptations of code throughout the application. I hope this helps.

How to include external .js file to ejs Node template page

I cannot find a way to include external .js file to Node ejs template. I want to put logic and data into object in external .js file, include that file to index.ejs template and pull data from it.
I tried by inserting standard way
<script src="sample.js"></script>, and it doesn't work
Then I tried ejs specific keyword <% include partials/sample.js %> and this works only for adding partials (ejs code snippets).
I inserted .js file into static directory which is defined in executable server.js, no results again.
But interestingly, including css file into ejs template classic way works fine, for example
<link href="/assets/styles.css" rel="stylesheet" type="text/css" />
Workaround would be to include external ejs file where I would put logic and data inside <% %> tags, but this is obviously a patch and not a viable solution, because ejs is not a js file. Besides, it doesn't work.
I cannot find any solution on Internet. Any hint?
Thanks
You can't.
Note: You can only pass data from .ejs file to .js file but not the other way. It won't work because .ejs is rendered on the server side while .js runs on the client side.
I am assuming you are using EJS on server side
1) You can pass an ejs variable value to a Javascript variable
<% var test = 101; %> // variable created by ejs
<script>
var getTest = <%= test %>; //var test is now assigned to getTest which will only work on browsers
console.log(getTest); // successfully prints 101 on browser
</script>
2) You can't pass a js variable value to a ejs variable
Yes, you can't: if it is on server.
Why:
The EJS template will be rendered on the server before the js is started execution(it will start on browser), so there is no way going back to server and ask for some previous changes on the page which is already sent to the browser.
A workaround with Express:
myScripts.js
module.export = {
foo() {},
bar() {}
}
Then in your app.js
var myScripts = require('/path/to/myScripts');
res.render('template', {
utils: myScripts
}); // you forgot a ')' here
then in your template.ejs
// utils will act in global scope for this file
<%
utils.foo();
utils.bar();
%>
I believe you are using it contrary to the intent.
In a controller you can define external scripts and styles you want to include like so
res.render('page-one', {
title: 'Page One',
data: pageData,
libs: ['page-one', 'utils'],
styles: ['page-one']
});
In your static assets for your app you have a js folder and a css folder
|- static/
|- css/
|- fonts/
|- img/
|- js/
favicon.ico
|- templates/
In your js folder you place the file page-one.js and utils.js
In your css folder you place the file page-one.css
In the head section of your html in the ejs template
<!-- styles included on all pages -->
<link rel="stylesheet" href="/css/bootstrap.css">
<!-- styles specific to individual pages -->
<% if (typeof styles !== 'undefined') { %>
<% if (styles.length > 0) { %>
<% for (let style of styles) { %>
<link rel="stylesheet" href="/css/<%= style %>.css">
<% } %>
<% } %>
<% } %>
Typically it is best practice to include scripts at closing body tag so they don't block page render so before the closing body tag in your ejs file
<!-- scripts included on all pages -->
<script src='/js/libs/jquery.min.js' type='text/javascript'></script>
<!-- page specific scripts -->
<% if (typeof libs !== 'undefined') { %>
<% for (let lib of libs) { %>
<script src='/js/<%= lib %>.js' type='text/javascript'></script>
<% } %>
<% } %>
</body>
When your page renders it will render the script and CSS includes automatically
The if block is in case you don't define any includes in the controller.
In your Express application you define your static and external script includes like so
Remember up above we created js and css folders inside a directory named static
// Define static assets
app.use(express.static('static'));
// included on all pages
app.use('/js/libs', express.static(path.join(process.cwd(), 'node_modules/jquery/dist'), { maxAge: 31557600000 }));
Finally, if you absolutely must include JavaScript in your template like rendering JSON data, etc. using special ejs tag <%- %>
<% if (jsonData) { %>
<script id="jsonData">var jsonData=<%- JSON.stringify(jsonData) %>;</script>
<% } %>
I was able to do that by:
serving the Js folder/file in the node app entry file like so:
app.use(express.static(path.join(__dirname, 'views/js')));
Added DOM functions in a index.js file which is in views/js folder.
Added script tag that links to the index.js file before the end body tag of index.ejs file like so:
<script scr="index.js" type="text/javascript"></script>
Note that the src in the script tag does not have "./js/index.js". I actually don't know why it works that way (same with external css stylesheet).
You can achieve it by adding the code below:
app.use(express.static(path.join(__dirname,public)));
You have to add a directory named public (or whatever you are naming) in your project folder. In that folder you can add your external JS file.
NB: the expression path.join is used to make the directory public available/accessible when you call/initiate app from outside the project folder.

YUI error: Uncaught ReferenceError: YUI is not defined

I am a jQuery user and just learning YUI. I have the following code and I keep the error that YUI is not defined. I know it is an issue with linking to the library but I'm not exactly sure what. I had someone else test my code where they had YUI held locally and it worked fine. If I need to do this, how do I obtain a copy of the min.js file? When you download a copy from the YUI site its a tonne of files...
<head>
<title>YUI3 Test</title
<script src="http://yui.yahooapis.com/3.2.0/build/yui/yui-min.js"></script>
</head>
<body>
<div id="menu">
<p>Click here to test.</p>
</div>
<script>
YUI().use('node', 'event', function (Y){
var changeText = function(e){
e.target.setHTML("<p>Now you see the test working.</p>");
}
var node = Y.one("#menu");
node.on("click", changeText);
//node.on("click", function(e){
// Y.one(node).load('menu.html');
//});
});
</script>
</body>
Thanks!
You're missing a > after </title. This may be causing the script tag not to be recognized and so it's not loading.
Here it is broken: http://jsbin.com/ubaxoy/1/edit
And here it works after adding the missing >: http://jsbin.com/ubaxoy/2/edit
I also had to change setHTML to setContent because YUI 3.2 didn't have setHTML yet. I'd also recommend you to use a newer version of YUI, from 3.9.1 up. There have been a number of great additions since 3.2.

Chrome Extension: Using addEventListener()

In the tutorial for migrating a Google Chrome Extension to Manifest Version 2, I am directed to Remove inline event handlers (like onclick, etc) from the HTML code, move them into an external JS file and use addEventListener() instead.
OK, I currently have a background.html page that looks like this…
<html>
<script type="text/javascript">
// Lots of script code here, snipped
…
</script>
<body onload="checkInMyNPAPIPlugin('pluginId');">
<object type="application/x-mynpapiplugin" id="pluginId">
</body>
</html>
Following another directive, I've moved that Lots of script code into a separate .js file, and following this directive, I need to remove the onload= from the body tag, and instead cal addEventListener() in my script code. I've tried several approaches, but am apparently guessing wrong. What will that code look like? In particular, upon what object do I invoke addEventListener()?
Thanks!
I normally use this for body onload event...
document.addEventListener('DOMContentLoaded', function () {
// My code here.. ( Your code here )
});
For somethings it is working.. but really, I think we should use..
window.addEventListener('load', function () {
document.getElementById("#Our_DOM_Element").addEventListener('change - or - click..', function(){
// code..
});
});

Resources