I'm creating a table while looping through an API array and I've hit a couple snags. Here is the repeated HTML ->
$html = "
<tr class='mt-2'>
<td>{$rank}.</td>
<td><img src='{$image}' height='75' width='75'></td>
<td>{$name}</td>
<td class='bold'>\${$final_worth}B</td>
<td class='{$class}'>\${$last_change}</td>
<td>{$country}</td>
<td>{$source}</td>
<td><button class='bg-color-primary text-color-third px-2' id='more_btn' onclick='showDetails({$cnt})'>More</button></td>
</tr>
<tr >
<div id='details'>lorem ipsum wahoo baby</div>
</tr>
";
Everything was going as expected until I went to add the second row (div#details).
There's actually 2 issues at play here - the first is how I make each button/div#details connected so button1 only effects div1 etc.
I can't tackle that one yet though, because right now when any button is clicked div#details shows up above the table header rather than underneath the previous row.
So until I have the positioning correct I can't really tackle the js functionality. Can someone please tell me why the <tr><div#details> is not appearing underneath it's previous row? The js code is as follows ->
<script>
var cnt = <?php echo $cnt; ?>;
function showDetails(cnt) {
var details = "details";
var x = document.getElementById(details);
if (x.style.display === "none") {
x.style.display = "block";
} else {
x.style.display = "none";
}
}
</script>
I know the code is a mess right now. It's kind of shameful lol but like I said I can't really do more with it until I can figure out why that table row isn't positioning properly
Try changing it to
<tr>
<td colspan='8' id='details'>lorem ipsum wahoo baby</td>
</tr>
If it isn't in a cell, it's rejected from the table, which is why it appears above.
Related
Context: I am trying to choose a university course from a list provided via a table from a search engine. The search engine only recognises suffixes if there is a prefix, i.e. COSC3 or COSC350. 3 or 350 would not return any results.
What I would like to know is if it would be possible to use Firefox's Firebug to parse a console command that would remove all table rows that don't contain a 100-level paper.
Pseudocode:
string regex = [A-Z]{4};
for each(tr) {
for each(td) {
if(!td.contains(regex + "1") {
tr.delete();
}
}
}
My pseudocode is probably pretty ineffective but it was designed to give you a general idea as to what I would like to do.
Yes, it's possible.
The general idea is outlined in your pseudo-code. The only tricky thing to note is that when operating on "live" HTMLCollection, you can't loop them like arrays.
// get all rows
var table = document.getElementById('my-table');
var trs = table.getElementsByTagName("tr");
// go through each row
var i = 0;
while (i < trs.length) {
var tds = trs[i].getElementsByTagName("td");
var deleted = false;
// go through each cell of this row
var j = 0;
while (j < tds.length) {
if (/[A-Z]{4}1/.test(tds[j].textContent)) {
// delete this row
trs[i].parentNode.removeChild(trs[i]);
deleted = true;
break;
} else {
j++;
}
}
if (!deleted) {
i++;
}
}
<p>The table below should not show any rows containing XXXX100 series courses.</p>
<table id="my-table" cellspacing="0">
<tr>
<td>COSC123</td>
<td>COSC456</td>
<td>COSC789</td>
</tr>
<tr>
<td>ABCD123</td>
<td>EFGH124</td>
<td>IJKL125 <span>span</span></td>
</tr>
<tr>
<td>MNOP233</td>
<td>QRST294</td>
<td>UVWX297</td>
</tr>
<tr>
<td>COSC333</td>
<td>COSC394</td>
<td>COSC397</td>
</tr>
<tr>
<td>ABCD3000</td>
<td>ABC3456</td>
<td>*COSC1997</td>
</tr>
</table>
To run JavaScript code on a website using Firebug, you can enter it into its Command Editor and then hit the Run button or pressing Ctrl/⌘ + Enter.
Doing so, the code will be executed in the context of the page.
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 as below;
<table>
<tr>
<td id="prev">prev</td>
<td class="content"></td>
<td class="content"></td>
<td class="content"></td>
<td class="content"></td>
<td class="content"></td>
<td id="next">next</td>
</tr>
</table>
and a PHP file, ajax.php for AJAX calls as;
<?php
$array = array(1,2,3,4,5,6,7,8,9,10);
$page = $_POST["page"];
$quantity = 5;
$offset = ($page-1)*$quantity;
$selectedFiles = array_slice($array, $offset, $quantity);
echo $selectedFiles;
?>
The PHP function is suppose to return an array with a limited number of elements with respect to $_POST["page"] like in pagination. The script will return first 5 elements for $page = 1, second 5 elements for $page = 2, etc..etc.. When page loads, the <td>s having id content may display 1,2,3,4 and 5 respectively.
When user click next, it may display next results and may return to previous result if user click prev. How can I do this using JavaScript using jQuery?
It will be more helpful if some effect is given when user clicks and data changes, like sliding (transition), so that it will look like sliding some bar.
Save yourself a TON of time. Use a pre-done grid solution like DataTables that does all this work for you. It allows you to sort, filter, paginate, order, and limit your table results that can be fed via the dom, JSON, or true server-side AJAX.
Since DataTables is such a mature project, it has already overcome all the random issues with cross-browser quirks, etc.
It also includes a pre-done PHP example with the query done for you. Just change to match your table, and voila!
This should help you get started:
<table id="pageLinks">
<tr>
<td id="prev">prev</td>
<td class="content">1</td>
<td class="content">2</td>
...
<td id="next">next</td>
</tr>
</table>
var currPage = 1;
$("#pageLinks tr td").click(function() {
if($(this).hasClass("content")) {
var currPage = $(this).text();
} else {
if(this.id == "next") {
currPage++;
} else {
if(currPage > 1)
currPage--;
}
}
$.post("script.php", {currPage: currPage}, function(html) {
$("#someDiv").hide().html(html).slideUp();
});
});
Notes:
IDs should not be duplicated in a document, so I've given those cells the class 'content' instead.
I don't fully understand your question, so I've assumed that the table is for paginated links, and you're loading in the content elsewhere.
I've been messing around with different forms and tables, now I need something that takes data from table tr and td field, runs a if statement on each fetched item, and outputs text inside the form, depending what was found in td fields.
So right now I have something like this, which doesn't do anything useful at all, for now, just outputs td-01 class values into the form:
var test;
$('tbody tr').each(function(index) {
test = $(this+'.td.td-0');
$('fieldset.csc-mailform').after($('td.td-0'));
});
and my table structure looks something like this:
<table class="contenttable contenttable-3 tabel">
<tr class="tr-even tr-0">
<td class="td-0">01</td>
<td class="td-1">Valik 1</td>
<td class="td-last td-2">150€</td>
</tr>
<tr class="tr-odd tr-1">
<td class="td-0">01</td>
<td class="td-1">Valik 2</td>
<td class="td-last td-2">50€</td>
</tr>
<tr class="tr-even tr-2">
<td class="td-0">01</td>
<td class="td-1">Valik 3</td>
<td class="td-last td-2">170€</td>
</tr>
<tr class="tr-odd tr-3">
<td class="td-0">01</td>
<td class="td-1">Valik 4</td>
<td class="td-last td-2">88€</td>
</tr>
</table>
Right now it only find tr tags and outputs all of them. I need it to split the tr tag up, run if condition on td-0 to determine if it needs to be radio button/text input/checkbox etc, then see what td-1 contains and make that field name, then td-2 is for example a price. all of this should end up in a form.
So as you can see, I am stuck with jQuery, but I think it should be doable.
edit:
I got something like this after messing around a little, but my if statements don't seem to work on jQuery objects, any way to get around this?
var check1;
$('tbody tr').each(function(index) {
//test = $(this+'.td.td-0');
check1 = $('td.td-0');
alert(check1);
if(check1=='01'){
content_type="checkbox";
}else if(check1=='02'){
content_type="text";
}else{
content_type="none";
}
$('fieldset.csc-mailform').after(content_type);
//$('fieldset.csc-mailform').after($('td.td-0'));
});
//edit2
Ugh, I was running if statement against jQuery object, of course it didn't work.
I got it working with this, looks quite nasty, but it seems to work:
$('tr').each(function () { var val = $(this).children('td:first').text();
//$check1 = $('td.td-0');
if(val=='01'){
content_type="checkbox";
}else if(val=='02'){
content_type="text";
}else{
content_type="none";
}
$('fieldset.csc-mailform').after(content_type + '<br/>');
}
);
Now, I need to figure out how to create input fields from these.
You could possibly make it a bit cleaner by using the jQuery selector context, e.g.:
$('tr').each(function () {
var val = $('td:first', this).text();
..
}
Something like this will do:
$('table tr').each(function() {
$tds = $(this).children();
for(var i=0;i<$tds.length;i++){
$td = $tds[i];
if($td.hasClass('td-0'){
//do your thing by getting next TD or something else
break;
}
}
});
I'm trying to write a function to add color to a table based on a reference which is one of the top rows of the table. There are several questions in SO mentioning row based iteration but not so much about column.
The structure of the table is something like:
<table id="data">
<tr>
<th rowspan="2">Name</th>
<th rowspan="2">Selection</th>
<th rowspan="2">Title</th>
<th rowspan="2">Info1</th>
<th rowspan="2">Info2</th>
<th colspan="10">Data</th>
</tr>
<tr>
<th>001</th>
<th>002</th>
<th>003</th>
<th>004</th>
<th>005</th>
<th>006</th>
<th>007</th>
<th>008</th>
<th>009</th>
<th>010</th>
</tr>
<tr id="ref_control">
<td></td>
<td>RefName</td>
<td></td>
<td></td>
<td></td>
<td>A</td>
<td>B</td>
<td>J</td>
<td>L</td>
<td>Z</td>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
</tr>
<tr>
<td><input type="checkbox" name="checkbox"/></td>
<td>Entity 1</td>
<td>Info...</td>
<td>More info...</td>
<td>Even more...</td>
<td>A</td>
<td>T</td>
<td>M</td>
<td>L</td>
<td>Z</td>
<td>1</td>
<td>2</td>
<td>3</td>
<td>2</td>
<td>5</td>
</tr>
(...)
</table>
In addition I'm using JQuery and the JQuery column cell select plugin to perform the mentioned task.
The Javascript code looks like this:
$(document).ready(function() {
// Colorize table based on matches
// Number of Data entries - Count on the reference (2nd row)
// and only 5th column onwards (index starts at 0)
var datasize = $("#data tr:eq(2) td:gt(4)").length;
// Start with column 6 (index starts at 1)
var begin = 6;
for (var i = begin; i < begin + datasize; ++i) {
var curCol = $("#data td").nthCol(i);
var ref = curCol.eq(0).text();
curCol.not(curCol.eq(0)).each(function() {
var data = $(this);
if (data.text() == '') {
data.addClass("black");
} else if (data.text() != ref) {
data.addClass("color");
}
});
}
});
A working example can be visualized here. In the example the table has only 9 rows and 10 data columns. The actual page I'm trying to optimize has 20 rows and 90 data columns.
Using the mentioned Javascript extensions/plugins the big sized table poses no threat to the Google Chrome browser taking a few seconds to load, however Opera, Firefox and Internet Explorer have a hard time running the function or end up asking for user interaction to stop the script from running.
So my question is aimed at both alternatives to the column select plugin or ways to optimize the code such that I don't kill almost all browsers except Google Chrome.
Edit: Changes according the the two comments from #Pointy
You can easily get 10x faster code if you want. Just save references once and go row by row instead of column by column. It doesn't become more complicated yet it performs much better. The reason is that your plug-in hides the abstraction that your table is made of rows that are made of columns. And not the other way around. Emulating the second version can be costy as you noticed in this example.
You may also use DOM properties instead of jQuery methods. They are really straightforward.
// get text (modern browsers || IE <= 8)
var text = elem.textContent || elem.innerText;
// set class
elem.className = "black";
your final code will be something like:
var refcells = $("#data tr:eq(2) td:gt(4)");
var datasize = refcells.length;
// Start with column 5
var begin = 5;
var refs = [];
var i = begin;
refcells.each(function () {
refs[i++] = $(this).text();
});
$("#data tr:gt(2)").each(function () {
var cells = $("td", this);
for (var i = begin; i < begin + datasize; i++) {
var elem = cells[i];
var text = elem.textContent || elem.innerText;
if (!text) {
elem.className = "black";
} else if (text != refs[i]) {
elem.className = "color";
}
}
});
Doing what you're doing is going to be very computationally intensive. Since your table layout seems pretty regular, I'd just completely ditch that nthCol() thing (for this page anyway) and do your work by iterating over the table once:
Grab the "key" row first, and save it
Loop through each relevant <tr>, and for each one get the <td> elements and iterate over them as a raw node list, or as a jQuery list. Either way it should be a lot faster.
In the second loop, you'll do the same logic you've got (although I'd use addClass() and removeClass()), referring back to the saved "key" row for each cell.
In your current loop, you're re-building the jQuery object of every <td> in the table for each column, and then you're doing that nthCol() work! That's a lot of work to do if you do it once, so repeating that for every single column is going to really drag that CPU down. (On IE6 - especially with all those "class" changes - I bet it's almost unbearably slow.)
edit — I looked over that code (for the plugin), and while it looks like it was competently implemented it doesn't have any "magic tricks". All it does is iterate through all the table cells you give it and checks whether or not each cell is in fact in the "nth" column. Thus, your iteration will perform that test on every cell in the table for every column you care about. In your 90x20 table, that'd be about 85 iterations through all 1800 cells. And that's before you do your work!