I am trying to build a pixel marker webpage for a project. It is almost completed. I am facing a couple of problems:
Unable to fill in the color, when a <td> tag is clicked.
The wells that contain the color options and the input value to the grid, over flow the vertical line when I resize the browser. I need the width tag here because I want it to fill 100% of the column size it is located in. I had to use a hard coded value here because if I use 100% as the width value, the wells fill the entire width of the window when the browser is resized.
Your elements are dynamically created. You need to target an element available on page load and make use of event delegation.
– Obsidian AgeMar 18 '18 at 19:21
@ObsidianAge. Thank you for your prompt reply. The elements have already been loaded. I am trying to access the
tags once all the elements have been created. Could you please give me an example of how could I use event delegation here? Because in a grid, the user can select any of the
tags. And the only way I can think of to target that element is by using `this` keyword.
Because your elements are dynamically created, you need to attach the click event handler to an element that is available on page load, and make use of event delegation. Instead of $('td').click(), you're looking for $('body').on("click", "td", function() {} ).
Also note that in addition to this, your concole.log should be console.log.
I've corrected this in the following example:
$(document).ready(function() {
$("#grid-input").click(function() {
$(".drawing-area").empty();
var rows = $("#row").val();
var cols = $("#col").val();
if (rows > 0 && cols > 0) {
if (rows < 8 || cols < 8) {
for (var i = 1; i <= rows; i++) {
var rowClassName = 'row' + i;
var tr = $('<tr>').addClass(rowClassName);
tr.appendTo('.drawing-area'); //Adding dynamic class names whenever a new table row is created
for (var j = 1; j <= cols; j++) {
var colClassName = 'col' + j;
$('<td width="30px" height="30px" style="border: 1px solid #000; "></a></td>').addClass(colClassName).appendTo(tr);
}
$('.drawing-area').append('</tr>');
}
$('.drawing-area').css('visibility', 'visible').hide().fadeIn('slow');
} else if ((rows >= 8 && rows <= 20) && (cols >= 8 && cols <= 50)) {
for (var i = 1; i <= rows; i++) {
var rowClassName = 'row' + i;
var tr = $('<tr>').addClass(rowClassName);
tr.appendTo('.drawing-area'); //Adding dynamic class names whenever a new table row is created
for (var j = 1; j <= cols; j++) {
var colClassName = 'col' + j;
$('<td width="20px" height="20px" style="border: 1px solid #000; text-align: center;"></a></td>').addClass(colClassName).appendTo(tr);
}
}
$('.drawing-area').css('visibility', 'visible').hide().fadeIn('slow');
} else if (rows > 20 || cols > 50) {
alert('Bamm!!! Your input will flood the browser\'s belly');
}
} else {
alert("You haven't provided the grid size!");
}
});
$('body').on("click", "td", function() {
var color = $("input[name='color']:checked").val();
console.log(color);
if (color === 'blue') {
if ($(this).hasClass('colorFill-Blue'))
$(this).removeClass('colorFill-Blue');
else
$(this).addClass('colorFill-Blue');
} else if (color === 'green') {
if ($(this).hasClass('colorFill-Green'))
$(this).removeClass('colorFill-Green');
else
$(this).addClass('colorFill-Green');
alert("green is selected");
} else {
if ($(this).hasClass('colorFill-Yellow'))
$(this).removeClass('colorFill-Yellow');
else
$(this).addClass('colorFill-Yellow');
}
});
});
Your td elements are dynamically created, but your code uses $("td").click(…) which only binds to the TD elements at the time that is called. Instead of binding an event on the existing TDs, a simpler and more efficient fix is to bind the event to a more static ancestor. The table element is a static ancestor, so changing your click definition to $('table').on('click','td',function(){...}) will ensure that the dynamic TDs are included.
This means when you click anywhere in the table, the function will see if the target was a td and if so it will call the included function.
You had an error in the code, where what should have been console was spelled concole.
I've fixed both of these below:
$(document).ready(function() {
$("#grid-input").click(function() {
$(".drawing-area").empty();
var rows = $("#row").val();
var cols = $("#col").val();
if (rows > 0 && cols > 0) {
if (rows < 8 || cols < 8) {
for (var i = 1; i <= rows; i++) {
var rowClassName = "row" + i;
var tr = $("<tr>").addClass(rowClassName);
tr.appendTo(".drawing-area"); //Adding dynamic class names whenever a new table row is created
for (var j = 1; j <= cols; j++) {
var colClassName = "col" + j;
$(
'<td width="30px" height="30px" style="border: 1px solid #000; "></a></td>'
)
.addClass(colClassName)
.appendTo(tr);
}
$(".drawing-area").append("</tr>");
}
$(".drawing-area")
.css("visibility", "visible")
.hide()
.fadeIn("slow");
} else if (rows >= 8 && rows <= 20 && (cols >= 8 && cols <= 50)) {
for (var i = 1; i <= rows; i++) {
var rowClassName = "row" + i;
var tr = $("<tr>").addClass(rowClassName);
tr.appendTo(".drawing-area"); //Adding dynamic class names whenever a new table row is created
for (var j = 1; j <= cols; j++) {
var colClassName = "col" + j;
$(
'<td width="20px" height="20px" style="border: 1px solid #000; text-align: center;"></a></td>'
)
.addClass(colClassName)
.appendTo(tr);
}
}
$(".drawing-area")
.css("visibility", "visible")
.hide()
.fadeIn("slow");
} else if (rows > 20 || cols > 50) {
alert("Bamm!!! Your input will flood the browser's belly");
}
} else {
alert("You haven't provided the grid size!");
}
});
$("table").on('click', 'td', function() {
var color = $("input[name='color']:checked").val();
console.log(color);
if (color === "blue") {
if ($(this).hasClass("colorFill-Blue"))
$(this).removeClass("colorFill-Blue");
else $(this).addClass("colorFill-Blue");
} else if (color === "green") {
if ($(this).hasClass("colorFill-Green"))
$(this).removeClass("colorFill-Green");
else $(this).addClass("colorFill-Green");
alert("green is selected");
} else {
if ($(this).hasClass("colorFill-Yellow"))
$(this).removeClass("colorFill-Yellow");
else $(this).addClass("colorFill-Yellow");
}
});
});