Click event not working in Chrome extension options page - javascript

In my options page I generate some rows with an input number and a button, related to entries at chrome storage.
The problem is that the event listener i'm creating for the buttons doesn't work at all.
options.html
<html>
<head>
<title>Select the movie's Id</title>
<style>
body: { padding: 10px; }
.style-1 input[type="number"] {
padding: 10px;
border: solid 1px #dcdcdc;
transition: box-shadow 0.3s, border 0.3s;
width: 5em;
}
.style-1 input[type="number"]:focus,
.style-1 input[type="number"].focus {
border: solid 1px #707070;
box-shadow: 0 0 5px 1px #969696;
}
</style>
</head>
<body>
<legend style="border-bottom: solid 1px">Insert</legend>
<input type="number" name="id" id="id" value="">
<button id="save">Insert</button>
<br>
<br>
<legend style="border-bottom: solid 1px">Manage</legend>
<div id="ghost" style="display: none">
<input type="number" name="VAL">
<button name="DEL" id="" >Delete</button>
<br><br>
</div>
<script src="options.js"></script>
</body>
options.js
document.getElementById('save').addEventListener('click', save_options);
chrome.storage.sync.get('movieId', function(result){
for (var i=0; i<result.movieId.length; i++){
createRow(result.movieId[i]);
}
});
function save_options() {
var id = document.getElementById('id').value;
chrome.storage.sync.get('movieId', function(result){
var ids = result.movieId;
ids.push(id);
chrome.storage.sync.set({
'movieId': ids
}, function() {
});
location.reload();
});
}
function createRow(pos){
var newRows= document.getElementById('ghost').cloneNode(true);
newRows.id= '';
newRows.style.display= 'block';
var newRow= newRows.childNodes;
for (var i= 0; i< newRow.length; i++){
var newName= newRow[i].name;
if (newName){
newRow[i].name = newName+pos;
newRow[i].id = pos;
newRow[i].value = pos;
}
}
var insertHere= document.getElementById('ghost');
insertHere.parentNode.insertBefore(newRows,insertHere);
document.getElementById(pos).addEventListener('click', delet());
}
function loop(arrayIds){
console.log('loop');
for (var i=0; i<arrayIds.length; i++){
createRow(i);
}
}
function delet(){
console.log("this.id");
//chrome.storage.sync.remove(id);
}
With this, when I click any of the Delete buttons nothing happens.
I've tried all the combinations I can think for document.getElementById(pos).addEventListener('click', delet()); but none of them work.

document.getElementById(pos).addEventListener('click', delet());
is supposed to be
document.getElementById(pos).addEventListener('click', delet);
In your snippet you are calling delet thus result of that function is added as event listener that is undefined. If you want to bind delet as event handler, pass it to addEventListener without calling it.
EDIT
As I saw your code, you are giving same id to both input and button and when you call document.getElementById it returns input instead of button so, event is binded to input instead of button.
To fix that replace your createRow with this
function createRow(pos) {
var newRow = document.getElementById('ghost').cloneNode(true);
newRow.id= '';
newRow.style.display= 'block';
var value = newRow.querySelector("[name=VAL]");
var button = newRow.querySelector("[name=DEL]");
value.id = "VAL" + pos;
value.value = pos;
button.id = "DEL" + pos;
var insertHere= document.getElementById('ghost');
insertHere.parentNode.insertBefore(newRow, insertHere);
button.addEventListener('click', delet);
}

Related

pixel art maker project jquery

