Creating a table of divs - javascript

I want to create a 16*16 table in html that holds div container in each cell. I'm not sure to what degree I'm allowed to mix jquery and pure javascript but what I have is
$( document ).ready(function() {
var table = Doucument.getElementById('table');
for (var i = 0; i <16; i++) {
var row = table.insertRow(i);
for(var j = 0; j < 16; j++){
row.insertCell(i);
}
};
});
This is adding a row to my table and then adding 16 cells. However I'm not sure how to add the div element to each cell. Perhaps theres a simpler way to do this with jquery? I'm not so proficient in jquery

Change "Document" to "document", remove the loop indexes (i, j) from the insertRow() and insertCell methods, and capture the newly inserted cell so that you can populate it. I've set each div's ID to be a combination of row and cell number in the example below.
I should also point out that there are better ways to do this. Tables should only be used for displaying data that requires tables. Also, this kind of thing would ideally be done on the server side unless there's a reason for you to do it in JavaScript.
That being said, here is a working example using JavaScript:
HTML:
<table id="myTable"></table>
JavaScript:
$(document).ready(function () {
var table = document.getElementById('myTable');
for (var i = 0; i < 16; i++) {
var row = table.insertRow();
for (var j = 0; j < 16; j++) {
var cell = row.insertCell();
var id = 'r' + i + 'c' + j;
cell.innerHTML = '<div id="' + id + '">' + id + '</div>';
}
};
});
CSS (after reading your comment about controlling size):
#myTable TD DIV {
height: 30px;
width: 30px;
}
Demo: http://jsfiddle.net/BenjaminRay/ugm613zg/

Do you have a specific reason to create a "table" - it is frowned upon by UX and CSS experts. It is considered a better approach to consider creating a table-like layout using Div/Spans and CSS. There are frameworks available that can provide you this layout style out of the box.
One of the most popular ones is Bootstrap's Grid - and here are some layout examples - http://getbootstrap.com/examples/grid/. The benefit of using this approach instead of tables is that your layout will adjust better to screen size changes like say viewing on a mobile device (called responsive layout).
In the interest of full disclosure Bootstrap supports 12 columns out of the box - but modifications are available for 16 and 24 columns - How to use bootstrap with 16 or 24 columns.
This is a longer route but a better solution than tables overall.

