Why is my button function only providing output once? - javascript

I am experimenting with a basic VSCode extension webview. I am trying to get a simple button click to display a message whenever it is clicked, but the message is only appearing the first time. My HTML code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Module Manager</title>
<style> h1 {
position: fixed;
top: 50%;
left: 50%;
margin-top: -100px;
margin-left: -200px;}
</style>
</head>
<body style="background-color:rgb(60,99,201);">
<h1 style="color:white;">Welcome to the Lab Ticketing System</h1>
<button onclick="moduleAdd()">Click me</button>
<script>
function moduleAdd(){
const vscode = acquireVsCodeApi();
vscode.postMessage({command: "alert", text: "BUTTON PRESSED!"});
}
</script>
</body>
</html>
Then, the javascript code:
let newCommand = vscode.commands.registerCommand('ticketing.start', function () {
vscode.window.showInformationMessage("Activating ticketing system!")
// create webview
const modulePanel = vscode.window.createWebviewPanel('modManage', "Module Manager",
vscode.ViewColumn.One, {enableScripts: true}, );
// pull in the HTML content for the webview panel from external module
modulePanel.webview.html = htmlStuff.getWelcomeScreen();
// handle recieving messages from the webview
modulePanel.webview.onDidReceiveMessage(message =>
{switch(message.command){case 'alert': vscode.window.showErrorMessage(message.text);
return;}}, undefined, context.subscriptions);
});
context.subscriptions.push(disposable, newCommand);
I'm leaving out some code that manages the extension, since the webview displays correctly I think it's just an issue with how I'm implementing the button.

Only call acquireVsCodeApi() once, outside the functions that need it.

Related

How to take input from user in html and use that variable as .bg background url in css file

I have been working on this code where I need to take input from the user via HTML buttons and then assign that input URL of an image from the web to the .bg {background: URL('URL') } in my CSS file.
Is there some way I can do that?
.bg {
background: URL(' *user input image URL * ')
}
This is the project I have been originally working on, so I wanted the URL input from the user and then display the blurry loading post that using the input from the user
https://github.com/bradtraversy/50projects50days/tree/master/blurry-loading
So as you see here I am updating the background after 3 seconds. This will not change the css file but will change the css in real time. All you need to do is update what is stored in the background style portion of the element. You just need the link to the image. If you want to update permanently in the css there are 2 ways to go about it, keeping the css the same and changing the reference file or writing to the css file with a different script and reloading.
setTimeout(function () {
document.getElementById("bg").style.background ="URL('https://i.picsum.photos/id/866/200/300.jpg?hmac=rcadCENKh4rD6MAp6V_ma-AyWv641M4iiOpe1RyFHeI')";
}, 3000);
#bg {
color: blue;
background: URL('https://i.picsum.photos/id/237/200/300.jpg?hmac=TmmQSbShHz9CdQm0NkEjx1Dyh_Y984R9LpNrpvH2D_U');
height: 400px;
}
<div id="bg"></div>
I think you can do like this
function setImage() {
const input_from_user = document.getElementById("input_from_user");
const image_url = input_from_user.value;
const bg_container = document.getElementsByClassName("bg")[0];
bg_container.style.backgroundImage = `url(${image_url})`;
}
.bg {
width: 400px;
height: 200px;
background-repeat: no-repeat;
background-size: contain;
background-position: center center;
}
<!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>Document</title>
</head>
<body>
<div class="bg"></div>
<input type="url" id="input_from_user" />
<button onclick="setImage()">Set Image</button>
</body>
</html>
Can try with this image: https://www.google.nl/images/srpr/logo3w.png
Hope this can help.

Writing a boolean expression to solve