The code is about a webpage that takes grid height and width and creates it by clicking submit and then draw in the grid any shape by choosing the boxes depending on the chosen color. can someone explain to me what is wrong with my javascript code?
code pen is here
$('#submit').on('click', function makeGrid(event){
var r = $('#inputHeight').val();
var c = $('#inputWeight').val();
/*var grid = $('table');
var tr = '<tr></tr>';
var td = '<td></td>';*/
for (var i=0; i<r; i++){
$('table').append('<tr></tr>');
for(var j=0; j<c; j++){
$('tr:last-child').append('<td></td>');
}
}
});
$('table').on('click',' tr td', function(){
$(this).css('background-color',$('colorPicker').val())
});
The <input type="submit"> will send a request to the server. Which in turn will cause a redirect.
You'll need to call preventDefault() and/or return false in your handler.
The jquery selector $("#submit") will look for an element with id submit, it isn't selecting the <input type="submit">, to fix, add the id="submit" to the <input>.
also, you might want to remove all children in the <table> when the button is pressed a second time. IE. $("table").empty();
$("#submit").on("click", function makeGrid(event) {
var r = $("#inputHeight").val();
var c = $("#inputWeight").val();
$("table").empty();
/*var grid = $('table');
var tr = '<tr></tr>';
var td = '<td></td>';*/
for (var i = 0; i < r; i++) {
$("table").append("<tr></tr>");
for (var j = 0; j < c; j++) {
$("tr:last-child").append("<td></td>");
}
}
$("table tr td").on("click", function() {
$(this).css("background-color", $("#colorPicker").val());
});
event.preventDefault();
return false;
});
body {
text-align: center;
}
h1 {
font-family: Monoton;
font-size: 70px;
margin: 0.2em;
}
h2 {
margin: 1em 0 0.25em;
}
h2:first-of-type {
margin-top: 0.5em;
}
table,
tr,
td {
border: 1px solid black;
}
table {
border-collapse: collapse;
margin: 0 auto;
}
tr {
height: 20px;
}
td {
width: 20px;
}
input[type=number] {
width: 6em;
}
<html>
<head>
<title>Pixel Art Maker!</title>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Monoton">
<link rel="stylesheet" href="styles.css">
</head>
<body>
<h1>Lab: Pixel Art Maker</h1>
<h2>Choose Grid Size</h2>
<form id="sizePicker">
Grid Height:
<input type="number" id="inputHeight" name="height" min="1" value="1"> Grid Width:
<input type="number" id="inputWeight" name="width" min="1" value="1">
<input type="submit" id="submit">
</form>
<h2>Pick A Color</h2>
<input type="color" id="colorPicker">
<h2>Design Canvas</h2>
<table id="pixelCanvas"></table>
<script src="designs.js"></script>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
</body>
</html>

Dynamic <a> not clickable

I have done the following code in php so that I can click on the arrow and a form opens below
echo '<div class="editor" id="'.$par_code.'" style=" background-color: #fdfdfd; padding:14px 25px 30px 20px; font-family: Lucida Console, Monaco, monospace; box-shadow: 0 1px 10px 2px rgba(0,0,0,0.2),0 8px 20px 0 rgba(0,0,0,0.03); border-radius: 3px;">'
.'<img width="50" height="50" style="border-radius:50%" src="images/default.png" alt="Image cannot be displayed"/>'
.'<p class="uname"> '.$uname.'</p> '
.'<p class="time">'.$date.'</p>'
.'<p class="comment-text" style="word-break: break-all;">'.$content.'</p>'
.'<a class="link-reply al" id="reply" name="'.$par_code.'" style="padding-top: 18px; float: right;"><i class="fa fa-reply fa-lg" title="Reply"></i></a>';
My javascript code:
$(document).ready(function() {
$("a#reply").one("click" , function() {
var comCode = $(this).attr("name");
var parent = $(this).parent();
var str1 = "new-reply";
var str2 = "tog";
var res = str1.concat(i);
var tes = str2.concat(i);
// Create a new editor inside the <div id="editor">, setting its value to html
parent.append("<br /><center><form action='index.php' method='post' id='"+tes+"'><input class='iptext2' type='text' name='uname2' id='uname2' placeholder='Your Name' required /><div style='padding-bottom:5px'></div><textarea class='ckeditor' name='editor' placeholder='Your Query' id='"+res+"' required></textarea><input type='hidden' name='code' value='"+comCode+"' /><br/><input type='submit' class='form-submit' id='form-reply' name='new_reply' value='Reply' /></form></center>")
CKEDITOR.replace(res);
/*
var x = document.getElementById("tes");
if (x.style.display === "none") {
x.style.display = "block";
} else {
x.style.display = "none";
}
*/
i++;
});
})
The following is my css code applied to the anchor tag:
.al {
font-size:11.2px;
text-transform: uppercase;
text-decoration: none;
color:#222;
cursor:pointer;
transition:ease 0.3s all;
}
.al:hover {
color:#0072bc;
}
.link-reply {
color:#767676;
}
Here the arrow icon is displayed but is not clickable
Your code fails, because your <a> elements are created dynamically, whereas the event listener is added only to the elements available when the document has loaded.
In order to get your code to work, you need to use event delegation; that is to add the event listener to a common static ancestor, such as the document or the body, that will in turn delegate it to your target elements.
The methods you can use to achieve this effect in jQuery are on and one, with the latter fitting your case better, if you are trying to attach one-time event listeners.
Code:
$(document).one("click", "a#reply", function() {
// ...
});
Use on for dynamic created events on DOM.
$(document).on("click","a#reply" , function() {
console.log('a#reply => clicked!')
});
Or
$(body).on("click","a#reply" , function() {
console.log('a#reply => clicked!')
});

dynamically Adding and removing elements based on checkbox values with DOM