And using jQuery, you could do the following.
function addElems(ele, howMany, append) {
var $items = $();
for (var i = 0; i < howMany; i++) {
var $ele = $("<" + ele + "/>");
typeof append !== "undefined" && $ele.append(append);
$items = $items.add($ele);
}
return $items;
}
var $table = $("#myTable").append("<tbody></tbody>");
var $trs = addElems('tr', 16);
$table.append($trs);
$table.find("tbody > tr").each(function() {
var $tds = addElems('td', 16, "<div>My Div</div>");
$(this).append($tds);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="myTable"></table>

Related

Replacing entire DIV with function

I'm attempting to start a div area with html in it and then replace that html with new html. I am currently trying to do so with the use of a function to simplify the creation of the html.
This is my function that creates a table based on input of rows and columns and a character.
function drawArt (x, y, char){
$( "#artArea").append("<table>");
indexY = 0;
while (indexY < y)
{
$( "#artArea").append("<tr>");
var indexX = 0;
while (indexX < x)
{
$( "#artArea").append("<td class=tableCell>" + char + "</td>");
indexX++;
}
$( "#artArea").append("</tr>");
indexY++;
}
$( "#artArea").append("</table>")
};
I'd like to be able to recall this function to redraw the table. So far this is what I have written but it seems to not work. Any tips?
$( "#genNew" ).click(function(){
var xGlobal = $("#numCols").val();
var yGlobal = $("#numRows").val();
var charGlobal = $("#drawChar").val();
$( "#artArea" ).replaceWith();
drawArt (xGlobal, yGlobal, charGlobal);
})
So, as suggested below changing "replaceWith" to "empty" fixed part of my problem. However, it broke another part of my program. I should be able to click on any character and get it to change to whatever was input, without changing the whole table, as so:
$( ".tableCell" ).click(function(){
charGlobal = $("#drawChar").val();
$(this).text(charGlobal)
})
Which part of my program is failing?
The big problem is you're creating invalid html. You always append to the #artArea table, so your markup will end up as
<table>
<tr></tr>
<td></td>
<td></td>
... etc
</table>
This is not what you want. What I suggest you could do is to simply create the appropriate html as a string inside drawArt and use `replaceWith to change the html
function drawArt (x, y, char){
var html = "<table>";
indexY = 0;
while (indexY < y)
{
html += "<tr>";
//-- snip, you get the idea!
}
html += "</table>"
return html;
}
and then
$( "#genNew" ).click(function(){
var xGlobal = $("#numCols").val();
var yGlobal = $("#numRows").val();
var charGlobal = $("#drawChar").val();
$( "#artArea" ).html(drawArt (xGlobal, yGlobal, charGlobal));
})
Working example: http://jsfiddle.net/0sh1wt01/1/
Having updated the question with a new requirement, I should address that too. The reason your click event handler does not work on the table cells is that click only affects elements which are on the page at the time the page loads. if you're dynamically adding new elements (as we are above) then you need to delegate the event to an element which does exist at page load. In this case we could use the artArea. Note you want .html not .text
$( "#artArea" ).on('click','.tableCell', function(){
charGlobal = $("#drawChar").val();
$(this).html(charGlobal);
});
Live example: http://jsfiddle.net/0sh1wt01/2/
You can replace the html with a new one.
This is the js code:
$("#start").click(function() {
var x = $("#rows").val(),
y = $("#columns").val(),
charx = $("#char").val();
//getting teh no of columns, rows and the character
$("#container").html("");
//empty the container first
var table = document.createElement("table");
for (var i = 0; i < x; i++) {
var tr = document.createElement("tr");
for (var j = 0; j < y; j++) {
var td = document.createElement("td");
td.innerHTML = charx;
tr.appendChild(td);
}
table.appendChild(tr);
}
//creating the table based on the values
$("#container").append(table);
//appending inside the container
});
Here is the Plnkr Link
Hope it works for you :)

How to set empty data text in a groupable kendo grid?

I am having a groupable kendo grid.
Please help me out with setting some custom text whenever the grid is empty.
If grid is not groupable i could acheive it using databound funtion.
Here's a version I adapted from KendoGridBinderEx as I wanted a function on databound that could handle not only empty but error cases too. I've modified it back to mostly suit what you're struggling with. When my datasource has errors I'll read them out of the event that I pass into the function itself, thus why you see 'e' referenced as a parameter but not used.
function DisplayNoResultsFound(evt) {
var grid = evt.sender.element;
//Only do this if you can properly find the grid
if (grid.data("kendoGrid") == undefined) {
return;
}
// Get the number of Columns in the grid
var dataSource = grid.data("kendoGrid").dataSource;
var colCount = grid.find('.k-grid-header colgroup > col').length;
//Check for an empty datasource
if (dataSource._view.length == 0) {
//Clear the grid
//you may or may not need this depending on how your datasource returns
grid.find('.k-grid-content tbody').empty();
//Add the no result row
grid.find('.k-grid-content tbody')
.append('<tr class="kendo-data-row"><td colspan="' + colCount + '" style="text-align:center" class="k-state-error"><b>No Results Found</b></td></tr>');
}
// Get visible row count
var rowCount = grid.find('.k-grid-content tbody tr').length;
// If the row count is less that the page size add in the number of missing rows
if (rowCount < dataSource._take) {
var addRows = dataSource._take - rowCount;
for (var i = 0; i < addRows; i++) {
grid.find('.k-grid-content tbody').append('<tr class="kendo-data-row"><td> </td></tr>');
}
}
}
EDIT: Here's a JSFiddle example

jQuery - Identify td that was clicked

I have created a grid (table) inside of an HTML doc based on user preference.
After appending the rows and cells to the table, it appears jQuery cannot access them properly? Its as if it doesn't consider them part of the DOM.
Essentially I will be handling everything inside of a multidimensional array for my data, such as:
[ ["","",""], ["","",""], ["","",""] ]
It is currently set up with appended rows named #row_0, #row_1, etc and td's added without an ID.
I need to be able to map the clicked TD to my jQuery so I can perform some functions and logic on it.
Is there any way to respond to my JS when a user clicks on a td with something like:
tr = [1]
td = [2]
Current code found here:
http://jsfiddle.net/HNjMR/4/
Here live example friend: http://jsfiddle.net/HNjMR/5/
$("#board").on('click', 'td', function(){
$("#board td").css("background","white");
$(this).css("background","red");
});
This happens because when you insert a new dynamic element on the page, ready jquery can not find it. The ready by default runs events only on existing elements at load time. While some functions like .on, solve this problem.
http://jsfiddle.net/898n2/1/
$( document ).on( "click", "td", function() {
alert(this.id);
});
This is using your current code
Notice I have used .on - this is a 'live' event using jquery
I have also modified your naming of each td to read col_1_2 - with 1 being col and 2 being row.
$("#row_"+i).append("<td id='col_"+j+"_"+i+"'> </td>");
when the td element click handler is added those target elements are not yet created so use event delegation and bind the click handler to the #board element with the target element selector as td as given below. Then use .index() to find the position of row and td(Add 1 to index as it is 0 based)
$("#board").on('click', 'td', function () {
var $td = $(this);
var td = $td.index() + 1,
row = $td.parent().index() + 1;
alert(td + '-' + row);
});
Demo: Fiddle
Also your create code is buggy, jQuery append does not work like string concatenation
$('#board tr').remove();
var size = parseInt($("#size").val());
for (var i = 0; i < size; i++) {
var $tr = $('<tr />', {
id: 'row_' + i
}).data('index', i + 1);
$("#board").append("<tr id='row_" + i + "'>");
for (var j = 0; j < size; j++) {
$('<td />', {
id: 'col_' + j
}).data('index', j + 1).appendTo($tr);
}
$("#board").append($tr);
}
Demo: Fiddle
Here the solution, remember that you should bind the eventclick when the elements was created, you souldn't use a generical $('td').click event, this does not work because some elements was not added in DOM yet.
$("#go").click(function(){
var size = $("#size").val();
if(size<3 || size>10){
alert("That is not a valid input. Please select 3-10");
return;
}
$('#board tr').remove();
// Check this bellow
var size = parseInt($("#size").val()),
tr = $("<tr/>"), td = $("<td/>"), tdc;
for(var i=0;i < size;i++){
for(var j=0;j<size;j++){
tdc = td.clone();
tdc.attr('id', 'col_'+j);
tr.append(tdc);
tdc.click(function(){
alert(this);
});
}
tr.attr('id','row_'+i);
$("#board").append(tr);
}
});

How can I create a table with Javascript and jQuery so that each cell is droppable?

This code works fine to create a grid of divs:
for (var i = 0; i < 10; i++) { // rows
for (var j = 0; j < 6; j++) { // columns
var id = String.fromCharCode(65 + j) + i; // e.g., B1
$('<div></div>').data('accepts', id).appendTo("#cardSlots").droppable({
accept: '#cardPile div',
hoverClass: 'hovered',
drop: handleCardDrop
});
}
$("cardSlots").append("<br />");
}
...but when I resize the window, the divs sometimes slip on to the next line. I want a table with a fixed 6x10 size, but when I try to build a table instead of divs, I break the "droppable" property.
How can I rewrite the code above so that it creates a 6x10 html table where each cell is droppable?
Try jQuery UI's Sortable library:
http://jqueryui.com/demos/sortable/
You can specify objects to be sortable just by a class or id name.
you should create a <table>, and in each cell put a div with the droppable attached to it and width:100%;height:100%;
this will solve your problem
OK, there were two things I needed to learn to do this right. The first is that appendTo is smart enough to know to put td inside tr, so this line is what allows me to create table rows on the fly:
$('<tr></tr>').appendTo("#grid");
The second is that I can identify the last (i.e., the most recently written) table row as follows:
appendTo("#grid tr:last")
So the end result (and it works perfectly, thanks Mike!) is this:
for (var i = 0; i < 10; i++) { // rows
$('<tr></tr>').appendTo("#grid");
for (var j = 0; j < 6; j++) { // columns
var id = String.fromCharCode(65 + j) + i; // e.g., B1
$('<td id="'+id+'"><div>' + id +'</div></td>').data('accepts', id).appendTo("#grid tr:last").droppable({
accept: '#stack div',
hoverClass: 'hovered',
drop: handleCardDrop
});
}
}

Hide table column ondblclick

I have a table and I want to hide a column when I double click a column.
Code for hiding a column is practically all around Stack Overflow. All I need is a hint on how/where to add the ondblclick event so I can retrieve the identity of a <td> within a <table>.
Here are two solutions that should work. One done with jQuery and one with only standard Javascript.
http://jsfiddle.net/GNFN2/2/
// Iterate over each table, row and cell, and bind a click handler
// to each one, keeping track of which column each table cell was in.
var tables = document.getElementsByTagName('table');
for (var i = 0; i < tables.length; i++) {
var rows = tables[i].getElementsByTagName('tr');
for (var j = 0; j < rows.length; j++) {
var cells = rows[j].getElementsByTagName('td');
for (var k = 0; k < cells.length; k++) {
// Bind our handler, capturing the list of rows and colum.
cells[k].ondblclick = column_hide_handler(rows, k);
}
}
}
// Get a click handler function, keeping track of all rows and
// the column that this function should hide.
function column_hide_handler(rows, col) {
return function(e) {
// When the handler is triggered, hide the given column
// in each of the rows that were found previously.
for (var i = 0; i < rows.length; i++) {
var cells = rows[i].getElementsByTagName('td');
if (cells[col]) {
cells[col].style.display = 'none';
}
}
}
}
With jQuery it is much cleaner. This method also uses event bubbling, so you don't need to bind an event handler to each table cell individually.
http://jsfiddle.net/YCKZv/4/
// Bind a general click handler to the table that will trigger
// for all table cells that are clicked on.
$('table').on('dblclick', 'td', function() {
// Find the row that was clicked.
var col = $(this).closest('tr').children('td').index(this);
if (col !== -1) {
// Go through each row of the table and hide the clicked column.
$(this).closest('table').find('tr').each(function() {
$(this).find('td').eq(col).hide();
});
}
});
You can do this way:
<td ondblclick="this.style.display = 'none';">Some Stuff</td>
Here this refers to current td clicked.
Working Example
To go unobtrusive, you can do that easily using jQuery if you want:
$('#tableID td').dblclick(function(){
$(this).hide();
});
Due to lack of answears I came up with a workaround, which is a big ugly, but it works fine.
On the window load event I decided to iterate the table and set each 's onclick event to call my show_hide_column function with the column parameter set from the iteration.
window.onload = function () {
var headers = document.getElementsByTagName('th');
for (index in headers) {
headers[index].onclick = function (e) {
show_hide_column(index, false)
}
}
}
show_hide_column is a function that can be easily googled and the code is here:
function show_hide_column(col_no, do_show) {
var stl;
if (do_show) stl = 'table-cell'
else stl = 'none';
var tbl = document.getElementById('table_id');
var rows = tbl.getElementsByTagName('tr');
var headers = tbl.getElementsByTagName('th');
headers[col_no].style.display=stl;
for (var row=1; row<rows.length; row++) {
var cels = rows[row].getElementsByTagName('td')
cels[col_no].style.display=stl;
}
}
Note: my html only had one table so the code also assumes this. If you have more table you should tinker with it a little. Also it assumes the table has table headers ();
Also I noted this to be an ugly approach as I was expecting to be able to extract the index of a table cell from the table without having to iterate it on load.

Categories

Resources