While working through the application process for a bootcamp, I was tasked with the following JS problem which is above my head. I was successful in testing through the JS console on Chrome but when I attempt to plug the code into the .js file, it does not work. Do I need to apply a boolean expression? If so, what is the best way of coding it?
Here is everything that is in the .js file:
document.addEventListener("DOMContentLoaded", function(event) {
var thumbnailElement = document.getElementById("smart_thumbnail");
thumbnailElement.addEventListener("click", function() {
// write here
});
});
Here is the problem that is at hand:
"To make the image bigger or smaller, you have to change its class. In your JavaScript console, run this code:
var thumbnailElement = document.getElementById("smart_thumbnail");
thumbnailElement.className; This displays what the class currently is; it
should be
"small", unless you changed it since.'
To make it big, you should remove the class, by running this:
thumbnailElement.className = ""; To make it small again, you can put it back:
thumbnailElement.className = "small";'
See how it changes from small to big? You should put the line that makes it big in your JavaScript file so that it executes when the user clicks."
You could use the HTMLElement.classList.toggle method to add or remove the class. Here is a small snippet that illustrates how you can do it.
<style>
.small {
transform: scale(0.5);
}
</style>
<button class="small" id="smart_thumbnail">Click me</button>
<script>
document.addEventListener("DOMContentLoaded", function (event) {
// Get the element by id
var thumbnailElement = document.getElementById("smart_thumbnail");
// add the event listener on the element
thumbnailElement.addEventListener("click", function () {
thumbnailElement.classList.toggle("small");
/*
HTMLElement.classList.toggle(className) will remove the class if it is in the class list OR add it if it is not already there.
*/
});
});
</script>
If you simply want to remove it, you can use the remove method instead.
thumbnailElement.classList.remove("small");
if you have the css of the elment in the id and changing its size by class then it will not work here is the code that I wrote to solve
<!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>Answer</title>
<style>
.small{
width: 10%;
height: 10%;
transition: all 1s ease;
}
.notSmall{
width: 30%;
height: 30%;
transition: all 1s ease;
}
</style>
</head>
<body>
<img src="Your Image" class="small" id="smart_thumbnail" alt="The image">
<script>
document.addEventListener("DOMContentLoaded", () => {
let thumbnailElement = document.getElementById("smart_thumbnail");
thumbnailElement.addEventListener("click", function() {
if(thumbnailElement.classList == "small"){
thumbnailElement.classList.remove('small');
thumbnailElement.classList.add('notSmall');
console.log('now image is big')
}else{
thumbnailElement.classList.add('small');
thumbnailElement.classList.remove('notSmall');
console.log('now image is small')
}
});
});
</script>
</body>
</html>

Is there a way to refresh a webpage from inside a Mozilla Firefox extension

I am currently working on developing a Mozilla Firefox extension that blocks ads to learn more JavaScript, HTML, and CSS. Within the extension of that popup, I want to be able to click a button and refresh whatever page the browser is currently on. I have the buttons developed, and are currently interactive, but I am failing to see how I can extend the scope from the HTML I am using to see the webpage the browser is on.
Here is the most simplified state I have working:
popup.html
<!doctype html>
<hmtl>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<style>
body {
padding: 1em;
}
input {
margin-left: 1em;
margin-right: 1em;
}
</style>
</head>
<form>
<input type="button" value="Refresh">
<button onClick="document.location.href=window.location.href">Refresh Window</button>
<button onClick="document.location.href = 'popup.html' + '?' + Date.parse(new Date());">Refresh Page</button>
</form>
<p>Page hasn't been refreshed</p>
<script src="/popup1.js"></script>
</hmtl>
popup1.js:
const button = document.querySelector('input');
const paragraph = document.querySelector('p');
const mainBrowser = browser.document
button.addEventListener('click', refreshButton);
function refreshButton(){
button.disabled = true;
button.value="Refreshing"
paragraph.textContent = 'Page is refreshing';
// mainBrowser.reload();
window.setTimeout(function() {
button.disabled = false;
button.value = "Refresh"
paragraph.textContent = 'Page is up-to-date.';
}, 1000);
}
Image of what extension ui looks like, on clicking icon
The goal is to be able to click the Refresh Page button in the extension, and it reload whatever website my browser is currently on. I'm very new to JS, CSS, and HTML, and am failing to access things outside the scope of my extension.

How to display Internet explorer not supported in angular without importing pollyfills

With IE officially deprecated in Angular 12, I want to display a static warning in my page to notify the user to switch to a supported browser.
I'm using a simple snippet like this in the index.html
to append a css class to the body, when then displays a div element.
<body class="mat-typography">
<script>
(function msieversion() {
const ua = window.navigator.userAgent;
const msie = ua.indexOf('MSIE ');
if (msie > 0) {
document.body.classList.add('is-internet-explorer');
}
})();
</script>
<div class="ie">isIE</div>
<app-root></app-root>
</body>
.is-internet-explorer {
.ie {
display: flex;
}
app-root{
display: none;
}
}
.ie {
display: none;
}
But I'm getting errors in internet explorer, that runtime.js, polyfills.js, vendor.js and main.js wont run. I assume it is because of missing polyfills and the tsconfig target setting, that these won't run.
Is there a way to "prevent" angular from inserting or executing these script tags in the first place? I've tried to remove them in my if (msie > 0) block, but that doesn't work.
setTimeout(() => {
const x = document.body.querySelectorAll('script[defer]');
x.forEach((i) => document.body.removeChild(i));
});
My goal is to accomplish this without having to adjust polyfill and tsconfig settings, to keep the build size to a mininum.
The errors showing in IE is due to the scripts still load in IE. If you don't want to see the errors in IE, you can load an unsupported html page when the browser is IE.
Besides, it seems that there're some issues in your detecting IE code. I made some changes, and you can refer to my steps below, I test it and it works well:
Add a unsupported.html file in the root of src folder. Example unsupported.html file:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title></title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<body>
<h1>The app is not supported in IE. Please use other browsers!</h1>
</body>
</html>
Add "src/unsupported.html" in angular.json assets property. For example:
"assets": [
"src/favicon.ico",
"src/assets",
"src/unsupported.html"
],
Detect browser in src/index.html, if IE then redirect to unsupported.html, if not then render <app-root>. The code is like below:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>MyApp</title>
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>
<script type="text/javascript">
var msie = /msie\s|trident/i.test(window.navigator.userAgent);
if (msie) {
//IE, redirect page
window.location.href = "./unsupported.html";
}
else {
//render app
var elem = document.createElement("app-root");
document.body.appendChild(elem);
}
</script>
</body>
</html>
I suggest to display an alert before IE encounters any problem. I use below code:
<body>
<script>
function isUserUsingIeBrowser() {
return /MSIE|Trident/.test(window.navigator.userAgent);
}
if (isUserUsingIeBrowser()) {
alert('IE not supported');
}
</script>
<app-root></app-root>
</body>

