I have an application in which I display a table(basically used to display errors) inside a popup, one of the tds have a button which is used to suppress this error. My problem is when used in conjuction with the smallipop plugin the click event is not getting fired , however it is running when run without the smallipop plugin. I have no clue whats going on here. I have fiddles for both the scenarios below:
HTML
<body>
<label>testing with smalipop</label>
<div class="myElement" id="test" style="width:100px;height:200px;background:blue">
</div>
</body>
JS
var table = document.createElement('table');
for (var i = 1; i < 4; i++){
var tr = document.createElement('tr');
var td1 = document.createElement('td');
var text1 = document.createTextNode('Text1');
var btn = document.createElement("BUTTON");
btn.className ="clickable";
var t = document.createTextNode("CLICK ME");
btn.appendChild(t);
btn.addEventListener( 'click', function ( e ) {
console.log('you clicked me');
}, false );
td1.appendChild(btn);
td1.appendChild(text1);
tr.appendChild(td1);
table.appendChild(tr);
}
var tooltipSpan = document.createElement('span');
tooltipSpan.className = "smallipop-hint";
tooltipSpan.appendChild(table);
$("#test").append(tooltipSpan);
$('.myElement').smallipop();
Fiddle with smallipop
http://jsfiddle.net/fdu9vtv0/8/
Fiddle without smallipop
https://jsfiddle.net/dzrn7rus/12/
There might be a problem with interfering JavaScript. Sometimes plugins override click events and especially because smallipop has special options for the behaviour of clicks inside the tooltip (see for example hideOnTriggerClick), this might be the problem.
I found out that when binding with jQuery, the listener still works:
var table = document.createElement('table');
for (var i = 1; i < 4; i++){
var tr = document.createElement('tr');
var td1 = document.createElement('td');
var text1 = document.createTextNode('Text1');
var btn = document.createElement("BUTTON");
btn.className ="clickable";
var t = document.createTextNode("CLICK ME");
btn.appendChild(t);
$(btn).on( "click", function() {
alert('You clicked me');
console.log('you clicked me');
});
td1.appendChild(btn);
td1.appendChild(text1);
tr.appendChild(td1);
table.appendChild(tr);
}
var tooltipSpan = document.createElement('span');
tooltipSpan.className = "smallipop-hint";
tooltipSpan.appendChild(table);
$("#test").append(tooltipSpan);
$('.myElement').smallipop();
This works as expected. See corresponding jsFiddle.
As to why it doesn't work with JavaScript: I have no clue. You might look into the source code of smallipop (although this seems to be offline at the moment). Probably there are some methods that smallipop uses that override the click events of its content.
Related
Pardon the bad title, it's hard to explain. If you know how to phrase it better, please comment and I will update as soon as I can.
So, I was messing around with a random generator site (perchance.org) and writing my own HTML/Javascript to make my generator work. It has a behavior that is what I want, but that shouldn't be happening according to my knowledge of HTML.
Let me explain with a minimal example.
The example code here is to produce a simple page that has a button.
This button should generate <input>s with <button>s next to them, attached with similar ID's.
The button, when clicked, deletes the <input> and <button>.
Here is a snippet to show you the code/let you reproduce the results:
<html>
<head>
<script>
var current_id = 0;
function add_input () {
var list = document.getElementById("list");
var input = document.createElement("input");
var delete_button = document.createElement("button");
var br = document.createElement("br");
input.id = "input_" + current_id;
delete_button.id = "button_" + current_id;
br.id = "br_" + current_id;
input.value = input.id;
delete_button.textContent = "Delete";
delete_button.onclick = function () {
delete_input(this.id.slice(7)) //To get the numerical ID
}
list.appendChild(input);
list.appendChild(delete_button);
list.appendChild(br);
current_id++;
}
function delete_input (id) {
var input = document.getElementById("input_"+id);
var button = document.getElementById("button_"+id);
var br = document.getElementById("br_"+id);
input.remove();
button.remove();
br.remove();
current_id--;
}
</script>
</head>
<body>
<div id="list">
</div>
<button onclick="add_input()">Add</button>
</body>
</html>
When you add two inputs, then delete the first, and add one more, it leaves you with two inputs using the same ID. It also leaves you with two buttons with the same ID. And yet, both buttons delete their intended target.
Why?
You really should delegate - here I wrap in a div that can be removed in one go
You can rename each input to have incremented IDs but just letting the cnt run, gives you unique IDs
let cnt = 0;
function add_input() {
var list = document.getElementById("list");
var div = document.createElement("div");
var input = document.createElement("input");
var delete_button = document.createElement("button");
var br = document.createElement("br");
input.id = "input_" + (cnt++)// list.querySelectorAll("div").length
input.value = input.id;
delete_button.textContent = "Delete";
delete_button.classList.add("delete")
div.appendChild(input);
div.appendChild(delete_button);
div.appendChild(br);
list.appendChild(div);
}
window.addEventListener("load", function() {
document.getElementById("list").addEventListener("click", function(e) {
const tgt = e.target;
if (tgt.classList.contains("delete")) tgt.closest("div").remove();
})
})
<div id="list">
</div>
<button onclick="add_input()">Add</button>
I changed your code to be more effective.
I'm not using IDs as they aren't adding any benefit instead making it more complex.
Instead I target the element via the event handler and an argument.
I also wrap each set of inputs/buttons in a div so I can just remove that div and it will remove all of the children.
function add_input() {
var list = document.getElementById("list");
var input = document.createElement("input");
var delete_button = document.createElement("button");
var br = document.createElement("br");
delete_button.textContent = "Delete";
delete_button.onclick = function(e) {
e.target.parentNode.remove();
}
var div = document.createElement("div");
div.appendChild(input);
div.appendChild(delete_button);
div.appendChild(br);
list.appendChild(div)
}
<div id="list">
</div>
<button onclick="add_input()">Add</button>
I'm new to javascript and I'm trying to create a menu of buttons. In the menu, I want to add event listeners when I click a button.
My problem is I'm not sure how to implement it, to make it possible to target each button with the specific code that button need to run.
I have a button that needs to turn red when clicked and another that needs to load another site. How is it possible to achieve these things.
At the moment I generate the Buttons from a JSON document and create them in the code you can see below.
EDIT: added id attribute to javascript
function createMenu(jsonObj) {
let menu = jsonObj["menuitems"];
console.log(menu[0]);
let table = document.createElement("table");
for (let i = 0; i < menu.length; i++) {
let tableSection = document.createElement("tr");
let tableItem = document.createElement("td");
tableSection.appendChild(tableItem);
let button = document.createElement("BUTTON");
tableItem.appendChild(button);
let text = document.createTextNode(menu[i].item);
button.appendChild(text);
button.classList.add("menuButtons");
table.appendChild(tableSection);
button.setAttribute("id", menu[i].id);
button.addEventListener("click",/*What do i write here*/);
}
document.getElementById("menuDiv").appendChild(table);
}
Standards advice to not declare variable in loop. You can make an attribute (data-horsSujet) and compare the value to know what to do. Like this :
function createMenu(jsonObj) {
const menu = jsonObj["menuitems"];
console.log(menu[0]);
const table = document.createElement("table");
const myfct = function (event) {
const button = event.target;
if (button.getAttribute("data-horsSujet") == 1)
button.style.color = "red";
else
document.location = "google.fr";
}
for (let i = 0, tableSection, tableItem, button, text; i < menu.length; i++) {
tableSection = document.createElement("tr");
tableItem = document.createElement("td");
tableSection.appendChild(tableItem);
button = document.createElement("BUTTON");
tableItem.appendChild(button);
text = document.createTextNode(menu[i].item);
button.appendChild(text);
button.classList.add("menuButtons");
table.appendChild(tableSection);
button.setAttribute("id", menu[i].id);
button.addEventListener("click", myfct);
button.setAttribute("data-horsSujet", i);
}
document.getElementById("menuDiv").appendChild(table);
}
I have a table, and each row is added through JavaScript. I create these rows so that when they're clicked another cell will be created beneath them where I can display additional information. Now I want to be able to destroy the row I just created when the user clicks a button etc. So essentially, I need to be able to have the row I created have an onclick attribute, but it doesn't seem to work... I've tried everything I can think of so any help would be awesome!
var table = document.getElementById("main_table");
var row = table.insertRow(1);
row.id = count;
row.onclick = function ()
{
var id = this.id;
var target = document.getElementById(id);
var newElement = document.createElement('tr');
newElement.style.height = "500px";
newElement.id = id + "" + id;
//newElement.innerHTML = text;
target.parentNode.insertBefore(newElement, target.nextSibling );
//var newRow = document.createElement("tr");
//var list = document.getElementById(id);
//list.insertAfter(newRow,list);
var newRow = table.insertRow(newID);
}
I have tried to mimic your problem with below fiddle.
http://jsfiddle.net/kr7ttdhq/12/
newElement.onclick = createClickableCells;
del.onclick = delCell;
The above code shows the snippet from the fiddle
During the onclick event of the cell. New cells are created which in turn have the same onclick events as the first cell.
Moreover, a 'close' text cell is inserted by which you can delete the entire row.
Hope this helps
Hi I was trying to demonstrate a problem with an example in fiddle, however I am stuck in the first step. In the fiddle that follows I am trying to dynamically create a table with td containing buttons and on click of that button I want to print the event.I dont see any error in the console. But the click event is never fired. Can someone please help me. I have another problem which I need to try out after this has been fixed.
HTML
<body>
<div class="myElement" id="test">
</div>
</body>
JS
var table = document.createElement('table');
for (var i = 1; i < 4; i++){
var tr = document.createElement('tr');
var td1 = document.createElement('td');
var text1 = document.createTextNode('Text1');
var btn = document.createElement("BUTTON");
btn.className ="clickable";
var t = document.createTextNode("CLICK ME");
btn.appendChild(t);
td1.appendChild(btn);
td1.appendChild(text1);
tr.appendChild(td1);
table.appendChild(tr);
}
$('.clickable').click(function(){
alert('You clicked me');
console.log("You clicked meg");
});
var tooltipSpan = document.createElement('span');
tooltipSpan.appendChild(table);
var innerHtml = document.createElement("div");
innerHtml.appendChild(tooltipSpan);
$("#test").append(innerHtml);
https://jsfiddle.net/dzrn7rus/
I'm trying to create a table with 32 buttons.
Each button generated must have the name of a color (in turn generated for the button).
If I click on the button, placed in the table, the page background color should be with the text (color) displayed on the pressed button.
I thought about this:
var tableRef = document.getElementById('table').getElementsByTagName('tbody')[0];
var newRow = tableRef.insertRow(tableRef.rows.length);
newRow.id = "row"
Can you do this?
What advice could you give me the components to be used?
I making this in Javascript code.
Advice:
Create the entire thing using Javascript.
function createTable(){
var body=document.getElementsByTagName('body')[0];
var tbl=document.createElement('table');
tbl.setAttribute('id', tableID);
var tbdy=document.createElement('tbody');
for(var i=0;i<4;i++){
var tr=document.createElement('tr');
for(var j=0;j<8;j++){
var td=document.createElement('td');
var bt = document.createElement('button');
// add button attributes
td.appendChild(bt);
tr.appendChild(td)
}
}
tbdy.appendChild(tr);
}
tbl.appendChild(tbdy);
body.appendChild(tbl)
}
then you create the onclick method
function changeColor(color){
var body=document.getElementsByTagName('body')[0];
body.style.bgColor = color;
}
Mind you I'm doing this from memory, if the bgcolor doesn't work then try something else