I am trying to get user's input from Shadow DOM with addEventListener, but I don't get any response, any error. References to the elements work correctly, so console.log(input) prints out the correct element. The same code works perfectly fine without shadow DOM but I have to include it in my project. This is my code (these events are just for checking of course):
const template = document.createElement('template')
template.innerHTML = /* html */`
<div id="username">
<p>Please choose your username!</p>
<input id="username_input" type="text" placeholder="enter username">
<button>Ok</button>
</div>
`
/**
* #class Quiz
* #extends {window.HTMLElement}
*/
export class Quiz extends window.HTMLElement {
constructor () {
super()
this.attachShadow({ mode: 'open' })
this.shadowRoot.appendChild(template.content.cloneNode(true))
}
getUserName () {
const button = this.shadowRoot.querySelector('button')
const inputUname = this.shadowRoot.querySelector('#username input')
console.log(button)
button.addEventListener('click', event => console.log('badum tss'))
inputUname.addEventListener('input', event => console.log('badums tss'))
}
}
window.customElements.define('user-name', Quiz)
app.js code:
import { Quiz } from './quiz.js'
var x = new Quiz()
x.getUserName()
html:
<!doctype html>
<html lang="">
<head>
<meta charset="utf-8">
<title></title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script type="module" src="js/app.js"></script>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<user-name></user-name>
<script nomodule src="build.js"></script>
</body>
</html>
The problem is quite simple. Your code actually creates two <user-name>s.
One is statically created in html:
<user-name></user-name>
The other is dynamically created by javascript:
var x = new Quiz()
The dynamic one is never attached to the document, so you can only see the static one on the page. Since you only call getUserName() on the dynamic one, the click and input listeners are never added to the static one. That's why you didn't get any response.
I would suggest that you put addEventListener() in the constructor, then the static one should function normally.
Related
I am making a todo-list in javascript but whenever I add something into this list and then refresh, it is gone. How can I make it able to save, and I don't want to use cookies and would like to use this todo list across multiple devices with the todo list saving. For example, is there a way to add a container directly into my html instead of through my browser? I know of the .appendChild but that adds it only to the browser and it does not save. I need to do this without cookies.
Recreate this problem:
copy and paste the code below into a .html
open it up through your browser.
add a todo into the input box, for example "throw out the trash"
add a due date for this todo.
click the "Add Todo" button.
Refresh the page.
My code so far:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Practice </title>
<link href="style.css" rel="stylesheet" type="text/css" />
</head>
<body>
<input id="todo-title" type="text" />
<input id="date-picker" type="date" />
<button onclick="addTodo();">Add Todo</button>
<div id="todo-list"></div>
<script>
const todos = [{
title: 'Get groceries',
dueDate: '2021-10-04'
}, {
title: 'Wash car',
dueDate: '2021-02-03'
}, {
title: 'Make dinner',
dueDate: '2021-03-04'
}];
//todos.push('another todo'); //Adds to an array
render();
function addTodo(){
const textbox = document.getElementById('todo-title');
const title = textbox.value;
const datePicker = document.getElementById('date-picker');
const dueDate = datePicker.value;
todos.push({
title: title,
dueDate: dueDate
});
render();
}
function render(){
//reset list
document.getElementById('todo-list').innerHTML = '';
todos.forEach(function(todo){
const element = document.createElement('div');
element.innerText=todo.title + ' is due by ' + todo.dueDate;
const todoList = document.getElementById('todo-list');
todoList.appendChild(element);
});
}
//todos.pop(); //Remove's the last string of an array
</script>
<!--<div id="counter">0</div>
<button onclick="addCount();">Up</button>
<button onclick="removeCount();">Down</button> -->
<script src="script.js"></script>
</body>
</html>
I tried to make the todo-list save after refreshing. What resulted was the todo disappearing.
data.indexOf is not a function error in Tabulator JavaScript Library.
Complete error message:
[Error] TypeError: data.indexOf is not a function. (In 'data.indexOf("{")', 'data.indexOf' is undefined)
load (tabulator.js:6075)
_loadInitialData (tabulator.js:7971)
_create (tabulator.js:7841)
(anonieme functie) (tabulator.js:7756)
And warning:
Table Not Initialized - Calling the redraw function before the table is initialized may result in inconsistent behavior, Please wait for the `tableBuilt` event before calling this function
I used the setup as described in the doc, browser based so tabulator.js and tabulator.css in the location that is in the html. Nothing else done.
My HTML:
<!DOCTYPE html>
<html lang="nl">
<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">
<link rel="stylesheet" href="css/tabulator.css">
<!-- <link rel="stylesheet" href="css/tabulator.css.map"> -->
<link rel="stylesheet" href="css/layout.css">
<link rel="stylesheet" href="css/style.css">
<script defer src="js/tabulator.min.js"></script>
<script defer src="js/crud.js"></script>
<script defer src="js/data.js"></script>
<script defer src="js/assess.js"></script>
<title>DMMA</title>
</head>
<body>
<main id="home">
<h1 class="center-text dark-blue-text">Datamanagement Maturity Assessment</h1>
<div id="entree" class="container"></div>
<div class="output container"></div>
</main>
</body>
</html>
My javascript in assess.js:
document.addEventListener('DOMContentLoaded', async function() {
// the assObj is the data of assessment objects I want to retrieve
const assObj = new dataProvider;
// Use Tabulator
assObj.get('api.php/records/AssmntPlusObjects')
// .then(async dataArray => displayRecords(dta, false)) // Works!
.then(dataArray => {
let table = new Tabulator("#entree", {
data: dataArray,
autoColumns: true
})
})
.catch(err => displayError(err, null))
});
The assObj.get goes to a fetch class that gets the data from a MySQL database that gets the data via a PHP generic API. That all works.
The data array with objects is transformed to JavaScript object OK. The Tabulator gives the above error.
The site is on an internet provider host, I don't want to run another MySQL locally.
Any suggestions? Setup wrong?
dataArray is either empty or undefined. Check by console.log(dataArray)
Found the culprit! I needed get to the records in dataArray with
data: dataArray.records,
That's it!
I found that amazing because in a custom table function I built with the data (the displayRecords(dataArray, false)) it just worked without the .records property.
Thanks for putting me on the track of the contents of the dataArray.
I'm a student working on an art project in which I select one of 500 created images to show up on a webpage. I'm very new to coding and only really understand html and css, with very small amount of knowledge in JavaScript. I'm stuck in getting the images to show up, when I inspect it gives me an error saying: Failed to load resource: net::ERR_FILE_NOT_FOUND $selected_image}< I'm not really sure what to do with this, I hope someone would like to help me with this.
Thankyou :)
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" media="screen" href="css/main.css">
<!-- <link rel="JavaScript" href="script.js"> -->
<meta charset='utf-8'>
<meta content='IE=edge,chrome=1' http-equiv='X-UA-Compatible'>
<title>Mother</title>
<body>
<div id="container">
<div id="inner_container">
<img id="image_shower"/>
</div>
<div id="button_container">
<button onclick="get_random_image()"></button>
</div>
</div>
<script>
image_array = [
'Lilith10.png',
'Lilith11.png',
'Lilith12.png',
'Lilith13.png',
'Lilith14.png']
function get_random_image(){
random_index = Math.floor(Math.random() * image_array.lenght);
selected_image = image_array[random_index]
document.getElementById('image_shower').src = './images/$selected_image}'}
</script>
</body>
</html>
Javascript template strings are written with oblique quotes, and variables inside it must have brackets around them (you only had the closing one):
document.getElementById('image_shower').src = `./images/${selected_image}`;
EDIT
Even if in the present case this won't stop your code from working (unless you activate "strict mode"), I also recommend that you use the appropriate keywords to declare your variables.
const image_array = [
'Lilith10.png',
'Lilith11.png',
'Lilith12.png',
'Lilith13.png',
'Lilith14.png'
];
function get_random_image() {
const random_index = Math.floor(Math.random() * image_array.length);
const selected_image = image_array[random_index];
document.getElementById('image_shower').src = `./images/${selected_image}`;
}
PLeaseHelp. it wont show the Value, even for form authentication, to get username & password values,I was trying the same methods.
<!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>
<h1 id="result">Selected movie is </h1>
<select id="movie" onchange="showmovie()">
<option value="Spiderman">Spiderman</option>
<option value="Spiderman2">Spiderman2</option>
<option value="Spiderman3">Spiderman3</option>
</select>
</body>
</html>
<script>
var movie = document.getElementById("movie").value
function showmovie(){
alert("Changed")
document.getElementById("result").innerHTML="Movie chosen is"+movie
}
</script>
Try with this function showmovie
<script>
function showmovie() {
//Selected option
var selectedMovie = document.getElementById("movie").value;
document.getElementById("result").innerHTML = "Movie chosen is " + selectedMovie;
}
</script>
The issue here is because of the line var movie = document.getElementById("movie").value being executed just one time at the beginning (you could verify that adding console.log(movie); just after the movie variable declaration)
(movie stores then the value 'Spierdaman') and it never executes again with the calls for showmovie() function, so you could just move the movie declaration line above inside the function so it executes each time the action occurs and then having the good values.
Other details : To have a compliant code i suggest moving the script bloc to part just before and dont forget to add semicolons ';' at the end of each line ! + Better approach would be to use an eventListener as suggested by #T.J. Crowder in comments section above
Why I am getting this error? I guess some of my HTML nodes are not created why I try to call the doSearch method. It's actually happening only second time I call this function.
I'm using React and calling this function inside componentDidUpdate lifecycle method.
Here is my HTML file where I load my script inside
<!DOCTYPE html>
<html lang = "en">
<head>
<meta charset="utf-8"/>
<script type="text/javascript" src="//csr.inspsearchapi.com/lib/infospace.search.js">
</script>
<link rel="stylesheet" href="./static/style/styles.css" />
</head>
<body>
<div class="container"></div>
<script src = "bundle.js"></script>
</body>
Here is my function:
componentDidUpdate(prevProps) {
const signature = this.props.signature ? this.props.signature.response.data : '';
window.insp.search.doSearch({
query: this.state.searchText,
searchUrlFormat: this.state.searchText,
signature,
page: 1,
containers: {
'top': {id:'topResults'},
'related': {id:'relatedResults'},
},
});
}