I'm developing a test build for my project, which includes a lot of data manipulation. I have two buttons inline at the end of the rows, one for editing, and one for committing the changes made.
function editRow(btn) {
var row = btn.parentNode.parentNode;
row.contentEditable = "true";
row.focus();
}
function addRow(tableID, numberOfCells) {
var tbl = document.getElementById(tableID);
//create rows
var newRow = tbl.insertRow(-1);
var i;
for (i = 0; i < numberOfCells; i++) {
newRow.insertCell(0);
}
//assignbuttons
var lastcell = newRow.cells[numberOfCells - 1];
addEditButton(lastcell);
addCommitButton(lastcell);
}
function addEditButton(context) {
var button = document.createElement("input");
button.type = "button";
button.value = "Edit";
button.onclick = editRow(this);
context.appendChild(button);
}
The user will press the new row button, and then an empty row will appear along with the two buttons.
I am getting the error:
Uncaught TypeError: Cannot read property 'parentNode' of undefined
at editRow (js.js:97)
at addEditButton (js.js:123)
at addRow (js.js:115)
at HTMLButtonElement.onclick (index.html:36)
There are 2 problems I can see.
button.onclick = editRow(this); the this would result in undefined (in strict mode) in that scope. You can probably fix this by sending in the button element
button.onclick = editRow(button);
More reading on this in a function scope
Also you are not creating a row with a td element to place the button in. So btn.parentNode.parentNode is not the row element as you are expecting
Try this
function editRow(btn) {
var row = btn.parentNode.parentNode;
row.contentEditable = "true";
row.focus();
}
function addRow(tableID, numberOfCells) {
var tbl = document.getElementById(tableID);
//create rows
var newRow = tbl.insertRow(-1);
var i;
for (i = 0; i < numberOfCells; i++) {
newRow.insertCell(0);
}
//assignbuttons
var lastcell = newRow.cells[numberOfCells - 1];
addEditButton(lastcell);
//addCommitButton(lastcell);
}
function addEditButton(context) {
var row = document.createElement("row");
var td = document.createElement("td");
var button = document.createElement("input");
button.type = "button";
button.value = "Edit";
td.appendChild(button);
row.appendChild(td);
context.appendChild(row);
button.onclick = editRow(button);
}
addRow("myTable", 2)
<table id="myTable">
</table>
function addRow(tableID, numberOfCells) {
var tbl = document.getElementById(tableID);
var tableHTML = $("#" + tableID).html();
if(numberOfCells === 5) {
$("#" + tableID).html(tableHTML + "<tr id=\"bikeTableBike_new\"><td>-</td><td>-</td><td>-</td><td>-</td><td><button id=\"editBikeButton\" class=\"tableButtons\" onclick=\"editRow(this)\"><img src=\"images/edit.png\"/></button><button id=\"deleteBikeButton\" class=\"tableButtons\" onclick=\"commitRow(this)\"><img src=\"images/commit.png\"/></button></td></tr>");
}
if(numberOfCells === 4) {
$("#" + tableID).html(tableHTML + "<tr id=\"bikeTableBike_new\"><td>-</td><td>-</td><td>-</td><td><button id=\"editBikeButton\" class=\"tableButtons\" onclick=\"editRow(this)\"><img src=\"images/edit.png\"/></button><button id=\"deleteBikeButton\" class=\"tableButtons\" onclick=\"commitRow(this)\"><img src=\"images/commit.png\"/></button></td></tr>");
}
if(numberOfCells === 3) {
$("#" + tableID).html(tableHTML + "<tr id=\"bikeTableBike_new\"><td>-</td><td>-</td><td><button id=\"editBikeButton\" class=\"tableButtons\" onclick=\"editRow(this)\"><img src=\"images/edit.png\"/></button><button id=\"deleteBikeButton\" class=\"tableButtons\" onclick=\"commitRow(this)\"><img src=\"images/commit.png\"/></button></td></tr>");
}
}
Related
Let me start by saying, I have seen very similar questions and yes; I have read through and tried to implement the suggested solutions. I am trying to have it so that only one checkbox in a row can be selected at a time. The most common answer I have seen is this one;
$('input.example').on('change', function() {
$('input.example').not(this).prop('checked', false);
});
This solution did work for me, but that was before I was creating my table dynamically. Here is my code currently. It is pulling the table data from a MySQL table via a JSON $.post.
function load() {
$.post(
"Returnsmedb.php",
function(response) {
var block = []
index = 0;
for (var item in response) {
var objectItem = response[item];
var firstname = objectItem.fname;
var lastname = objectItem.lname;
var username = objectItem.uname;
var email = objectItem.email;
var password = objectItem.password;
var deny = document.createElement("input");
deny.type = "checkbox";
deny.className = "chk";
deny.name = "deny";
deny.id = "deny";
var approve = document.createElement("input");
approve.type = "checkbox";
approve.className = "chk";
approve.name = "approve";
var moreinfo = document.createElement("input");
moreinfo.type = "checkbox";
moreinfo.className = "chk";
moreinfo.name = "moreinfo";
block.push(firstname);
block.push(lastname);
block.push(username);
block.push(email);
block.push(password);
block.push(deny);
block.push(approve);
block.push(moreinfo);
dataset.push(block);
block = [];
}
var data = [" First Name", " Last Name ", " User Name ", " Email ", "Password", " Deny", "Approve", "More Information"]
tablearea = document.getElementById('usersTable');
table = document.createElement('table');
thead = document.createElement('thead');
tr = document.createElement('tr');
for (var i = 0; i < data.length; i++) {
var headerTxt = document.createTextNode(data[i]);
th = document.createElement('th');
th.appendChild(headerTxt);
tr.appendChild(th);
thead.appendChild(tr);
}
table.appendChild(thead);
for (var i = 0; i < dataset.length; i++) {
tr = document.createElement('tr');
tr.appendChild(document.createElement('td'));
tr.appendChild(document.createElement('td'));
tr.appendChild(document.createElement('td'));
tr.appendChild(document.createElement('td'));
tr.appendChild(document.createElement('td'));
tr.appendChild(document.createElement('td')); //Added for checkbox
tr.appendChild(document.createElement('td')); //Added for checkbox
tr.appendChild(document.createElement('td')); //Added for checkbox
tr.cells[0].appendChild(document.createTextNode(dataset[i][0]));
tr.cells[1].appendChild(document.createTextNode(dataset[i][1]));
tr.cells[2].appendChild(document.createTextNode(dataset[i][2]));
tr.cells[3].appendChild(document.createTextNode(dataset[i][3]));
tr.cells[4].appendChild(document.createTextNode(dataset[i][4]));
tr.cells[5].appendChild((dataset[i][5])); //
tr.cells[6].appendChild((dataset[i][6])); //
tr.cells[7].appendChild((dataset[i][7])); //
table.appendChild(tr);
}
tablearea.appendChild(table);
}, 'json'
);
}
I have tried pasting the common solution in various areas but I still cannot get it to work. Any help would be greatly appreciated.
Thanks!
Please try this code
$('input.chk').on('change', function() {
if($('this:checked'))
{
var tr =$(this).parents('tr');
tr.find("input.chk").not(this).each(function(){
$(this).prop('checked', false);
});
}
});
A excel CSV (comma seperated value) file is uploaded initially. This CSV file is represented as a table format in an html page. Here, I need to add a radio button, button etc,along with the table formatted representation. Is this possible without usage of database?.
Thanks in advance.
function Upload() {
var fileUpload = document.getElementById("fileUpload");
var regex = /^([a-zA-Z0-9\s_\\.\-:])+(.csv|.txt)$/;
if (regex.test(fileUpload.value.toLowerCase())) {
if (typeof (FileReader) != "undefined") {
var reader = new FileReader();
reader.onload = function (e) {
var table = document.createElement("table");
var radio = document.createElement("radio");
var rows = e.target.result.split("\n");
for (var i = 0; i < rows.length; i++) {
var row = table.insertRow(-1);
var cells = rows[i].split(",");
for (var j = 0; j < cells.length; j++) {
var cell = row.insertCell(-1);
cell.innerHTML = cells[j];
}
}
var dvCSV = document.getElementById("dvCSV");
dvCSV.innerHTML = "";
dvCSV.appendChild(table);
dvCSV.appendChild(radio);
}
reader.readAsText(fileUpload.files[0]);
} else {
alert("This browser does not support HTML5.");
}
} else {
alert("Please upload a valid CSV file.");
}
}
I had created an element 'radio' inside function also appended as a child, but it doesn't displays it. My requirement is that, when each row of CSV file is placed, I need to place a radio and button there.(radio for selecting and button for editing the row element and save file).
This line
var radio = document.createElement("radio");
means <radio></radio>. However, there is no radio tag. It's <input type="radio">:
var radio = document.createElement("input");
radio.type = 'radio';
To "group" all radio buttons together, you also need to give them the same name:
radio.name = 'radio';
And if you say you need a button too, then create one:
var button = document.createElement('button');
button.textContent = 'Click me';
But most importantly, if you need them for every row, then put them there, and not somewhere else:
reader.onload = function(e)
{
var table = document.createElement("table");
var rows = e.target.result.split("\n");
for(var i = 0; i < rows.length; i++)
{
var row = table.insertRow(-1);
var cells = rows[i].split(",");
for(var j = 0; j < cells.length; j++)
{
var cell = row.insertCell(-1);
cell.innerHTML = cells[j];
}
// Here:
var radio = document.createElement("input");
radio.type = 'radio';
radio.name = 'radio';
var button = document.createElement('button');
button.textContent = 'Click me';
var cell = row.insertCell(-1);
cell.appendChild(radio);
cell.appendChild(button);
}
var dvCSV = document.getElementById("dvCSV");
dvCSV.innerHTML = "";
dvCSV.appendChild(table);
}
I am confused at to why my function executes before the start button is pressed. I looked around and they said the onclick will run at the start if you don't but the code to be executed when the button is clicked in a function. But mine is a function... This code is supposed to create 4 buttons when the start button is pressed. But right now the 4 buttons appear right away.
EDIT: Here is the full code.
var log = document.getElementById("Log");
log.addEventListener("click", login); // Runs the Login Function
var email;
var password;
// Makes an alert to test input values.
function login() {
form = document.getElementById("form");
var text = "E-Mail: " + form.elements[0].value + " Password: " + form.elements[1].value;
alert (text);
}
// Testing Function
function helloWorld() {
alert ("Hello World");
}
//create the snake
function createSnake() {
var bodyLength = 5; //snake length
var body = []; //snake body
var head = [10, 10]; //snake head starting position;
// create the variables to edit for the body positions loop
var row = head[0];
var col = head[1];
// set the snake body positions
for (var i=0;i<bodyLength; i++) {
body[body.length] = [row, col];
var cord = row + "_" + col;
// Set the head Green
if (i == 0) { document.getElementById(cord).style.backgroundColor = 'green';
}
// Set the Body blue
else {document.getElementById(cord).style.backgroundColor = 'blue';}
row++;
}
}
var snakeBool = false; //Bool to test if the snake game has been pressed.
// Create a table function. Creates a gray table for Snake.
function createTable() {
if (!snakeBool) {
// create a table of data
//target the activity div
var activity = document.getElementById("activity");
//create table
var tbl = document.createElement("table");
//table styles
tbl.style.borderCollapse = "collapse";
tbl.style.marginLeft = '12.5px';
//create size var
//var size = '5px';
//set the row and column numbers
var tr_num = 30;
var td_num = 25;
//start the loops for creating rows and columns
for (var i = 0; i < tr_num; i++) {
var tr = document.createElement("tr"); // create row
//tr style
tr.style.height = '7px';
for (var j = 0; j < td_num; j++) { //start loop for creating the td
var td = document.createElement("td"); //create td
td.style.width = '5px';
if (i == 0 || i == (tr_num-1) || j == 0 || j == (td_num-1)) {
td.style.backgroundColor = "white";
}
else {
td.style.backgroundColor = "gray";
}
td.id = i + "_" + j; //set id to td
//td.appendChild("data"); //append data to td
tr.appendChild(td); //append td to row
}
tbl.appendChild(tr); //append tr to the table
}
activity.appendChild(tbl); //append the table to activity div
createSnake(); //Creates the snake body.
snakeBool = true; //Sets the Snake Bool to true since game has been created.
//create Start button
var b1 = document.createElement("input");
b1.type = "button";
b1.value = "Start";
b1.onClick = startGame;
activity.appendChild(b1);
} // end of if Function
}
function startGame() {
createButtons();
}
function createButtons() {
var b1 = document.createElement("input");
b1.type = "button";
b1.value = "Up";
//b1.onClick = func
activity.appendChild(b1);
var b2 = document.createElement("input");
b2.type = "button";
b2.value = "Down";
//b1.onClick = func
activity.appendChild(b2);
var b3 = document.createElement("input");
b3.type = "button";
b3.value = "Left";
//b1.onClick = func
activity.appendChild(b3);
var b4 = document.createElement("input");
b4.type = "button";
b4.value = "Right";
//b1.onClick = func
activity.appendChild(b4);
}
// when button is pressed, do createTable function
document.getElementById("gamesButton").addEventListener("click", createTable);
Using the brackets, you’re immediately invoking the startGame function. Its return value is then assigned to the onClick property.
You most likely want to assign the function itself, so it’s executed when the onClick event fires. To do so, change this
b1.onClick = startGame();
to this
b1.onClick = startGame;
I am creating a javascript based "favourite assignment" list for my photo app which I have created using phonegap.
I'm basing it on a "to-do list" tutorial code and have tried to adapt it to my purposes.
There are two variables: the title (text) and the link (text2)
It works great in a browser, and on first launch in the app.
But on refresh or relaunch, I dont think it's saving the link variable to the dictionary.
would appreciate any guidance with the code:
<script type="text/javascript" language="JavaScript">
//Create a new To-Do
function createNewToDo()
{
var todoDictionary = {};
//Prompt the user to enter To-Do
var todo="FAST SHUTTER SPEEDS";
var todolink="#fastshutter";
if (todo!=null)
{
if (todo == "")
{
alert("To-Do can't be empty!");
}
else
{
//Append the new To-Do with the table
todoDictionary = { check : 0 , text : todo , text2 : todolink};
addTableRow(todoDictionary,false);
}
}
}
//Add a row to the table
var rowID = 0;
function addTableRow(todoDictionary, appIsLoading)
{
rowID +=1;
var table = document.getElementById("dataTable");
var rowCount = table.rows.length;
var row = table.insertRow(rowCount);
//Set up the CheckBox
var cell1 = row.insertCell(0);
var element1 = document.createElement("input");
element1.type = "deleteButton";
element1.value = "X";
element1.setAttribute("onclick","deleteSelectedRow(this)");
element1.className = "deleteButton";
cell1.appendChild(element1);
//Set up the View Button
var cell2 = row.insertCell(1);
var element2 = document.createElement("input");
element2.type = "viewButton";
element2.value = todoDictionary["text"];
var link = todoDictionary["text2"];
element2.id = rowID;
element2.onclick=function(){ window.location.hash = link; };
element2.className = "viewButton";
cell2.appendChild(element2);
//Save & Update UI
saveToDoList();
if (!appIsLoading)
alert("Assignment Added To Favourite List!");
}
//Deletes current row
function deleteSelectedRow(deleteButton)
{
var p=deleteButton.parentNode.parentNode;
p.parentNode.removeChild(p);
saveToDoList();
}
function saveToDoList()
{
//Create a todoArray
var todoArray = {};
var checkBoxState = 0;
var textValue = "";
var text2Value = "";
//Get current table
var table = document.getElementById("dataTable");
var rowCount = table.rows.length;
if (rowCount != 0)
{
//Loop through all rows
for(var i=0; i<rowCount; i++)
{
var row = table.rows[i];
//Add checkbox state
var chkbox = row.cells[0].childNodes[0];
if(null != chkbox && true == chkbox.checked)
{
checkBoxState = 1;
}
else
{
checkBoxState= 0;
}
//Add text data
var textbox = row.cells[1].childNodes[0];
textValue = textbox.value;
//Fill the array with check & text data
todoArray["row"+i] =
{
check : checkBoxState,
text : textValue
};
}
}
else
{
todoArray = null;
}
//Use local storage to persist data
//We use JSON to preserve objects
window.localStorage.setItem("todoList", JSON.stringify(todoArray));
}
function loadToDoList()
{
//Get the saved To-Do list array by JSON parsing localStorage
var theList = JSON.parse(window.localStorage.getItem("todoList"));
if (null == theList || theList=="null")
{
deleteAllRows();
}
else
{
var count = 0;
for (var obj in theList)
{
count++;
}
//Clear table
deleteAllRows();
//Loop through all rows
for(var i=0; i<count; i++)
{
//Add row
addTableRow(theList["row"+i],true);
}
}
}
It appears that in the saveToDoList function you aren't adding your text2 value to the array of objects that's saved to localStorage:
todoArray["row"+i] =
{
check : checkBoxState,
text : textValue
};
Should be:
todoArray["row"+i] =
{
check : checkBoxState,
text : textValue,
link : // get the value of your link
};
Since you haven't posted the associated HTML I cannot tell you how to get the value of the link
I am trying to create mine field game. "I am very new to Js".
What I have done so far:
var level = prompt("Choose Level: easy, medium, hard");
if (level === "easy") {
level = 3;
} else if (level === "medium") {
level = 6;
} else if (level === "hard") {
level = 9;
}
var body = document.getElementsByTagName("body")[0];
var tbl = document.createElement("table");
var tblBody = document.createElement("tbody");
for (var i = 1; i <= 10; i++) {
var row = document.createElement("tr");
document.write("<br/>");
for (var x = 1; x <= 10; x++) {
var j = Math.floor(Math.random() * 12 + 1);
if (j < level) {
j = "mined";
} else {
j = "clear";
}
var cell = document.createElement("td");
var cellText = document.createTextNode(j + " ");
cell.appendChild(cellText);
row.appendChild(cell);
}
tblBody.appendChild(row);
}
tbl.appendChild(tblBody);
body.appendChild(tbl);
tbl.setAttribute("border", "2");
So I create here 2d table and enter 2 random values in rows and columns (mined or clear).
Where I am stuck is:
Check if td = mined it dies otherwise open the box(td) etc.
How do I assign value of td? I mean how can I check which value(mined/clear) there is in the td which is clicked?
Ps: Please don't write the whole code:) just show me the track please:)
Thnx for the answers!
Ok! I came this far.. But if I click on row it gives sometimes clear even if I click on mined row or vice versa!
// create the table
var body = document.getElementsByTagName("body")[0];
var tbl = document.createElement("table");
tbl.setAttribute('id','myTable');
var tblBody = document.createElement("tbody");
//Create 2d table with mined/clear
for(var i=1;i<=10;i++)
{
var row = document.createElement("tr");
document.write("<br/>" );
for(var x=1;x<=10;x++)
{
var j=Math.floor(Math.random()*12+1);
if(j<level)
{
j = "mined";
}
else{
j = "clear";
}
var cell = document.createElement("td");
var cellText = document.createTextNode(j + "");
cell.appendChild(cellText);
row.appendChild(cell);
}
tblBody.appendChild(row);
}
tbl.appendChild(tblBody);
body.appendChild(tbl);
tbl.setAttribute("border", "2");
//Check which row is clicked
window.onload = addRowHandlers;
function addRowHandlers() {
var table = document.getElementById("myTable");
var rows = table.getElementsByTagName("tr");
for (i = 0; i < rows.length; i++) {
var currentRow = table.rows[i];
var createClickHandler =
function(row)
{
return function() {
var cell = row.getElementsByTagName("td")[0];
var id = cell.innerHTML;
if(id === "mined")
{
alert("You died");
}else
{
alert("clear");
}
};
}
currentRow.onclick = createClickHandler(currentRow);
}
}
I think I do something wrong with giving the table id "myTable"..
Can you see it?
Thank you in advance!
So, the idea would be:
assign a click event to each td cell:
td.addEventListener('click', mycallback, false);
in the event handler (callback), check the content of the td:
function mycallback(e) { /*e.target is the td; check td.innerText;*/ }
Pedagogic resources:
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/td?redirectlocale=en-US&redirectslug=HTML%2FElement%2Ftd
https://developer.mozilla.org/en-US/docs/DOM/EventTarget.addEventListener
JavaScript, getting value of a td with id name