I'm just trying to dynamically add to a div within a form depending on which checkboxes are checked. So, I am creating the li tag and then they are added as li elements within an ol parent element so its just a list of values. I do not know what is wrong with my code, I'm not sure how to remove the appropriate value if the relevant checkbox is unchecked, and when I uncheck and then recheck a checkbox, it keeps adding the value over and over again.
<!DOCTYPE html>
<html>
<head>
<title></title>
<style>
input {
margin: 18px;
}
#o {
list-style-type: none;
}
.u {
list-style: none;
}
</style>
</head>
<body style="width: 700px">
<div style="float: left; width: 340px; height: 250px; border: 1px solid black; padding: 20px 0 10px 20px;">
<form id="myForm">
<ul class="u">
<li><input id="showAlert1" type="checkbox" name="thing" value="laptop">laptop</li>
<li><input id="showAlert2" type="checkbox" name="thing" value="iphone">iphone</li>
</ul>
</form>
</div>
<div id="myDiv" style="float: right; width: 317px; height: 250px; border: solid black; border-width: 1px 1px 1px 0; padding: 20px 0 10px 20px;">
<ol id="o">
</ol>
</div>
<script>
document.getElementById('myForm').addEventListener('change', function () {
var a = document.getElementsByName('thing');
for (var i = 0; i < a.length; i++) {
if (a[i].checked){
createDynamicElement();
} else if (!a[i].checked){
removeDynamicElement();
}
}
function createDynamicElement(){
var node = document.createElement("LI");
node.setAttribute("id1", "Hey");
var textnode = document.createTextNode(event.target.nextSibling.data);
node.appendChild(textnode);
document.getElementById("o").appendChild(node);
}
function removeDynamicElement() {
document.querySelector("#o li").innerHTML = "";
}
});
</script>
</body>
</html>
It looks like that you are adding an event listener to the form instead of the input elements themselves. I dont think the change event will be fired when an input element in a form changes. (see: https://developer.mozilla.org/en-US/docs/Web/Events/change)
On your event listener, try targeting the input elements themselves.
} else if (!a[i].checked){
removeDynamicElement();
}
...
function removeDynamicElement() {
document.querySelector("#o li").innerHTML = "";
}
Will empty the first or all matches(not sure) but wont remove them. Instead you should give li tags a unique ID and remove them completely via something like:
for (var i = 0; i < a.length; i++) {
if (a[i].checked){
console.log(a[i])
createDynamicElement(a[i].value);
} else if (!a[i].checked){
removeDynamicElement(a[i].value);
}
}
function createDynamicElement(id){
var node = document.createElement("LI");
node.setAttribute("id", id);
var textnode = document.createTextNode(id);
node.appendChild(textnode);
console.log(node)
document.getElementById("o").appendChild(node);
}
function removeDynamicElement(id) {
var target = document.getElementById(id)
target.parentElement.removeChild(target);
}
Or you could clear the ol completely on every change and repopulate it again like:
var a = document.getElementsByName('thing');
document.getElementById("o").innerHTML = null;
for (var i = 0; i < a.length; i++) {
if (a[i].checked){
console.log(a[i])
createDynamicElement(a[i].value);
}
}
function createDynamicElement(id){
var node = document.createElement("LI");
var textnode = document.createTextNode(id);
node.appendChild(textnode);
console.log(node)
document.getElementById("o").appendChild(node);
}
Edit:
A proper FIFO solution:
var a = document.getElementsByName('thing');
for (var i = 0; i < 2; i++) {
var target = document.getElementById(a[i].value);
if (a[i].checked && !target){
createDynamicElement(a[i].value);
} else if ((!a[i].checked) && target){
removeDynamicElement(a[i].value);
}
}
function createDynamicElement(id){
var node = document.createElement("li");
node.setAttribute("id", id);
var textnode = document.createTextNode(id);
node.appendChild(textnode);
document.getElementById("o").appendChild(node);
console.log("a")
}
function removeDynamicElement(id) {
target.parentElement.removeChild(target);
}
});

Highlight the text in textarea with delay

