Importing a function into a new .html file - javascript

I am trying to import a function of a simple button click opening up a box from one .html file to another and for some reason it isn't working. It works perfectly fine when all the css js and html is in its own file, but when they are apart I cant get the button to open when clicked.
regions.html file
<style> #btn_region {
position: absolute; /* create a positioning context for the list items */
width: 23%;
left: 51vw;
top: 130vw;
font-size: 14px;
height: 9vw;
z-index: 1000;
}
#box_region {
position: absolute;
width: 90%;
height: 27%;
background-color: #f1f1f1;
left: 0px;
top: 138vw;
}
.regions {
width:80%;
height:60.15%;
}}
</style>
<button id='btn_region'>Region</button>
<div id='box_region' style='display:none;'>
<div id='div_region'>
<a id='neus' href='$(url)'>
<h1><span class='color-change' >Northeast</span></h1>
<img class='regions'
src='#' width='300'
height='225'>
</a>
</div>
<div id='div_region'>
<a id='usa' href='$(url)'>
<h1><span class='color-change' >USA</span></h1>
<img class='regions'
src='#' width='300'
height='225'>
</a>
</div>
</div>
script.js file
const regions = document.querySelector('.regions')
fetch('regions.html')
.then(res=>res.text())
.then(data=>{
regions.innerHTML=data
const parser = new DOMParser()
const doc = parser.parseFromString(data, 'text/html')
eval(doc.querySelector('script').textContent)
})
let mainDirectory = '#'
let neus_href = document.getElementById('neus');
neus_href.href = mainDirectory+'neus.html';
let usa_href = document.getElementById('usa');
usa_href.href = mainDirectory+'usa.html';
const btn_region = document.getElementById('btn_region');
const box_region = document.getElementById('box_region');
btn_region.addEventListener('click', function() {
if (box_region.style.display === 'block') {
box_region.style.display = 'none';
} else {
box_region.style.display = 'block';
}
});
document.addEventListener('click', function(event) {
if (event.target !== btn_region && event.target !== box_region) {
box_region.style.display = 'none';
}
});
file I'm importing into
<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">
</head>
<body>
<div class="regions">
</div>
<script src="script.js"></script>
</body>
</html>

Spotted a syntax error in "regions.html". I think there's an extra curly bracket in your last style rule.
.regions {
width:80%;
height:60.15%;
}} <-------
Also, I'm getting a console error: neus_href is null
I have a feeling this is because you're trying to select #neus as a generated DOM element, with:
let neus_href = document.getElementById('neus');
I imagine this would work fine if all the HTML code is together on one page, but when the HTML is split into separate files you should probably grab it from your fetch data, which it looks like you're storing in the 'doc' variable. Should probably try something like:
let neus_href = doc.querySelector('#neus');
Hope this helps.

Related

After adding a non-case sensitive search and clickable pictures, script stopped working

