My table is being populated using ajax from a mysql database. I have a text field below it which adds the entered data to the database. All this works fine, but what i want to do is on adding that new row to the table, i want to dynamically show the user that their entry has been added (or simply refresh that div when new field has been added). Currently aim able to achieve that using a simple function:
function addItem(new_item, edit_table) {
var itemName = new_item;
var newRow = document.createElement('tr');
var rowCell = document.createElement('td');
rowCell.textContent = itemName;
// rowCell.addClass("grid");
newRow.appendChild(rowCell);
edit_table.appendChild(newRow);
}
However this does not let me add extra functionalities to that row e.g. i have a delete and edit icon upon hover. So by using this function i am able to show the new row added but its not exactly functioning. So i recon the better option would be to refresh that div when this happens.
I am using the following code to call the addItems method:
$('#b_go').click(function(){
//some other conditions, then using ajax to post the data
success: function (data) {
if(data == 'success') {
addItem(new_row, selected_table);
}
HTML for the table:
<table class="table table-striped table-bordered home" id="subjects">
<thead>
<th>Subject Title</th>
</thead>
<tbody>
<?php
$sql = mysql_query("select Title from Subject");
while($row = mysql_fetch_array($sql)) {
echo "<tr><td>";
echo $row['Title']?> <!--using html to output buttons for delete and edit for each row-->
<?;echo "</td></tr>";
}
?>
</tbody>
</table>
Css for the above table:
.table {
width: 100%;
margin-bottom: 18px;
}
.table th, .table td {
padding: 8px;
line-height: 18px;
text-align: left;
border-top: 1px solid #ddd;
}
.table th {
font-weight: bold;
vertical-align: bottom;
}
.table td {
vertical-align: top;
}
.table thead:first-child tr th, .table thead:first-child tr td {
border-top: 0;
}
.table-striped tbody tr:nth-child(odd) td, .table-striped tbody tr:nth-child(odd) th {
background-color: #f9f9f9;
}
.home {
width: 100%;
border-collapse: collapse;
text-align: left;
}
.home th {
font-size: 15px;
font-weight: 400;
color: #039;
padding: 10px 8px;
border-bottom: 2px solid #6678b1;
}
.home td {
line-height:15px;
border-bottom: 1px solid #E0E0E0;
border-left: 1px solid #E0E0E0;
font-size: 12px;
color: #404040;
padding: 9px 8px 3px 8px;
}
.home tbody tr:hover td {
background-color:#E6E6FF;
cursor: pointer;
}
Any help would be appreciated!
I have to leave work, but here's a quick and dirty answer.
When adding new elements dynamically that have pre-existing functions/events/actions that are already bound, the new elements will not automatically inherent the events/actions of their siblings. I recommend using jQuery for something like this.
For jQuery versions greater than 1.3 - use jQuery LIVE() function:
http://api.jquery.com/live/
Description: This will map the data passed to your new event handlers needed
For jQuery versions 1.7 or higher - use jquery ON() function:
http://api.jquery.com/on/
Description: method attaches event handlers to the currently selected set of elements in the jQuery object. This will attach the event handler to any new element you create.
Update: 11:57 AM Tuesday: Based on your comment. You need to use bind('click') or on('') function when you SUBMIT the form.
// First : Change your click code to this. You'll need the bind() function here. This will make it so your events will bind to each new row
$('#b_go').bind("click", function(){
//some other conditions, then using ajax to post the data
success: function (data) {
if(data == 'success') {
addItem(new_row, selected_table);
}
// Change your function to this:
function addItem(new_item, edit_table) {
var itemName = new_item;
var newRow = document.createElement('tr');
var rowCell = document.createElement('td');
rowCell.textContent = itemName;
$(rowCell).addClass("grid"); // Make sure GRID is the class being applied to your other TDs/TRs etc
newRow.appendChild(rowCell);
edit_table.appendChild(newRow);
$(edit_table +' tr:odd td').css('background','#f9f9f9'); // Set color for all odd rows.
}
HOW TO RELOAD TABLE:
STEP #1 - Create a new < div > layer with an ID #getDataGrid. THIS MUST WRAP AROUND YOUR TABLE.
STEP #2 - Create a new file like : data-grid.php and include the following HTML. Please also include any PHP business logic that would be needed to make the appropriate database calls to make this code successful:
<table class="table table-striped table-bordered home" id="subjects">
<thead>
<th>Subject Title</th>
</thead>
<tbody>
<?php
$sql = mysql_query("select Title from Subject");
while($row = mysql_fetch_array($sql)) {
echo "<tr><td>";
echo $row['Title']?> <!--using html to output buttons for delete and edit for each row-->
<?;echo "</td></tr>";
}
?>
</tbody>
</table>
STEP #3 : Update your click function:
$('#b_go').bind("click", function(){
//some other conditions, then using ajax to post the data
success: function (data) {
if(data == 'success') {
addItem(new_row, selected_table);
$.get('data-grid.php', function(getTable) {
$('#getDataGrid').html(getTable);
});
}
EXPLANATION. What this is doing on your click function is using jQuery to essentially perform a "GET" (just as PHP GET would perform). We are retrieveing our newly created data-grid.php file, and then PLACING the contents into the #getDataGrid div layer we created that wraps around the table. What this will do will actually wipe out the currently displayed table with the new displayed table.
Instead of only partially using a DOM approach, create the TD in javascript too.
function addItem(itemName) {
var newRow = document.createElement('tr');
var rowCell = documentcreateElement('td');
rowCell.textContent = itemName;
newRow.appendChild(rowCell);
document.getElementById('subjects').appendChild(newRow);
}
Do you have JQuery? You can make something similar in JS, but here's the concept.
Create a template of the new row in HTML
Add the row to the DB.
Add the row to the table:
var row = $("#myRowTemplate").clone();
row.attr("id", "");
//Bind the new data
row.find(".fname").text("Jack");
row.find(".lname").text("Dean");
//Bind a click event on the first name
row.find(".fname").click(function(){alert('Hi!');});
$("#myTable").find("tbody :first").append(row);
Hopes that's helps :)
Related
I have a two columned HTML table which I want to translate from English to Greek.
I desire to do that by double-clicking the Click to translate placeholder under the Greek column and then being prompted there, to insert a Greek text instead it.
In other words, I would interact with the HTML file to translate where the placeholder, right from web browser.
Any such (raw data) change should saved in the HTML file directly, without involving database programs such as a MySQL; thus, this program is aimed to be HTML-CSS-JS only.
table, th, td {
border: 1px solid black;
}
<!DOCTYPE html>
<html>
<body>
<section class="allEnglishSections">
<h2>Conditioning</h2>
<table>
<tr><th>English</th><th>Greek</th></tr>
<tr><td>if</td><td class="changeable">Click to translate</td></tr>
<tr><td>than</td><td class="changeable">Click to translate</td></tr>
<tr><td>else</td><td class="changeable">Click to translate</td></tr>
</table>
</section>
<script>
</script>
</body>
</html>
From searching data on how to achieve this, I understand I should use something similar to this pseudocode:
document.querySelectorAll(".changeable").addEventListener(ondblclick, function() {
myTranslation = prompt();
document.querySelector(".changeable").value = myTranslation;
}
But it is unclear to me how to actually selecting all text of a cell by double clicking it, and then changing it directly from web browser in such a way that the HTML file would change.
Is this even possible with latest ECMAScript and if so how will you achieve this?
An easy system would be to create a textarea inside the HTML on double click, and whenever you experience either the blur event or a specific key combination to remove the textarea and swapping it with a text node of it's own value.
Please note that I am added the events onto the tbody element. This is done because most events bubble up, and this way no matter how many <tr> elements get added in dynamically, I will have the same functionality without having to loop over the nodelist and add the event one-by-one.
I also use focusout instead of blur for a similar reason: blur does not bubble up, but focusout does.
Note The current version using the localStorage won't work on StackOverflow due to sandboxed permissions and so on. Copy/Paste the values into something like JSFiddle or Codepen to see a working example. I personally tested it on this JSFiddle in case you want to look at it.
I also did not use an example with AJAX/XHR as you seem relatively new to Javascript, and that needs for you to look up how REST APIs / XHR work. Feel free to make another question once you've done some fiddling with those, but for now that felt a bit out-of-scope for this question.
// get items from storage. if nothing is there originally we will get a null value
const fromStorage = localStorage.getItem('definitions');
// null values are falsey, so if it is null we need to use our default.
// otherwise we just JSON.parse the values we retrieved
const definitions = !fromStorage ? {
"if": null,
"when": null,
"tomato": null,
} : JSON.parse(fromStorage);
// I don't feel like running this command everytime I need to reference the tbody,
// thus, the reference to it here.
const tbody = document.querySelector('#definitions');
// adding an event listener on the tbody means that any of the same event that bubble up from it's children will reach here.
// This means you can add children in dynamically without needing to worry so long as they have
// a data-editorShown attribute
tbody.addEventListener('dblclick', e => {
const parent = e.target.parentElement;
// if somehow the event gets called from something that is NOT one of the TDs, we don't need to go any further from there.
// sidenote, all values in the Element.dataset are read as strings. you can set them to be whatever
// but when you read them, they will be strings.
if (parent.tagName !== 'TR' || parent.dataset.editorShown === 'true') return;
// The editor is now shown, so let's set that
parent.dataset.editorShown = true;
// get the last TD, which is where we will put our textarea
const dataTd = parent.querySelector('td:last-child');
// create a new textarea element
const textarea = document.createElement('textarea');
// the textarea gets some class
textarea.classList.add('full');
// and a placeholder
textarea.placeholder = "Double click to translate";
// the arguments for this function are backwards to me, but I think it's self explanatory what's happening
dataTd.replaceChild(textarea, dataTd.firstChild);
// get that focus on the textarea.
dataTd.firstChild.focus();
});
function blurOrKeypress(e) {
// split up largely for readability
if (e.target.tagName !== 'TEXTAREA') return false;
if (e.type === 'keypress' && e.code != 'Enter' && !e.ctrlKey) return false;
// a parent, a row, and a newly minted text node walk into a bar...
const parent = e.target.parentElement;
const row = parent.parentElement;
const text = document.createTextNode(e.target.value || 'Double click to translate');
/* .isConnected refers to it's state in the DOM. this was some work to try and stop an error that was
ocurring due to this being simultaneously the 'blur' 'keypress' event handler. Alas, it didn't.
If the error is really an issue, then wrapping the parent.replaceChild in a try/catch block should solve it for you.*/
if (e.target.isConnected) {
// use the dataset key + the textarea's value to update the definitions.
definitions[row.dataset.key] = e.target.value;
// write those to the local storage
localStorage.setItem('definitions', JSON.stringify(definitions));
// Or, if you are using a database, you would use some variety of AJAX/XHR call here.
// get rid of our text element
parent.replaceChild(text, e.target);
// reset the editorshown value in case we need to update this again
row.dataset.editorShown = false;
}
}
// the one thing I miss about jquery event listeners: adding multiple types of event by putting spaces
tbody.addEventListener('keypress', blurOrKeypress);
tbody.addEventListener('focusout', blurOrKeypress);
// gets the key/value pairs and maps them
tbody.append(...Object.entries(definitions).map(([word, translation]) => {
// table row, key TD and value TD cells.
const tr = document.createElement('tr');
const keyTd = document.createElement('td');
const valueTd = document.createElement('td');
// editor is not shown by default
tr.dataset.editorShown = false;
// we use this in an upper function.
tr.dataset.key = word;
// add the bold class just for visual interest. you do not need to do this.
keyTd.classList.add('bold');
// set the inner text to our word
keyTd.innerText = word;
// if it's already set, great! use that. otherwise, 'double click to translate'
valueTd.innerText = translation || 'Double click to translate';
// add these two values to our newly minted tr tag.
tr.append(keyTd, valueTd);
// return the TR tag so that the above tbody.append gets an element to actually append
return tr;
}));
/* Styling here to make myself feel better*/
textarea.full {
height: 1.5rem;
width: 100%;
padding: 3px;
line-height: 1.5rem;
}
.bold {
font-weight: bold;
}
td.bold {
font-style: unset;
}
table {
border-collapse: collapse;
width: 100%;
}
td {
color: #111;
width: 50%;
border: 1px solid lightgray;
box-sizing: border-box;
padding: 5px 10px;
border-width: 1px 0;
font-style: italic;
}
th {
border: 2px solid lightgray;
border-width: 0 0 2px;
padding-bottom: 6px;
text-decoration: underline;
font-style: unset;
font-size: 1.15rem;
}
tbody tr:nth-child(odd) {
background-color: lightgray;
}
<table>
<thead>
<tr>
<th>Word/Phrase</th>
<th>Translation</th>
</tr>
</thead>
<tbody id="definitions">
<!-- HTML generated later -->
</tbody>
</table>
I'll work on an example using contentEditable when I come back to comment this when I wake up. Hope it helps in the meantime.
Try using getElementById.
const if_in_greek = document.getElementById('translate-if');
const than_in_greek = document.getElementById('translate-than');
const else_in_greek = document.getElementById('translate-else');
if_in_greek.ondblclick = function() {
if_in_greek.innerHTML = "Translation of IF goes here"
}
than_in_greek.ondblclick = function() {
than_in_greek.innerHTML = "Translation of THAN goes here"
}
else_in_greek.ondblclick = function() {
else_in_greek.innerHTML = "Translation of ELSE goes here"
}
table,
th,
td {
border: 1px solid black;
}
<section class="allEnglishSections">
<h2>Conditioning</h2>
<table>
<tr>
<th>English</th>
<th>Greek</th>
</tr>
<tr>
<td>if</td>
<td id="translate-if">Click to translate</td>
</tr>
<tr>
<td>than</td>
<td id="translate-than">Click to translate</td>
</tr>
<tr>
<td>else</td>
<td id="translate-else">Click to translate</td>
</tr>
</table>
</section>
( UPDATED: See last section. )
One way of doing this, is to create an object which maps english words to greek words, and then add an eventlistener that catches the double click event on the table element, checks if the 'click to translate' element has been clicked and do the translation:
const dict = {
if: "αν",
than: "από",
else: "αλλιώς"
}
document.querySelector("table").addEventListener("dblclick", function(e){
// Check if the .changeable element has triggered the click event
if ( e.target.classList.contains("changeable")){
// Get the text content from the sibling element which contains the english word
const word = e.target.previousElementSibling.textContent;
// Check if we have the word in our dictionary
if ( dict[word] ){
// Change the text content of the 'click to translate' element with the greek word
e.target.textContent = dict[word];
}
}
});
table {
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
<section class="allEnglishSections">
<h2>Conditioning</h2>
<table>
<tr><th>English</th><th>Greek</th></tr>
<tr><td>if</td><td class="changeable">Click to translate</td></tr>
<tr><td>than</td><td class="changeable">Click to translate</td></tr>
<tr><td>else</td><td class="changeable">Click to translate</td></tr>
</table>
</section>
Updated
Notes: As #Jhecht correcly pointed out, the querySelectorAll returns a NodeList that needs to be iterated. The easiest way to do that, is through the forEach method available to the NodeList object. The code would be written like this:
document.querySelectorAll(".changeable").forEach(function(element){
element.addEventListener( "dblclick", function(){ /* CODE HERE */ } );
});
If you see trying to attach multiple event listeners to a web page, you should reconsider your choice and instead attach a single event listener on a parent object which will be receiving all the events of its inner children. I applied this pattern in my solution.
Since the question has been updated, and the intentions are more clear, I am adding another code that enables the user to double click on the Click to translate area and allow them to enter a custom value:
document.querySelector("table").addEventListener("dblclick", function(e){
if ( e.target.classList.contains("changeable")){
e.target.setAttribute("contenteditable", true);
if ( e.target.textContent === "Click to translate" ){
e.target.textContent = "";
e.target.focus();
}
}
});
<section class="allEnglishSections">
<h2>Conditioning</h2>
<table>
<tr><th>English</th><th>Greek</th></tr>
<tr><td>if</td><td class="changeable">Click to translate</td></tr>
<tr><td>than</td><td class="changeable">Click to translate</td></tr>
<tr><td>else</td><td class="changeable">Click to translate</td></tr>
</table>
</section>
var $TABLE = $('#table');
var $BTN = $('#export-btn');
var $EXPORT = $('#export');
$('.table-add').click(function () {
var $clone = $TABLE.find('tr.hide').clone(true).removeClass('hide table-line');
$TABLE.find('table').append($clone);
});
$('.table-remove').click(function () {
$(this).parents('tr').detach();
});
$('.table-up').click(function () {
var $row = $(this).parents('tr');
if ($row.index() === 1) return; // Don't go above the header
$row.prev().before($row.get(0));
});
$('.table-down').click(function () {
var $row = $(this).parents('tr');
$row.next().after($row.get(0));
});
// A few jQuery helpers for exporting only
jQuery.fn.pop = [].pop;
jQuery.fn.shift = [].shift;
$BTN.click(function () {
var $rows = $TABLE.find('tr:not(:hidden)');
var headers = [];
var data = [];
// Get the headers (add special header logic here)
$($rows.shift()).find('th:not(:empty)').each(function () {
headers.push($(this).text().toLowerCase());
});
// Turn all existing rows into a loopable array
$rows.each(function () {
var $td = $(this).find('td');
var h = {};
// Use the headers from earlier to name our hash keys
headers.forEach(function (header, i) {
h[header] = $td.eq(i).text();
});
data.push(h);
});
// Output the result
$EXPORT.text(JSON.stringify(data));
});
.table-editable {
position: relative;
.glyphicon {
font-size: 20px;
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.0/jquery.min.js"></script>
<div class="container">
<h1>HTML5 Editable Table</h1>
<p>Through the powers of <strong>contenteditable</strong> and some simple jQuery you can easily create a custom editable table. No need for a robust JavaScript library anymore these days.</p>
<ul>
<li>An editable table that exports a hash array. Dynamically compiles rows from headers</li>
<li>Simple / powerful features such as add row, remove row, move row up/down.</li>
</ul>
<div border="1" id="table" class="table-editable">
<span class="table-add glyphicon glyphicon-plus"></span>
<table style="border: 1px solid black;" class="table">
<tr>
<th>Name</th>
<th>Value</th>
<th></th>
<th></th>
</tr>
<tr>
<td contenteditable="true">Stir Fry</td>
<td contenteditable="true">stir-fry</td>
<td>
<span class="table-remove glyphicon glyphicon-remove"></span>
</td>
<td>
<span class="table-up glyphicon glyphicon-arrow-up"></span>
<span class="table-down glyphicon glyphicon-arrow-down"></span>
</td>
</tr>
<!-- This is our clonable table line -->
<tr class="hide">
<td contenteditable="true">Untitled</td>
<td contenteditable="true">undefined</td>
<td>
<span class="table-remove glyphicon glyphicon-remove"></span>
</td>
<td>
<span class="table-up glyphicon glyphicon-arrow-up"></span>
<span class="table-down glyphicon glyphicon-arrow-down"></span>
</td>
</tr>
</table>
</div>
<button id="export-btn" class="btn btn-primary">Export Data</button>
<p id="export"></p>
</div>
I am using the selection. I am selecting a value and getting the result in an input box, but the problem is, it is only working in the first row of my selection and not working when I am clicking second selection. Here is the code, Please share if you can solve this one or advice.
<script type="text/javascript">
function displayResult()
{
document.getElementById("mycall1").insertRow(-1).innerHTML = '<td><select id = "forcx" onchange="fillgap()"><option>Select</option> <option>Force</option><option>Angle</option><option>Area</option></select></td>';
document.getElementById("mycall2").insertRow(-1).innerHTML = '<td><input type="text" id="result1" size = "10" ></td>';
}
function fillgap(event){
var xnumb = 20;
var forcxlist = document.getElementById("forcx");
var forcxlistValue = forcxlist.options[forcxlist.selectedIndex].text;
if (forcxlistValue == "Force"){
document.getElementById("result1").value = xnumb;
}
}
</script>
Ok, so if i understand correctly
1) You want to add the: selection, results & + to the existing table
2) Add the options Force, Angle & Area to the select
3) If Force is selected, put the value '20' in the results td
4) When the + is clicked, a new row is added.
5 The newly added rows should behave exactly the same.
Given the above, I have done the following, I'm using jQuery as its simpler and I'm more familiar with it. Its easy.
The trick here is event delegation. at the time your page loads the new rows don't exist, that's why your JavaScript isn't working on them. you can read about it here: https://learn.jquery.com/events/event-delegation/
Here's the result:
$(document).ready(function() {
// add headers to table
$('table tr:first-child').append('<th>Result</th><th>Add</th>');
//add fields to table
$('table tr:not(:first-child)').append('<td><select class="selection"><option></option><option value="Force">Force</option><option value="Angle">Angle</option><option value="Area">Area</option></select></td><td class="result"></td><td><button type="button" class="displayResultBtn">+</button></td>');
// add new row when button is clicked
$('table').on('click','.displayResultBtn', function( event) {
var tRow = $(this).parent().parent().clone();
$(this).parents('table').append(tRow);
$('table tr:last-child td.result').empty();
});
// when the dropdown is changed, update the result to 20 if "Force" is selected.
$('table').on('change','.selection', function( event) {
var selection = $(this).val();
if (selection == "Force") {
$(this).parent().next().html('20');
// You can add more coditionals if you want to add didferent values for the other options.
} else {
$(this).parent().next().empty();
}
});
});
table,
td,
th {
border: 1px solid black;
white-space: nowrap;
}
table {
border-collapse: collapse;
width: 30%;
table-layout: auto;
}
td {
text-align: center;
vertical-align: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<table>
<tr>
<th>To</th>
<th>From</th>
<th>Detail</th>
<th>Selection</th>
</tr>
<tr>
<td>A</td>
<td>B</td>
<td>A+B</td>
</tr>
</table>
It's hard to answer with limited code provided, but I think your issue is that you are using id multiple times. Which is invalid. id should be unique and used once only.
I have put together some demo code here that will hopefully help you. It doesn't solve your exact problem(I dont have your html so i cant fully solve it). but hopefully this will give you an idea of how to handle accessing different rows, or specific unique ids.
I'm using jQuery here for simplicity, but the principle is the same:
Here's a fiddle if thats easier to play with: https://jsfiddle.net/BradChelly/4179e26q/
I hope this helps somewhat.
// highlight row by child selectors (:last-child)
$('#selectLastRowBtn').click(function(){
//clear any previous highlighting
$('#myTable tr:not(:first-child)').css('background-color','white');
// highlight the last row in the table.
$('#myTable tr:last-child').css('background-color','lightgrey');
});
// highlight row using a specific unique id
$('#selectRowByIdBtn').click(function(){
//get selected row id from dropdown
var rowId = $('#rowSelector option:selected').val();
//clear any previous highlighting
$('#myTable tr:not(:first-child)').css('background-color','white');
//highlight the row with the matching id from the selection dropdown
$('#myTable #row_'+rowId).css('background-color','lightgrey');
});
//
// ------Below is just stuff to make demo work, not relevant to the question
//
// Add row with unique id
$('#addNewRowBtn').click(function(){
var rowCount = $('#myTable tr').length;
$('#myTable').append('<tr id="row_'+rowCount+'"><td>23124</td><td>23124</td><td>23124</td><td>23124</td></tr>');
populateSelect(rowCount);
});
// populate select options
function populateSelect(rowCount){
$('#rowSelector').append('<option value="'+rowCount+'">'+rowCount+'</option>')
}
table {
width: 100%;
text-align: center;
}
table td {
border: 1px solid #333;
padding: 30px 0px;
}
table tr:first-child {
top: 0px;
background: #333;
}
table tr:first-child th {
color: #fff;
padding: 20px 0px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<table id="myTable">
<tr>
<th>Column One</th>
<th>Column Two</th>
<th>Column Three</th>
<th>Column Four</th>
</tr>
<tr id="row_1">
<td>23124</td>
<td>23124</td>
<td>23124</td>
<td>23124</td>
</tr>
</table>
<button id="addNewRowBtn">Add Row</button>
<h3>Using child selectors:</h3>
<button id="selectLastRowBtn">Highlight last row using child selector</button>
<h3>Highlight a row by id:</h3>
<select name="" id="rowSelector">
<option value="1">1</option>
</select>
<button id="selectRowByIdBtn">Highlight row by selected id</button>
I am new to Javascript so take it easy on me. I want to change data inside a table using javascript. I have looked everywhere for a suitable tutorial but I haven't found any. This is my code.
function trans() {
var table = document.getElementById("table");
var row = table.getElementsByTagName("tr")[2];
var td = row.getElementsByTagName("td")[0];
td.innerHTML = "Julius";
}
**css**
table {
width: 100%;
border-collapse: collapse;
font-family: calibri;
}
tr,
th,
td {
border: 2px solid black;
padding: 10px 10px 10px 10px;
}
thead {
background-color: black;
color: white;
}
tbody {
background-color: white;
color: black;
}
.center {
text-align: center;
}
.caption {
text-align: center;
}
button {
background-color: blue;
color: white;
border-radius: 5px;
height: 25px;
}
<html>
<body>
<table id="table" title="Employment status verses Living Conditions">
<caption>Employment status verses Living Conditions</caption>
<thead>
<tr>
<th colspan="3" class="caption">Employment status verses Living Conditions</th>
</tr>
<tr>
<th>Name</th>
<th>State</th>
<th>Condition</th>
</tr>
</thead>
<tr>
<td>Antony</td>
<td>Employed</td>
<td>Poor</td>
</tr>
<tr>
<td>Grace</td>
<td>Student</td>
<td>Wealthy</td>
</tr>
<tr>
<td>Jane</td>
<td>Sponsored</td>
<td>Self actualization</td>
</tr>
<tr>
<td>Christine</td>
<td colspan="2" class="center"><i>Unknown</i>
</td>
</tr>
<tr>
<td rowspan="2">James and John</td>
<td>Fishermen</td>
<td>Spiritual</td>
</tr>
<tr>
<td>Brothers</td>
<td>Disciples</td>
</tr>
</table>
<button onclick="trans()">Change name</button>
</body>
</html>
When I run the code it gives me the following error,
{
"message": "Uncaught TypeError: table.getElementByTagName is not a function",
"filename": "http://stacksnippets.net/js",
"lineno": 96,
"colno": 15
}
I have changed the getElementByTagName to getElementsByTagName but it is still giving me an error, What is wrong with my code and what can I do to fix it. Find my jsfiddle here
This works:
Code snippet
Try this:
function trans() {
var table = document.getElementById("table");
var row = table.getElementsByTagName("tr")[2];
var td = row.getElementsByTagName("td")[0];
td.innerHTML = "Julius";
}
You selected the first tr that has no td , only th in it and you also forgot "s" in "getElementsByTagName".
Because with "Tag" you can get more then 1 element you need to add "s" , when it's by ID it makes sense that you will get only 1 item therefor no "s" is needed.
You're missing an s in your last line of Code.
Also, data already contains the element you want to edit, so there's no need to call getElementsByTagName on data.
Change this Line
data.getElementByTagName("td")[0].innerHTML = "Julius"
To
data.innerHTML = "Julius";
This should suffice.
function trans() {
var table = document.getElementById("table"),
tr = table.getElementsByTagName('tr')[2],
td = tr.getElementsByTagName('td')[0];
td.innerHTML = "Julius";
}
Issues:
In order to select a certain key "[2]" you need to use .getElementsByTagName instead of .getElementsByTagName;
You're targeting the wrong tr. There are tr's in the table head. So even with fixing the number 1 issue, you would not get the correct result.
I am dynamically inserting a table row (or multiple rows) into a table upon an ajax call's return. I am looking to accomplish this by having an empty container type element inside of my html table that I can insert <tr> elements into. As I have seen from other posts, a div cannot hold a tr element, so my question is, is there a particular way that I can insert the html for row(s) into a table? It must be dynamic in nature, or in other words I need to be able to hold more than just one <tr>.
You can append to last row of table.
<table>
<tr><td>First Row</td></tr>
<tr><td>Middle Row</td></tr>
<tr><td>Last Row</td></tr>
</table>
<script>
$( "#tableid tr:last" ).append(
</script>
Assuming you aren't using jQuery, you can do something like this:
var myTable = document.getElementById('myTable').getElementsByTagName('tbody')[0];
var row = myTable.insertRow(myTable.rows.length);
You can then insert cells using insertCell on row.
Alternatively, if you have jQuery,
$("#myTable").append("<tr><td>Table Row with cell!</td></tr>");
I'm not sure why you wouldn't just use the <table> element directly, but you can use <tbody> elements as row containers within a table.
onload = function(){
document.getElementById("aButton").onclick = addRow.bind(null, "a");
document.getElementById("bButton").onclick = addRow.bind(null, "b");
}
function addRow(id) {
var r = document.getElementById(id).insertRow(-1);
var c = r.insertCell(-1);
c.innerHTML = "Row added at " + new Date().toLocaleTimeString();
}
body {
font-family: sans-serif;
font-size: 12px;
}
table {
border-collapse: collapse;
margin: 8px 0;
}
td {
border: 1px solid #ccc;
padding: 1px 2px;
}
<button id="aButton">Add row to 'A'</button>
<button id="bButton">Add row to 'B'</button>
<table>
<tbody><tr><td>Before A</td></tr></tbody>
<tbody id="a"></tbody>
<tbody>
<tr><td>After A</td></tr>
<tr><td>Before B</td></tr>
</tbody>
<tbody id="b"></tbody>
<tbody><tr><td>After B</td></tr></tbody>
</table>
<table id="tab">
<tr><td class="here">dgd</td><td class="here">dfg</td></tr>
<tr><td class="here">fgf</td><td class="here">sg4</td></tr>
</table>
<table id="new">
<tr><td id="al">sss</td></tr>
</table>
#tab td {
padding: 5px;
border: solid 1px red;
}
#new td {
padding: 5px;
height: 40px;
border: solid 1px green;
background-color: green;
}
#new {
display: none;
}
$(".here").click(function(){
$("#new").show();
})
$("#al").click(function(){
alert('ok');
})
LIVE: http://jsfiddle.net/HTHnK/
How can i modify this example for add position in jQuery? I would like - if i click on .here then table id = new should show me on this clicked TD. Additionally if i clicked outside table id = new then this should hide.
How can i make it?
You want to be like this?
http://jsfiddle.net/HTHnK/6/
You want an event handler on the whole page, which will respond to clicks on it, but not on clicks within certain areas.
Use event.stopPropogation() to prevent the page from responding to certain areas:
$('.item').click(function(event){
$('#context').show();
event.stopPropogation();
});
$('body').click(function(){
$('#context').hide();
});
jsfiddle
If you're saying that the green box should be moved to the same position as the clicked cell (via absolute positioning, as compared to appending it as a child of the clicked cell) then you could try something like this:
$(document).on("click", function(e) {
var $el = $(e.target);
if ($el.hasClass("here")) {
$("#new").css({'left': e.target.offsetLeft,
'top': e.target.offsetTop}).show();
} else {
$("#new").hide();
}
});
Which processes clicks on the document. If the click is in one of the ".here" cells it moves the green box, otherwise it hides it.
Demo: http://jsfiddle.net/HTHnK/16/
Are you looking to move text from the source cell to the new table cell?
http://jsfiddle.net/dnrar/