I have a table body object stored as a string. I've tried setting an HTML table using javascript to be that string as follows (the {{}} are because I'm using Flask to get the string):
Way 1:
document.getElementsByTagName("tbody")[0].outerHTML= "{{tbody_string }}";
Way 2:
document.getElementsByTagName("table")[0].outerHTML = '<table>' + "{{tbody_string }}" + '</table>'
Way 3:
document.getElementsByTagName("table")[0].innerHTML = "{{tbody_string}}";
None of these is working. Instead, the table is created and is storing tbody_string as actual text content instead of treating it as html. I've used these sort of structures and flask variables with other HTML elements such as input and it works fine, but it's not seeming to work with table. Thoughts?
Extra Info:
The string looks like this:
'<tbody> <tr> <td>Name</td> <td> <input type="text" name="parameters_name" id="name" class="form-control"> </td> </tr> </tbody>'
The outer quotes are simply shown here to indicate it's a string.
Jinga2 is probably escaping your html when you render it with {{tbody_string}}. You can tell it not to do that with {{tbody_string|safe}}.
Ultimately you can get rid of your "javascript ways" entirely and just render it directly with Jinja2.
Also...please note that if there is any user editable data in your tbody_string, you'll want to take the necessary precautions to avoid creating a security loophole.
Here is javascript code for table
var body = document.getElementsByTagName("body")[0];
var ourTable = document.createElement("table");
var ourTableBody = document.createElement("tbody");
for (var i = 0; i < 4; i++) {
var row = document.createElement("tr");
for (var j = 0; j <2; j++) {
var cell = document.createElement("td");
var cellText = document.createTextNode("cell in row "+i+", column "+j);
cell.appendChild(cellText);
row.appendChild(cell);
}
ourTableBody.appendChild(row);
}
ourTable.appendChild(ourTableBody);
body.appendChild(ourTable);
ourTable.setAttribute("border", "2");
If your table body object stored as a string (aka tbody_string) is a string that goes something like tbody_string = "<table><tr><th>table</th></td></table>"
Way 3 should work fine
<html>
<body>
<table>
<tr>
<th>Replace this table</th>
</tr>
</table>
</body>
<script lang="javascript">
const tbody_string = `
<table>
<tr>
<th>Table</th>
</tr>
<tr>
<td>this is replaced table</td>
</tr>
</table>`;
document.getElementsByTagName('table')[0].innerHTML = tbody_string;
</script>
</html>
However, if your tbody_string isn't HTML markup text but something else.
you'll need to convert it to HTML as text somehow. if it's a DOM element object, the following code should work:
document.getElementsByTagName('table')[0].innerHTML = table_dom.innerHTML
Related
I have a table in my html that is populated dynamically from a JSON file. Once the page loads and the table is populated, some columns contain strings that are urls. I had a script that was able to search the table and assign a class to any string that started with 'http'.
I am trying to rework that script so that it will search the table (td cells), find the strings that start with 'http', convert them to hyperlinks and open the url on a new tab (_blank). But, it is not working. Can someone point out where I'm going wrong in the script below? I know there is the link() method but it is depreciated so I don't want to use it.
The table is identified by ID (#YukonTerr_FR) in the script.
Thanks!
var tds4 = document.querySelectorAll("#YukonTerr_FR td");
for (var i = 0; i < tds4.length; i++) {
var str4 = tds4[i].innerText;
var link = document.createElement("a");
if (str4.includes("https")) {
link.setAttribute("href", "str4");
link.setAttribute("target", "_blank");
link.appendChild(document.createTextNode("str4"));
}
}
You need to clear the content of the td and append the newly created "a" element to the td. Also, use the variable str4, not the string "str4"
var tds4 = document.querySelectorAll("#YukonTerr_FR td");
for (var i = 0; i < tds4.length; i++) {
var str4 = tds4[i].innerText;
var link = document.createElement("a");
if (str4.includes("https")) {
tds4[i].innerText = ""; //Clear content of td
link.setAttribute("href", str4);
link.setAttribute("target", "_blank");
link.appendChild(document.createTextNode(str4));
tds4[i].appendChild(link); // Add the new link to td
}
}
<b>Before:</b>
<table>
<tr>
<td>https://www.google.com</td>
</tr>
<tr>
<td>Just a string</td>
</tr>
<tr>
<td>https://amazon.com</td>
</tr>
</table>
<p></p>
<b>After:</b>
<table id="YukonTerr_FR">
<tr>
<td>https://www.google.com</td>
</tr>
<tr>
<td>Google</td>
</tr>
<tr>
<td>https://amazon.com</td>
</tr>
</table>
Your code doesn't appear to have any obvious errors, but I can't see where you're adding it back to the table. Something like:
...
tds4[i].appendChild(link)
I have the function where I want to get the value for first td in each table row. While looping I want to compare each of these values with the date value that user picked. After comparing the dates I need to get the position where that value should be placed in the table. Here is example of my code:
HTML Table:
<table id="tblBody_DBA">
<tbody>
<tr id="Att_5258717">
<td>03/28/2017</td>
<td></td>
</tr>
<tr id="Att_5258339">
<td>03/25/2017</td>
<td>03/26/2017</td>
</tr>
<tr id="Att_5258337">
<td>03/22/2017</td>
<td>03/24/2017</td>
</tr>
<tr id="Att_5258332">
<td>03/16/2017</td>
<td>03/21/2017</td>
</tr>
<tr id="Att_5258331">
<td>03/10/2017</td>
<td>03/15/2017</td>
</tr>
</tbody>
</table>
function sortRow(distType, rowId){
var newVal = document.getElementById("newDate").value; //this is new value that I have to compare against existing values and return position in the table.
var tblID = document.getElementById("parentTable").value;
var table = window.parent.document.getElementById("tblBody_"+tblID);
var arrayDates = [];
for(var i=0; table.rows.length; i++){
//Here I'm getting JavaScript error: TypeError: table.rows[i] is undefined
alert(table.rows[i].cells[0].innerHTML);
}
}
I'm getting value for each table cell in alert box but on the end error shows in my debugger. If anyone can help please let me know. I'm not able to use JQuery, plain JavaScript is the only way to et this done in my case.
You can just grab the first td from each tr specifically:
var table = document.getElementById('tblBody_DBA');
var targetTDs = table.querySelectorAll('tr > td:first-child');
for (var i = 0; i < targetTDs.length; i++) {
var td = targetTDs[i];
console.log(td.innerHTML);
}
First you get all of the tr elements using var allTr = document.querySelectorAll ('tr')
Then you loop through them and get the text from the first td
for (var i = 0; i < allTr.length; i++) {
allTr [i].firstChild.innerHTML;
}
<table id="tblBody_DBA">
<tbody>
<tr id="Att_5258717">
<td>03/28/2017</td>
<td></td>
</tr>
<tr id="Att_5258339">
<td>03/25/2017</td>
<td>03/26/2017</td>
</tr>
<tr id="Att_5258337">
<td>03/22/2017</td>
<td>03/24/2017</td>
</tr>
<tr id="Att_5258332">
<td>03/16/2017</td>
<td>03/21/2017</td>
</tr>
<tr id="Att_5258331">
<td>03/10/2017</td>
<td>03/15/2017</td>
</tr>
</tbody>
</table>
<script>
function sortRow(distType){
var table = document.getElementById(distType); //this is new value that I have to compare against existing values and return position in the table.
for (var i = 0; i < table.rows.length; i++) {
var firstCol = table.rows[i].cells[0]; //first column
console.log(firstCol.innerHTML);// or anything you want to do with first col
}
}
sortRow("tblBody_DBA");
</script>
The main issue is in the for loop's end condition. You did not provide a comparison with i and so it was continuing beyond the last row of the table, producing the error you got.
To find the row for which the input date falls between the dates in the first and second column, you'll need to convert those values to dates and then do a comparison:
// Parse text as date and convert to an absolute day number
newVal = Math.floor(Date.parse(newVal) / 24*60*60*1000);
for(var i=0; i < table.rows.length; i++){
// Do the same conversion for the table texts
var start = Math.floor(Date.parse(table.rows[i].cells[0].textContent) / 24*60*60*1000);
var end = Math.floor(Date.parse(table.rows[i].cells[1].textContent) / 24*60*60*1000);
// Make the comparison
if (start <= newVal && (newVal <= end || isNaN(end))) {
return i; // the row where the range for that value was found
}
}
Possible reasons for error could be :
document.getElementById("parentTable").value will be returning a value which will not map to any table id when using in window.parent.document.getElementById("tblBody_"+tblID);
There are no rows in the table which has been returned by window.parent.document.getElementById("tblBody_"+tblID);
Also you havn't provided terminating condition in your for loop, which should be like : for(var i=0; i < table.rows.length; i++)
One more thing why you are using window.parent when getting the table. If your table and rest of the content are in same page then you can get table by simply calling document.getElementById("tblBody_"+tblID);. If you creating multi frame page then this will be required but this will get the table from the parent window of window in which you have function sortRow defined.
Forgot to paste this snippet, which might help. Until you answer the questions on the comment, there's no way to determine the best approach.
Note: The following code uses some ES6 syntax, which may not be available in IE as #Brian has pointed out. For that reason, Babel.js or a suitable Polyfill is encouraged.
The idea is to grab the first-child cell of each row and iterate over them. Using map you can return an array, which can then be sorted, or queried using indexOf.
By returning the element as the first item of the array, you can use [0].parentNode to retrieve the TR, or [0].parentNode.id to get it's ID.
"use strict";
let newVal = document.getElementById('newDate').value;
console.log('newVal:', new Date(newVal));
let tbl = document.getElementById('tblBody_DBA');
var col_values = [...tbl.querySelectorAll('tr > td:first-child')].map(el => {
return [el, el.textContent, +new Date(el.textContent)];
}).sort((a,b) => a[2] > b[2] ? -1 : 1);
console.log(col_values);
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<p>I have the function where I want to get the value for first td in each table row. While looping I want to compare each of these values with the date value that user picked. After comparing the dates I need to get the position where that value should be
placed in the table. Here is example of my code:</p>
<p>HTML Table:</p>
<input id="newDate" value='3/24/2017' type="hidden" />
<table id="tblBody_DBA" class="table table-striped">
<tbody>
<tr id="Att_5258717">
<td>03/28/2017</td>
<td></td>
</tr>
<tr id="Att_5258339">
<td>03/25/2017</td>
<td>03/26/2017</td>
</tr>
<tr id="Att_5258337">
<td>03/22/2017</td>
<td>03/24/2017</td>
</tr>
<tr id="Att_5258332">
<td>03/16/2017</td>
<td>03/21/2017</td>
</tr>
<tr id="Att_5258331">
<td>03/10/2017</td>
<td>03/15/2017</td>
</tr>
</tbody>
</table>
<p>
I'm getting value for each table cell in alert box but on the end error shows in my debugger. If anyone can help please let me know. I'm not able to use JQuery, plain JavaScript is the only way to et this done in my case.</p>
I currently have a table that has a list of email template names being echoed using php. Below is part of the php code. I'm trying to grab the table value and pass it to my JS file where a future AJAX command will pass it to a different file (that I won't have any issues with). My first attempt to alert out the value stated that the value was undefined. My second attempt showed the type of element it was inside (at the time it was a span). Now it's not showing anything. Suggestions?
PHP code:
<table class="departments">
<tr>
<th scope="col" style="width: 175px;">Email Name</th>
';
$get_depts = mysql_query("SELECT dept_name FROM depts where bus_id = '{$_SESSION['bus_id']}'");
while(($department = mysql_fetch_assoc($get_depts)))
{
echo '
<th scope="col" style="width: 175px;">'.$department['dept_name'].'</th>
';
}
echo '
</tr>
';
$get_emails = mysql_query("SELECT id, email_name from emails where bus_id = '{$_SESSION['bus_id']}' ORDER BY email_name ASC");
while(($email = mysql_fetch_assoc($get_emails)))
{
echo '
<tr>
<td id="test" onclick="moveValue()">'.$email['email_name'].'</td>
';
Current JS code:
function moveValue()
{
var x = document.getElementById(test);
var y = x.innerHTML;
alert(y);
}
Javascript:
var y = document.getElementById("test").innerText;
jQuery:
$("#test").text();
To get the HTML:
var html = document.getElementById("test" ).innerHTML;
jQuery:
$("#test").html();
You id attribute would be the same for every td inside the loop. So JS would not know which element you want.
You could try passing this into the onclick method
HTML
<td onclick="moveValue(this);">
JS
function moveValue( elem )
{
alert(elem.innerHtml);
}
I would take a look at jQuery if I were you. It makes all this stuff much easier to achieve.
I don't want to get into all the problems with your code as there are rather a lot. However, getting the value of a <td> element by clicking is trivial to achieve.
You first need to assign a click handler to each cell in your table. The easiest way to do this is to loop through each cell and assign the handler like so:-
var cells = document.getElementsByTagName('td');
for(var i = 0; i <= cells.length; i++){
cells[i].addEventListener('click', clickHandler);
}
function clickHandler()
{
alert(this.textContent);
}
Then every time you click on a cell the clickHandler() will be called and you can run whatever code you wish.
You can see it working in this fiddle
Lots of information here https://developer.mozilla.org/en-US/docs/Web/API
With javascript:
To get raw text without any elements or:
somevar=document.getElementById ( "test" ).innerText;
To get full html code of tag. Contents will be stored in 'somevar' variable.
somevar=document.getElementById ( "test" ).innerHTML;
You can do it either by
function moveValue()
{
var x = document.getElementById('test');
var y = x.innerHTML;
alert(y);
}
or by:
function moveValue(element) {
var y = element.innerHTML;
alert(y);
}
//with the following html code:
<td onclick="moveValue(this)">'.$email['email_name'].'</td>
its work.
function clickValue(elem) {
var x = document.getElementById(elem).innerHTML;
alert(x);
}
<table>
<th>Coba</th>
<tr>
<td id="1" onclick="clickValue('1')">value</td>
</tr>
<tr>
<td id="2" onclick="clickValue('2')">value yg ke 2</td>
</tr>
</table>
Change id="*anyvalue*" and clickValue('*anyvalue*')
I have a table that is filled in with values dependant on a previous page
those avlues are filled in with struts apparently
but I'm not very good with all that stuff so is there a simple was I can do something like this, either with HTML only or maybe a small javascript I can put in tha page?
<Table>
<TR>
<TH>ID</TH>
<TD><s:property value="groupID" /><TD> <--Number generated by the page with struts
</TR>
<TR>
<TH>ID Value</TH>
<TD>foobar</TD> <-- the text I want to add in dependant on the number from the previous TD
</TH>
</Table>
so, is there a simple way to go about doing this? HTML, CSS, JavaScript solution maybe?
Given that exact HTML, a simple script like this will do it. But if you don't know JavaScript, you should really learn it so that you understand what you're doing.
<body>
<Table>
<TR>
<TH>ID</TH>
<TD><s:property value="groupID" /><TD>
</TR>
<TR>
<TH>ID Value</TH>
<TD>foobar</TD>
</TR>
</Table>
<!-- The script is here so it won't run until the TABLE has loaded -->
<script type="text/javascript">
// This is a map of the struts values to your values
var valueMap = {
"1": "foo",
"2": "bar",
"3": "baz"
};
// Browser compatibility. Older IE uses 'innerText' instead of 'textContent'
var textContent = ('textContent' in document) ? 'textContent' : 'innerText';
// Get all the TD elements on the page
var tds = document.getElementsByTagName('td');
// Get the text content of the first TD (index 0)
var text = tds[0][textContent];
// Get the value from the map using the text we fetched above
var value = valueMap[text];
// Set the text content of the second TD (index 1) to the mapped value
tds[1][textContent] = value;
</script>
</body>
Assuming you want to place the value 'groupID' (set in the first tr's td) into the second row's td element, then the following jQuery will do the trick:
$(document).ready(function() {
// Scrape the XML out of the TD containing the xml
var tdXml = $('table tr').eq(0).find('td').html();
// Grab the value of the value attribute (groupID)
var value = $(tdXml).attr('value');
// Set this value in the second row's TD
$('table tr').eq(1).find('td').text(value);
});
jsFiddle here
Currently I have a table variable which I want to get its table content in this way: <table><tr></tr></table> instead of getting a Javascript object. Is there a solution to finding a method that could do that?
try innerHTML.
This assumes your table is the only table on the page. If this is not the case, give it a unique ID (such as tableID) and reference using getElementsById("tableID").
var tables = document.getElementsByTagName("table");
var firstTable = tables[0];
var tableAttr = firstTable.attributes;
// get the tag name 'table', and set it lower case since JS will make it all caps
var tableString = "<" + firstTable.nodeName.toLowerCase() + ">";
// get the tag attributes
for(var i = 0; i < tableAttr.length; i++) {
tableString += " " + tableAttr[i].name + "='" + tableAttr[i].value + "'";
}
// use innerHTML to get the contents of the table, then close the tag
tableString += firstTable.innerHTML + "</" +
firstTable.nodeName.toLowerCase() + ">";
// table string will have the appropriate content
You can see this in action in a short demo.
The pertinent things to learn are:
getElementsByTagName - get DOM elements by their tag name
attributes - a DOM property that gets an attributes array
innerHTML - gets a string of the HTML inside any DOM object
nodeName - gets the name of any DOM object
If you get into using a framework, jquery's .html() method and the getAttributes plugin would potentially also be helpful
Try following code...
<html>
<head>
<script type="text/javascript">
function sample_function(){
alert(document.getElementById('div_first').innerHTML);
}
</script>
</head>
<body>
<div id="div_first">
<table border="1">
<tr>
<td>row 1, cell 1</td>
<td>row 1, cell 2</td>
</tr>
<tr>
<td>row 2, cell 1</td>
<td>row 2, cell 2</td>
</tr>
</table></div>
<button onclick="sample_function()">Click Here</button>
</body>
</html>