Trying to make my first project with bunch of pictures, with a filter/search bar at the top that would filter the pictures depending on the input. For example if the input would be "Aatrox", it would show "Aatrox" and not "Jayce" and or "Senna" and so on. Script was working fine, I added a .toLowerCase() so its not case sensitive and then I added to the pictures so they are clickable and each lead to their own page. After adding these two the search bar stopped working.
Here is the snippet of the script
<script>
function search(){
var searchText = (document.getElementById("searchInput").value).toLowerCase();
var images = document.querySelectorAll(".image_container > img");
if(searchText.length > 0){
images.forEach((image) => {
image.classList.add("hide");
if((image.dataset.tags).toLowerCase().indexOf(searchText) > -1){
image.classList.remove("hide");
}
});
}else{
images.forEach((image) => {
image.classList.remove("hide");
});
}
}
</script>
Here is the HTML part
<head>
<title> Counterpicks </title>
<meta charset="utf-8">
<link rel="stylesheet" href="style.css">
</head>
<body>
<h1> Counterpicks pro debily </h1>
<div class="container">
<div class="searchbox_container">
<div class="searchbox">
<input type="text" name=" " placeholder="Search" class="search" id="searchInput" onkeyup="search()">
</div>
</div>
<div class="image_container">
<img data-tags="aatrox" src="aatrox.webp" alt="Aatrox" class="actionimages">
<img data-tags="ahri" src="ahri.webp" alt="Ahri" class="actionimages">
</div>
I input only few of the lines because they are just repeating for 130 lines.
And here is the CSS
.container {
background: rgba(0,0,0,0);
text-align: center;
margin-left: 20%;
margin-right: 20%;
}
.searchbox {
text-align: center;
margin-left: 20%;
margin-right: 20%;
margin-bottom: 20px;
}
.image_container {
clear:both;
}
.hide {
display:none;
This is my first project with JavaScript so I will be happy for any constructive criticism.
Replace:
var images = document.querySelectorAll(".image_container > img");
with:
var images = document.querySelectorAll(".image_container > a > img");

refactoring javascript code to create for loop

I am practicing Javascript. I want each link to display something different in the DOM when clicked.
Here is my current Javascript that works.
//used a 'for' loop to hide each 'notes' page
const element = document.querySelectorAll(".notes");
for (let x = 0; x < element.length; x++)
element[x].style.display = 'none';
const html_link= document.getElementById('html-link');
const css_link = document.getElementById('css-link');
const javascript_link = document.getElementById('js-link');
const html_notes = document.getElementById('html-notes');
const css_notes = document.getElementById('css-notes');
const js_notes = document.getElementById('js-notes');
html_link.onclick = function() {
html_notes.style.display = "block";
css_notes.style.display = "none";
js_notes.style.display = "none";
}
css_link.onclick = function() {
css_notes.style.display = "block";
html_notes.style.display = "none";
js_notes.style.display = "none";
}
javascript_link.onclick = () => {
js_notes.style.display = "block";
html_notes.style.display = "none";
css_notes.style.display = "none";
}
How can I refactor it using a for loop? My thinking was for each link clicked, display notes. But I am struggling to figure out how to display the notes div correctly that matches the link clicked. This is what I have started.
const links = document.querySelectorAll('.links')
for (const link of links) {
link.addEventListener('click', function() {
let ref = event.target.parentElement.id.replace('link','notes');
//replaces parent element with id 'notes'
const show = document.getElementById(ref);
//'show' div with new id
})
}
Welcome, fellow newbie! I've taken the liberty of writing the html and very minimal styling as well. This is my first attempt at an answer on stackoverflow.
Please note some features of the code I've added:
'links' class added to all links.
'notes' class added to all notes.
'data-notes' attribute added to all links (with the id of each link's respective notes)
<!DOCTYPE html>
<html dir="ltr" lang="en-US">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.0"/>
</head>
<body>
<div class="outer">
<div id="html-link" data-notes="html-notes" class="links">
<p>html-link</p>
</div>
<div id="css-link" data-notes="css-notes" class="links">
<p>css-link</p>
</div>
<div id="javascript-link" data-notes="javascript-notes" class="links">
<p>javascript-link</p>
</div>
</div>
<div class="outer">
<div id="html-notes" class="notes">
<p>html-notes</p>
</div>
<div id="css-notes" class="notes">
<p>css-notes</p>
</div>
<div id="javascript-notes" class="notes">
<p>javascript-notes</p>
</div>
</div>
<style>
.links {
cursor: pointer;
background: green;
color: white;
padding: 1rem;
margin: 1rem;
}
.notes {
display: none;
background: blue;
color: white;
padding: 1rem;
margin: 1rem;
}
.outer {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-around;
margin: 2rem 0;
}
</style>
<script>
const links = document.querySelectorAll('.links');
const notes = document.querySelectorAll('.notes');
for (const link of links) {
link.onclick = function () {
for (const note of notes) {
if (note.id == link.dataset.notes) {
note.style.display = "block";
} else {
note.style.display = "none";
}
}
}
}
</script>
</body>
</html>

Add Show Dialog custom html to Google Slides Script

I'm trying to make this dialog popup for the duration of the execution of the AddConclusionSlide function, but I get the exception: "TypeError: Cannot find function show in object Presentation." Is there an alternative to "show" for Google Slides Script (This works perfectly in google docs)?
function AddConclusionSlide() {
htmlApp("","");
var srcId = "1Ar9GnT8xPI3ZYum9uko_2yTm9LOp7YX3mzLCn3hDjuc";
var srcPage = 6;
var srcSlide = SlidesApp.openById(srcId);
var dstSlide = SlidesApp.getActivePresentation();
var copySlide = srcSlide.getSlides()[srcPage - 1];
dstSlide.appendSlide(copySlide);
Utilities.sleep(3000); // change this value to show the "Running script, please wait.." HTML window for longer time.
htmlApp("Finished!","");
Utilities.sleep(3000); // change this value to show the "Finished! This window will close automatically. HTML window for longer time.
htmlApp("","close"); // Automatically closes the HTML window.
}
function htmlApp (status,close) {
var ss = SlidesApp.getActivePresentation();
var htmlApp = HtmlService.createTemplateFromFile("html");
htmlApp.data = status;
htmlApp.close = close;
ss.show(htmlApp.evaluate()
.setWidth(300)
.setHeight(200));
}
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<style>
img {
display: block;
margin-left: auto;
margin-right: auto;
width: 25%;
}
.gap-10 {
width: 100%;
height: 20px;
}
.gap-20 {
width: 100%;
height: 40px;
}
.gap-30 {
width: 100%;
height: 60px;
}
</style>
</head>
<body>
<div class="container">
<div>
<p align="justify" style="font-family:helvetica,garamond,serif;font-size:12px;font-style:regular;" class="light">
Function is running... This could take a while. It's a lot of data...</p>
</div>
<p id="status">(innerHTML).</p>
<div id="imageico"></div>
<script>
var imageContainer = document.getElementById("imageico");
if (<?= data ?> != "Finished!"){
document.getElementById("status").innerHTML = "";
} else {
document.getElementById("status").innerHTML = "";
}
if (<?= close ?> == "close"){
google.script.host.close();
}
</script>
</body>
</html>
Unlike Spreadsheet object, Slide object doesn't have a show method. So, class ui needs to be used:
SlidesApp.getUi().showModalDialog(htmlApp.evaluate()
.setWidth(300)
.setHeight(200), "My App")

How to create a thumbnail from image with close button

Here is my code:
https://codepen.io/manuchadha/pen/PBKYBJ
I have created a form. I want to be able to upload an image using the file upload input. When an image is selected, I want to show a thumbnail of the image just below the file selector box and also show a close (x) sign on the top-right corner of the image which could be used to delete the image. But I am unable to create it. What am I doing wrong?
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<base href="">
<title>Example</title>
<!--meta http-equiv="Content-Security-Policy" content="default-src *; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval'"-->
<link rel="stylesheet" media="screen" href="fiddle.css">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.13.1/css/bootstrap-select.css" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="fiddle.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.bundle.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.13.1/js/bootstrap-select.min.js"></script>
</head>
<body>
<div id="form-div" class="body__div--background"> <!-- takes the complete width/height of content section -->
<!-- The novalidate attribute in the <form> element prevents the browser from attempting native HTML validations.
validation will be done using Angular's Validators which come with FormGroups and FormControls-->
<form id="new-question-form" class="practice-question-form" [formGroup]="practiceQuestionForm" (ngSubmit)="addPracticeQuestion()" novalidate>
<!-- label and small in same line. select in a new line, thus enclosed select in a div-->
<div class="form-group">
<div class="form-group">
<label for="file-upload" class="control-label required">Upload files</label>
<div class="custom-file" id="file-upload" lang="es">
<input type="file" class="custom-file-input" id="question-file-upload" onchange="handleFileSelect()">
<label class="custom-file-label" for="question-file-upload">
Select file...
</label>
</div>
</div>
<button type="submit" id="submit-practice-question-button" class="content-div__button--blue"> Submit! </button>
</form>
<div id="imageContainer">
</div>
</div>
</div>
</body>
CSS
body{
margin:0px;
}
.body__div--background {
background: linear-gradient(45deg,#33b1f8 37%,#6e90f6 100%); /*syntax linear-gradient(direction, color1 limit, color2 limit)*/
color:#555555;
font-family: Helvetica;
line-height:1.5;
font-size: 11px;
letter-spacing: 0.25px;
}
#submit-practice-question-button{
display:block;
}
#imageContainer{
display:inline-block;
border: 1px solid black;
}
.close {
top:0;
right:80; /*match the width of the image*/
position: relative;
opacity: 0.3;
}
.close:hover {
opacity: 1;
}
.close:before, .close:after {
position: relative;
left: 15px;
content: ' ';
height: 33px;
width: 2px;
background-color: #333;
}
.close:before {
transform: rotate(45deg);
}
.close:after {
transform: rotate(-45deg);
}
JS
/*handler for file upload*/
function handleFileSelect(){
console.log("got file upload event:");
/*
FileList object is the object returned as a result of a user selecting files using the <input> element,
from a drag and drop operation's DataTransfer object, or from the mozGetAsFile() API on an HTMLCanvasElement.
*/
var files = document.getElementById('question-file-upload').files;//event.target.files;
console.log("files selected:"+files+", total selected: "+files.length);
for(var i=0;i<files.length;i++)
{
console.log("files name:"+files[i].name)
console.log("files object:"+files[i])
}
//working with only 1 file at the moment
var file = files[0];
if (files && file) {
/*
The FileReader object lets web applications asynchronously read the contents of files (or raw data buffers) stored on the user's computer,
using File or Blob objects to specify the file or data to read.
*/
var reader = new FileReader();
/*bind onload event of FileReader to _handleReaderLoaded
onload is a handler for the load event. This event is triggered by FileReader each time the reading operation is successfully completed.
*/
reader.onload =this._handleReaderLoaded.bind(this);
reader.readAsBinaryString(file);
}
}
function _handleReaderLoaded(readerEvt) {
var binaryString = readerEvt.target.result;
var base64textString= btoa(binaryString);
console.log(btoa(binaryString));
var src = "data:image/png;base64,";
src += base64textString;
var newImage = document.createElement('img');
newImage.src = src;
newImage.width = newImage.height = "80";
var closeButtonLink = document.createElement('a');
closeButtonLink.setAttribute('href',"#");
closeButtonLink.classList.add("close");
document.querySelector('#imageContainer').appendChild = newImage;
document.querySelector('#imageContainer').appendChild = closeButtonLink;
}
appendChild is a method, not a property.
For example instead of node.appendChild = newImage; it should be node.appendChild(newImage);
Also you needed to add the "X" in your anchor tag. I included that in the example below.
One more thing I did a small performance upgrade too where you save the reference to the query in a variable so you don't need to query the DOM twice.
var closeButtonLink = document.createElement('a');
closeButtonLink.textContent = "X";
closeButtonLink.setAttribute('href', "#");
closeButtonLink.classList.add("close");
// use a var here to only query once for imageContainer
var imgc = document.querySelector('#imageContainer');
imgc.appendChild(newImage);
imgc.appendChild(closeButtonLink);

How to write html with javascript and display it on a slider?

I have created a basic slider that runs through images every 5 seconds while using javascript. My slider works just fine, but I'm not wanting to use it as an image slider anymore. I'm wanting to create a div with some more html design features and post that within my slider instead of my images. Going by this code below, what would I have to change and add to make it work?
<!doctype html>
<html>
<head>
<title>Ad Slider</title>
<style>
#slider
{
width: 800px;
height: 200px;
}
#sliderImages
{
width: 100%;
height: 100%;
border: 1px solid #06c;
border-radius: 10px;
}
</style>
<script type = "text/javascript">
var image1 = new Image();
image1.src = "sky.jpg";
var image2 = new Image();
image2.src = "chatImage.jpg";
var image3 = new Image();
image3.src = "orange.jpg";
</script>
</head>
<body>
<div id = "slider">
<img id = "sliderImages" src = "sky.jpg" name = "slide" />
<script type = "text/javascript">
var sliderAd = 1
function slideAds()
{
if (!document.images)
{
return;
}
document.images.slide.src = eval("image"+sliderAd+".src")
if (sliderAd < 3)
{
sliderAd++;
}
else
{
sliderAd = 1;
}
setTimeout("slideAds()",5000)
}
slideAds()
</script>
</div>
</body>
</html>
Now instead of adding those images, how can I add this type of content but working the same way like the images were?
<div>
<p>Some Content</p>
</div>
There are plenty of ways to write what you're looking for. Here's an augmented version of your code... You can toss whatever HTML you want into the innerHTML.
In the future, you're better of using Google to read up on the basics of Javascript...
<div id = "container">
</div>
<script type = "text/javascript">
MAXSLIDES = 2
slideText = 1
function slideAds() {
container = document.getElementById("container")
if(slideText == 1) {
container.innerHTML = "test1"
} else if (slideText == 2) {
container.innerHTML = "test2"
}
slideText += 1
if(slideText > MAXSLIDES) { slideText = 1 }
setTimeout("slideAds()",5000);
}
slideAds()
</script>
One of the easiest way is just to create an array of html you need, and than iterate through it inserting in each string as html in your holder div: here is an example from your question the only thing I used jQuery it is much easier that way.
<!doctype html>
<html>
<head>
<title>Ad Slider</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
<style>
#slider
{
width: 800px;
height: 200px;
}
#sliderImages
{
width: 100%;
height: 100%;
border: 1px solid #06c;
border-radius: 10px;
}
</style>
<script type = "text/javascript">
var arrayOfDiv = new Array();
arrayOfDiv[0] = "<div style='background-color:#FF0'>this is first div!</div>";
arrayOfDiv[1] = "<div style='background-color:#0ff'>this is second div!</div>";
arrayOfDiv[2] = "<div style='background-color:#f0f'>this is third div!</div>";
var sliderAd = 0;
function slideAds()
{
$("#sliderImages").html(arrayOfDiv[sliderAd]);
if (sliderAd < arrayOfDiv.length-1)
{
sliderAd++;
}
else
{
sliderAd = 0;
}
setTimeout("slideAds()",5000);
}
$(function(){
slideAds();
});
</script>
</head>
<body>
<div id = "slider">
<div id = "sliderImages" ></div>
</div>
</body>
</html>

Categories