I am trying to highlight the single line of text in <textarea> with time delay. And I am wondering if I can choose a different color? The thing I wanted is when I click on the first <button>, the first line is highlighted into blue, click on the second <button>, 1 second later, the second line is highlighted into blue, lastly click on the third <button>, 2 second later, the third line is highlighted into yellow. I noticed I have a bug that I clicked on the button 3 times then the highlight doesn't work, but it is okay for me, I just want to know how to make the time delay and highlight with a different color. Thank you very much.
$( document ).ready(function() {
var str = 'line 1\nline 2\nline 3\n';
var textNumChar = str.length;
$('#str').val(str);
startPosition = 0;
$(".lines").click(function() {
var tarea = document.getElementById('str');
for(i=startPosition;i<textNumChar;i++)
{
if(str[i]=='\n') {
endposition = i;
break;
}
}
tarea.selectionStart = startPosition;
tarea.selectionEnd = endposition;
startPosition = endposition+1;
});
});
#container {
float: left;
}
button {
width: 50px;height: 30px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"> </script>
<div id="container">
<button class="lines" id="line1">line 1</button>
<br>
<button class="lines" id="line2">line 2</button>
<br>
<button class="lines" id="line3">line 3</button>
</div>
<textarea id="str" rows="6"></textarea>
You can use setTimeout() to set the delay in highlighting the text based on button id.
And ::selection css selector to style the portion of an element that is selected.
$( document ).ready(function() {
var str = 'line 1\nline 2\nline 3\n';
var textNumChar = str.length;
$('#str').val(str);
startPosition = 0;
$(".lines").click(function(e) {
var tarea = document.getElementById('str');
for(i=startPosition;i<textNumChar;i++)
{
if(str[i]=='\n') {
endposition = i;
break;
}
}
var time = 0;
var tar_id = e.target.id;
var colors;
if(tar_id == 'line1' ) { colors = 'red'; }
else if(tar_id == 'line2' ) { time = 1000; colors = 'blue'; }
else if(tar_id == 'line3' ) { time = 2000; colors = 'green'; }
setTimeout(function(){
tarea.selectionStart = startPosition;
tarea.selectionEnd = endposition;
startPosition = endposition+1;
$('body').addClass(colors);
}, time);
});
});
#container {
float: left;
}
button {
width: 50px;height: 30px;
}
.red ::selection {
color: red;
background: yellow;
}
.blue ::selection {
color: blue;
background: red;
}
.green ::selection {
color: green;
background: blue;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"> </script>
<div id="container">
<button class="lines" id="line1">line 1</button>
<br>
<button class="lines" id="line2">line 2</button>
<br>
<button class="lines" id="line3">line 3</button>
</div>
<textarea id="str" rows="6"></textarea>

Disable button until a number is reached

So I have a code so when I press a button a number goes up.
This is the html:
<button type="button" class="btn btn-default" onclick="javascript:btnClick()">+1</button>
This is the JavaScript:
function btnClick(){
timesClicked += 1;
document.getElementById('timesClicked').innerHTML = timesClicked;
return true
}
So I have a button that has +1 so when I press it the number goes up
I need a button that is disabled until that number gets to 5 for example then becomes clickable, is that possible? I'm still learning Javascript,
All help is appreciated.
If the button is disabled, a user cannot interact with it.
Try the following
window.onload=function() {
var count =0;
document.getElementById("btn").addEventListener("click", function() {
count++;
if(count === 5) {
this.innerHTML = "5 clicks reached!";
}
});
};
<button id="btn">Click</button>
You could try something like this:
document.getElementById("button").disabled = true;
timesClicked = 0;
function btnClick(){
timesClicked += 1;
document.getElementById('timesClicked').innerHTML = timesClicked;
if(timesClicked > 5){
document.getElementById("button").disabled = false;
}
}
<button type="button" id="button" class="btn btn-default" onclick="btnClick()">+1</button>
[].forEach.call(document.querySelectorAll("[data-click-vote]"), function(btn) {
btn.addEventListener("click", vote);
});
function vote() {
this.innerHTML = this.value=Math.min(++this.value, 5);
}
<button value="0" name="movie1" data-click-vote>+1</button> The Revenant<br>
<button value="0" name="movie2" data-click-vote>+1</button> Dracula<br>
<button value="0" name="movie3" data-click-vote>+1</button> The Usual Suspect<br>
Multiple buttons
Updates simultaneously value and innerHTML
You can submit the values using a <form>
You can achieve your requirement with JS and CSS as in the below solution.
You haven't tagged it with CSS but you might want to look at this as well.
Button is simply a disabled span. Clicks are registered and when the count requirement is satisfied, it springs to life and handles your clicks with the actual handler code. (You can add a handler instead of printing a click count)
window.onload = function() {
var count = 1;
document.getElementById("btn").addEventListener("click", function() {
count++;
this.innerHTML = "+" + count;
if (count >= 5) {
this.className = "btnenabled";
this.innerHTML = "Print Click Count!";
if(count > 5) {
document.getElementById("counter").innerHTML= "Click Count is " + count;
}
}
});
};
.btnenabled {
width:200px;
background-color: blue;
padding: 3px;
border-radius: 3px;
color: white;
font-weight: bold;
display:block;
text-align:center;
}
.btnenabled:hover {
background-color:purple;
}
.btndisabled {
width:200px;
padding: 3px;
border-radius: 3px;
display:block;
text-align:center;
background-color: grey;
color: #F0F0F0;
font-weight: 100;
}
<span id="btn" class="btndisabled"> +1 </span>
<span id="counter"></span>

Categories