pdfMake - open() and print() functions are not working

I'm trying to learn how to use pdfMake. I'm trying to use open and print to generate or print the information respectively. But, when I click on the button which fires the event, a new tab opens for a second and vanishes.
The page which opens is displayed in history as blob:http://localhost:9999/93c1600e-3c64-42fe-8b44-fe6eeb995b5e
I'm not able to figure out the error. I'm following the official documentation of pdfMake.
Please help.
function print(){
window.event.preventDefault()
// this is just a simulation of the open event, replacing it with print produces the same result
var docDefinition = { content: {text:'This is an sample PDF printed with pdfMake',fontSize:15} };
pdfMake.createPdf(docDefinition).open();
}
<!DOCTYPE HMTL>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
<script src='https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.27/pdfmake.min.js'></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.27/vfs_fonts.js"></script>
<script src="js/print.js"></script>
</head>
<body>
<main>
<button onclick="print()">Print Card</button>
</main>
</body>
</html>
Please check that any type of ad blocker in your browser is turned off and try again.
I found solution for printing in same window.
In your .html file put iframe
<iframe id="printPdf" name="printPdf"></iframe>
iframe needs style to hide himself for example (I do not know why, but if I define width and height on iframe, printing will not work):
#printPdf { position: fixed; top: 0px; left: 0px; display: block;
padding: 0px;border: 0px;margin: 0px;
visibility: hidden; opacity: 0;
}
Finally, just call:
if ('safari') {
pdfMake.createPdf(content).open({}, window.frames['printPdf']);
setTimeout(function() {
window.frames['printPdf'].focus();
window.frames['printPdf'].print();
}, 2000)
} else {
pdfMake.createPdf(content).print({}, window.frames['printPdf']);
}
Tested on Chrome v72, Firefox v65, Edge v18, Safari v12
for the open() it's not working even without ad blocker so i converted it to base64 then blob then fileURL
var docDefinition = getRWABELPDF(data);
var createPdf = pdfMake.createPdf(docDefinition);
var base64data = null;
createPdf.getBase64(function(encodedString) {
base64data = encodedString;
console.log(base64data );
var byteCharacters = atob(base64data);
var byteNumbers = new Array(byteCharacters.length);
for (var i = 0; i < byteCharacters.length; i++) {
byteNumbers[i] = byteCharacters.charCodeAt(i);
}
var byteArray = new Uint8Array(byteNumbers);
var file = new Blob([byteArray], { type: 'application/pdf;base64' });
var fileURL = URL.createObjectURL(file);
window.open(fileURL);
PDFMake has an open issue for this problem.
PDFMake creates URLs starting with blob: to print/open a generated PDF. The problem is that this pattern of URL is used by many sites to show undesired popups to users. Then EasyList listed this URL pattern and ad blockers started blocking it.
Therefore, as steffanjj suggested, disable your ad blocker and you should be able to print/open the generated PDF. I just wanted to explain in little more detail why this is happening.
This helped me for viewing directly in browser.
<!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>PDF Make</title>
<script src='js/pdfmake.min.js'></script>
<script src='js/vfs_fonts.js'></script>
<style>
#viewPdf { position: fixed; top: 0px; left: 0px; display: block; padding: 0px; border: 0px; margin: 0px; width: 100%; height: 100%; }
</style>
</head>
<body>
<iframe id="viewPdf" name="viewPdf"></iframe>
<script>
const docDefinition = {
pageMargins: [ 0, 0, 0, 0 ],
content: 'This is an sample PDF printed with pdfMake'
};
pdfMake.createPdf(docDefinition).open(window.frames['viewPdf']);
</script>
</body>
</html>

Categories

Resources