having trouble removing an extra row from a dynamically created table - javascript
I'm trying to dynamically create a table using JS and jQuery. (I know I can hard code it in html but I don't want to do that.)
I have an extra row at the table that I'm having trouble removing.
Can someone please provide an answer/answers on how best to solve this in my code?
My code is posted below.
var game = {
matrix: [],
startGame: function()
{
this.doDomStuff(); //build board
},
doDomStuff: function(row, column)
{
for(var i = 0; i < 7; i++)
{
var row = $('<div>');
row.attr('id', 'data-row' + (i + 1));
row.addClass('data-row');
for(var j = 0; j < 6; j++)
{
var column = $('<div>');
column.attr('id', 'data-column' + (j + 1));
column.addClass('data-column');
column.addClass('column');
row.append(column);
}
$('body').prepend(row);
}
}
};
If you are making a game, and each row can have its own logic and behaviour, so it will be faster to operate array neither DOM structure. If your logic will be more complecated, you will see the difference in perfomance. So, call the DOM structure if you are really need to update objects there. For example:
function SuperTable(){
this.tablerows = [];
this.DOMObject = $("body");
}
SuperTable.prototype.AddRow = function() {
this.tablerows[this.tablerows.length] = new SuperRow(this.tablerows.length,this.DOMObject);
}
SuperTable.prototype.RemoveRow = function(rowIndex) {
this.tablerows[rowIndex].DOMObject.remove(); // remove element from DOM
this.tablerows.splice(rowIndex,1); // remove element from logic of the game
}
function SuperRow(rownumber,parent) {
this.DOMObject = $("<div>");
this.DOMObject.addClass('data-row');
parent.prepend(this.DOMObject);
}
mytable = new SuperTable()
mytable.AddRow() // create row on 0 position
mytable.RemoveRow(0) // remove row from 0 position
You can use JQuery's .remove() function.
For example, if you want to remove the last row: $("#data-row7").remove()
Related
How to remove all children from an element using jQuery?
I have a script that creates a table with specifications given by the user. The issue is that when the table is printed more than once, it prints below the other table. Turning a 10x10 table into a 10x20 table. (if that makes sense) In previous assignments I used: //Clean grid while(grid.firstChild) grid.removeChild(grid.firstChild); to clear the grid, but this assignment is using jQuery and I am not sure how to do it. I've tried: var divBlock = document.getElementById('my_table'); while (divBlock.firstChild) { divBlock.removeChild(divBlock.firstChild); and $("#my_table").empty(); and $("#my_table").remove(); and $('#my_table').remove('table'); but neither seem to work, here is the full code: // TODO: clear table var $rows = $("#rows"); var $cols = $("#cols"); var $print_button = $("#print"); var $my_table = $("#my_table"); var $stats = $("#stats"); var arr = []; var $table_obj = $('<table>'); //Create an element var $row_obj; var $col_obj; var counter = 0; $print_button.on('click', function() {print_pattern();}); function print_pattern() { // Clear table // var divBlock = document.getElementById('my_table'); // while (divBlock.firstChild) { // divBlock.removeChild(divBlock.firstChild); // } // $("#my_table").empty(); $('#my_table').remove('table'); // Get row and column values var r = $rows.val(); //Get value of rows element var c = $cols.val(); //Get value of cols element // Create 2-D Array for (var i = 0; i < r; i++) { arr[i] = []; } // Double for-loop to create table for (var i = 0; i < r; i++) { $row_obj = $('<tr>'); // Create row for (var j = 0; j < c; j++) { $col_obj = $('<td>'); // Create table cell var n = Math.floor(Math.random()*10000)%100; //Math methods: floor and random $($col_obj).append(n); // Append random number to table cell $($row_obj).append($col_obj); // Append column to row $($table_obj).append($row_obj); // Append row to table object // if random number > 90 -> make background color yellow if (n > 90) { $col_obj.css('background-color', 'yellow'); //Change css counter++; // counter for stats } } $($table_obj).append($row_obj); // Append row to table object } $($my_table).append($table_obj); // Append table to div container // Stats calculation $stats.html("<b>" + (counter/(r*c)*100).toFixed(2) + "%<b>"); //Change html content counter = 0; // reset counter // event function for removing a row when its clicked on $('tr').on('click', function(){ $(this).fadeOut(500); }); } So I've tried a number of things, I am not sure if I am just getting the syntax wrong or if I am using the wrong function to clear the div tag. If anyone can point me in the right direction that would help a lot! Thank you. EDIT: I figured out the issue. My original while() block worked fine when I put all the variables inside the function.
First of all, you have to distinguish variables. A. There is a variable that has to define 1 time, and any changes will be stored on that. B. And there is a variable that needs to be reset every function called. variable on condition b you need put inside your function so it won't keep last value and make it has double value (last value + new value) in this case i could say this variable is on condition b: $table_obj, $row_obj, $col_obj, arr, ...
Javascript grid calculation
I am creating a game where I represent boxes with a two dimensional array of their id. var grid = [[X,X,X,X,X,X,X,X,X,X], [X,X,4,4,4,4,X,X,X,X], [X,3,3,3,3,X,X,X,X,X], [X,X,X,2,2,2,2,X,X,X], [X,1,1,1,1,5,5,5,5,5]]; The boxes stack on top of each other, and X represents a blank spot. If one of the boxes are deleted I want any of the boxes above (That can fit) to shift down. So they are always neatly stacked. So if I was to delete the box with ID: 1 I would get a new grid like this: var grid = [[X,X,X,X,X,X,X,X,X,X], [X,X,4,4,4,4,X,X,X,X], [X,3,3,3,3,X,X,X,X,X], [X,X,X,2,2,2,2,X,X,X], [X,X,X,X,X,5,5,5,5,5]]; Then I would want Box: 3 to slide down into its spot like so: var grid = [[X,X,X,X,X,X,X,X,X,X], [X,X,4,4,4,4,X,X,X,X], [X,X,X,X,X,X,X,X,X,X], [X,X,X,2,2,2,2,X,X,X], [X,3,3,3,3,5,5,5,5,5]]; Finally Box: 4 should move down into where 3 was: var grid = [[X,X,X,X,X,X,X,X,X,X], [X,X,X,X,X,X,X,X,X,X], [X,X,4,4,4,4,X,X,X,X], [X,X,X,2,2,2,2,X,X,X], [X,3,3,3,3,5,5,5,5,5]]; Is there an easy way of doing this? I was thinking of a callback that checks the grid when a box is destroyed but what I came up with was mostly IF statements. Is there something elegant out there? The box class itself also has the start position and its length: box = {id: 3, start: 1, length: 4};
This is actually not an easy task. I created a little fiddle that does what you wanted to achieve (i think). I extended the box prototype with some functions. My solution relies on the variables grid and blocks, but you could abstract that even more if you like to. The functions testFunctionality and printGridToElement are just there for testing purposes. My new Box prototype: function Box(i, s, l) { this.id = i; this.start = s; this.length = l; this.row; blocks.push(this); } Box.prototype.insertIntoGrid = function (row) { this.row = row; if (!grid[row]) grid[row] = []; for (var i = 0; i < this.length; i++) { grid[row][this.start + i] = this.id; } }; Box.prototype.destroy = function () { blocks.splice(blocks.indexOf(this), 1); this.removeFromGrid(); this.checkRemainingBlocksForMoveDown(); }; Box.prototype.checkRemainingBlocksForMoveDown = function () { for (var i = 0; i < blocks.length; i++) { var btmd = blocks[i].checkForMoveDown(); if (btmd) { btmd[0].move(btmd[1]); btmd[0].checkRemainingBlocksForMoveDown(); } } } Box.prototype.move = function (row) { this.removeFromGrid(); this.insertIntoGrid(row); }; Box.prototype.removeFromGrid = function () { for (var i = 0; i < this.length; i++) { grid[this.row][this.start + i] = 0; } }; Box.prototype.checkForMoveDown = function () { for (var i = 0; i < this.row; i++) { var move = true; for (var j = 0; j < this.length; j++) { if (grid[i][this.start + j] != 0) { move = false; break; } } if (move) { return [this, i]; } } }; and the usage of it: var b1 = new Box(1, 1, 4); b1.insertIntoGrid(0); var b2 = new Box(2, 3, 4); b2.insertIntoGrid(1); var b3 = new Box(3, 1, 4); b3.insertIntoGrid(2); var b4 = new Box(4, 2, 4); b4.insertIntoGrid(3); var b5 = new Box(5, 5, 5); b5.insertIntoGrid(0); b1.destroy(); b2.destroy(); b3.destroy(); NOTE: I designed the grid with 0 being the lowest row
I'm late, but here goes. You should probably swap rows, and columns. That is make it like: var rows = []; column = [x,x,x,x,x,x,x,x]; rows.push(column); Instead of: var columns = []; var row = [x,x,x,x,x,x,x,x]; columns.push(row); This way a drop is just an array operation on columns. You can then do things like splice out a block, splice in a block, unshift, shift, and so on. Do the array operations before animations, but not before you get the column, and row information from the grid. You can even name the methods that do it by array methods. shift drops the bottom block, splice(start, stop, [optional]new block). Like that. #Markai did swap the columns, and rows in their answer, but I thought I'd add some clarity.
This is what I came up with (Not working but the gist) fallCheck = function(deletedPosition, deletedLength) { var fallable = grid.reduce( function(array, row) { var unique = row.filter(function(item, i, ar) { return ar.indexOf(item) === i;}); var id = unique.find( function(boxId) { var box = boxes.iterate("id", boxId, Phaser.Group.RETURN_CHILD); //Finds the instance within a Phaser Group return (box.start >= deletedPosition) && (box.start + box.length) <= (deletedPosition + deletedLength); }); if (id != -1) array.push(id); }, []); if (fallable.length > 0) { fall(fallable[0]); } //fall simply moves the box to the lowest position on the grid };
Combing Slickgrid example 4 and example 9 (adding row reordering to dataview)
I'm trying to figure out how to combine Slickgrid's example 4 and example 9. Basically adding row reordering to a dataview grid. So far I have row reordering working as long as there is only one page in the grid. With multiple pages, row reordering works only on the first page and on any other pages, rows can be dragged up or down, but will not reorder. example 4: https://github.com/mleibman/SlickGrid/blob/master/examples/example4-model.html example 9: https://github.com/mleibman/SlickGrid/blob/master/examples/example9-row-reordering.html Any ideas? Thanks so much! Here is the row reordering code I have on my dataview grid: //Re-order rows on drag var moveRowsPlugin = new Slick.RowMoveManager({}); moveRowsPlugin.onBeforeMoveRows.subscribe(function (e, inboxData) { for (var i = 0; i < inboxData.rows.length; i++) { // no point in moving before or after itself if (inboxData.rows[i] == inboxData.insertBefore || inboxData.rows[i] == inboxData.insertBefore - 1) { e.stopPropagation(); return false; } } return true; }); moveRowsPlugin.onMoveRows.subscribe(function (e, args) { var extractedRows = [], left, right; var rows = args.rows; var insertBefore = args.insertBefore; left = inboxData.slice(0, insertBefore); right = inboxData.slice(insertBefore, inboxData.length); rows.sort(function(a,b) { return a-b; }); for (var i = 0; i < rows.length; i++) { extractedRows.push(inboxData[rows[i]]); } rows.reverse(); for (var i = 0; i < rows.length; i++) { var row = rows[i]; if (row < insertBefore) { left.splice(row, 1); } else { right.splice(row - insertBefore, 1); } } inboxData = left.concat(extractedRows.concat(right)); var selectedRows = []; for (var i = 0; i < rows.length; i++) selectedRows.push(left.length + i); inboxGrid.resetActiveCell(); inboxDataView.setItems(inboxData); inboxGrid.setSelectedRows(selectedRows); inboxGrid.render(); }); inboxGrid.registerPlugin(moveRowsPlugin); //End re-order rows
I'm not sure, but maybe these methods will help you: inboxGrid.invalidateAllRows(); //tells the grid that all the rows has been changed and it needs to rerender them. inboxGrid.invalidateRows(rows); // tells the grid that the specified rows has been changed and it needs to rerender them. You also need to use beginUpdate and endUpdate when updating the dataView: inboxDataView.beginUpdate(); inboxDataView.setItems(inboxData); inboxDataView.endUpdate(); Hope these help.
JQuery not replacing html
here is the deal, i have the following jquery code that should add the array values to specific #id, buf it does not replace the code, only add more, and i need a little help to make it replace the html on othe link click. Code: function changeClass(curClass){ switch(curClass){ case "Schoolgirl": case "Fighter": var charSkillsNames = ["text1","text2","text4","text5"]; //loop show array values listSkillsNames(charSkillsNames); break; } } function listSkillsNames(arr){ var length = arr.length, element = null; $("#skills").html(function(){ for (var i = 0; i < length; i++) { element = arr[i]; $(this).append("<li>"+element+"</li>"); } }); } this works well but i need it to replace the html inside the "#skills" id when i click on the link that makes it work PS: problem is really here
The issue is that you don't empty the HTML of #skills element. Use $("#skills").html("") to empty it. function listSkillsNames(arr){ var length = arr.length, element = null; var $skills = $("#skills"); $skills.html(""); // empty the HTML for (var i = 0; i < length; i++) { element = arr[i]; $skills.append("<li>"+element+"</li>"); // append new items } }
The problem is because you are keep appending new items to the element always without removing the existing items. Just empty the skill element, also there is no need to use the .html(function(){}) here function listSkillsNames(arr) { var length = arr.length, element = null; var $skill = $("#skills").empty(); for (var i = 0; i < length; i++) { element = arr[i]; $skill.append("<li>" + element + "</li>"); } }
JavaScript delete merged table cell
I have been working on a scheduling website for the past few weeks. I am showing the schedules as PHP generated html-tables. I use merged cells for showing events. I have come to a problem when trying to delete events using JS. Since those are merged cells, using rowspan, I have to go through the table and re-adding empty cells whenever there is a need when I delete one. My solution is working fine for when my table contains one merged cell among nothing but empty cells, but with a more complex table, it fails. I can't really grasp what's wrong with it, except that it doesn't correctly find the cellIndex anymore. Does anyone have a clue? Here is what I'm talking about: http://aturpin.mangerinc.com/table.html (Click on an event to remove it, or attempt to anyhow)
This sample may help you find your solution. It seems to demonstrate your problem as well as have some sample code to generate a matrix to help you solve it. EDIT: I liked the puzzle and decided to play with it for a bit, here is a "functioning" example of implementing that sample (although sometimes the table doesn't seem to redraw correctly. This should probably help you get further along the way. function getTableState(t) { var matrix = []; var lookup = {}; var trs = t.getElementsByTagName('TR'); var c; for (var i=0; trs[i]; i++) { lookup[i] = []; for (var j=0; c = trs[i].cells[j]; j++) { var rowIndex = c.parentNode.rowIndex; var rowSpan = c.rowSpan || 1; var colSpan = c.colSpan || 1; var firstAvailCol; // initalized the matrix in this row if needed. if(typeof(matrix[rowIndex])=="undefined") { matrix[rowIndex] = []; } // Find first available column in the first row for (var k=0; k<matrix[rowIndex].length+1; k++) { if (typeof(matrix[rowIndex][k])=="undefined") { firstAvailCol = k; break; } } lookup[rowIndex][c.cellIndex] = firstAvailCol; for (var k=rowIndex; k<rowIndex+rowSpan; k++) { if(typeof(matrix[k])=="undefined") { matrix[k] = []; } var matrixrow = matrix[k]; for (var l=firstAvailCol; l<firstAvailCol+colSpan; l++) { matrixrow[l] = {cell: c, rowIndex: rowIndex}; } } } } // lets build a little object that has some useful funcitons for this table state. return { cellMatrix: matrix, lookupTable: lookup, // returns the "Real" column number from a passed in cell getRealColFromElement: function (cell) { var row = cell.parentNode.rowIndex; var col = cell.cellIndex; return this.lookupTable[row][col]; }, // returns the "point" to insert at for a square in the perceived row/column getPointForRowAndColumn: function (row,col) { var matrixRow = this.cellMatrix[row]; var ret = 0; // lets look at the matrix again - this time any row that shouldn't be in this row doesn't count. for (var i=0; i<col; i++) { if (matrixRow[i].rowIndex == row) ret++; } return ret; } }; } function scheduleClick(e) { if (e.target.className != 'event') return; //Get useful info before deletion var numRows = e.target.rowSpan; var cellIndex = e.target.cellIndex; var rowIndex = e.target.parentNode.rowIndex; var table = e.target.parentNode.parentNode; var tableState = getTableState(table); var colIndex = tableState.getRealColFromElement(e.target); //Deletion e.target.parentNode.deleteCell(cellIndex); //Insert empty cells in each row for(var i = 0; i < numRows; i++) { var row = table.rows[rowIndex + i]; row.insertCell(tableState.getPointForRowAndColumn(rowIndex+i, colIndex)); } }