Building a very specific menu with JQuery - javascript

I have an HTML table defined as follows:
<table border="0" cellpadding="0" cellspacing="0">
<tr>
<td class="item1a"> </td>
<td class="item2a"> </td>
<td class="item3a"> </td>
<td class="item4a"> </td>
<td class="item5a"> </td>
<td class="item6a"> </td>
<td>Some addition content that is not a menu</td>
</tr>
</table>
Each cell has it's own item because the content and width such content varies. For instance, here is the CSS associated with item1a
.item1a {height:36px; width:84px; background-image:url(/resources/images/item1a.png);}
.item1b {height:36px; width:84px; background-image:url(/resources/images/item1b.png);}
When someone hovers over a cell, I need to change the class from a to b. I am pretty confident I know how to do that. My real problem is, I don't know how to make a menu popup underneath the item. I need to use this tabular structure because of the specificty of the graphics. Can someone help me out? How should I address this problem?
Thank you!

Assuming your classes item1a, item2a... are typos and you meant to type item1 a
$('td').hover(hoverIn, hoverOut); //make your more selector more specific
function hoverIn() {
$this = $(this);
$this.removeClass('a').addClass('b');
var hoverMenu = '<div class="hoverMenu">Rest of the HTML needed for the menu</div>';
$this.append(hoverMenu);
}
function hoverOut() {
$this = $(this);
$this.removeClass('b').addClass('a');
$this.children('.hoverMenu').remove();
}
Switches the classes on hover and adds a DIV to the TD bottom. You can move it around to suit your needs.

Related

Clone text from several elements to an a href as a mailto subject

I'm trying to append all the text in the td elements to the a element as the subject of the mailto link, but I can only get the first closest elements text. How do I make it so it retrieves the text from all the elements? If possible I would rather have the a link inside the tbody element instead of the tr wrapper.
HTML:
<tbody>
<tr class="row-2" role="row">
<td class="column-1" tabindex="0" style="">2238221D2</td>
<td class="column-2">HPINC</td>
<td class="column-3">N7P47AA</td>
<td class="column-4">HP USB 3.0 to Gigabit LAN Adapter</td>
<td class="column-5" style="display: none;">#4.2</td>
<td class="column-6" style="display: none;">16</td>
<td class="column-7" style="display: none;">30</td>
<td class="column-8" style="display: none;">52</td>
<a class="mailme" href="mailto:test#test.com?subject=Product request&body=">mailtolink</a>
</tr>
</tbody>
Script:
$('a.mailme').each(function() {
$(this).attr('href', $(this).attr('href') +
$(this).closest('a.mailme').prev('td').text());
});
Your code is almost right, just select all td-tags, get the text and join the resulting array:
$('a.mailme').each(function() {
$(this).attr('href', $(this).attr('href') +
$(this).closest('.row-2').children('td').slice(0,-1).map(function() {return $(this).html()}).get().join(','));
});
Working fiddle: https://jsfiddle.net/21873jcz/
EDIT My Solution will work if you fix your html code. a tags are not permitted within tr-tags. Only td or th elements are allowed. So please fix your html and it will work
I found a few problems but here is what you want:
https://jsfiddle.net/uqswr2k3/
var subject = "";
$(".row-2 td").each (function() {
subject = subject + '-' + $(this).html();
});
$(".mailme").attr('href', 'mailto:test#test.com?subject=' + subject + '&body=');
<table>
<tbody>
<tr class="row-2" role="row">
<td class="column-1" tabindex="0" style="">2238221D2</td>
<td class="column-2">HPINC</td>
<td class="column-3">N7P47AA</td>
<td class="column-4">HP USB 3.0 to Gigabit LAN Adapter</td>
<td class="column-5" style="display: none;">#4.2</td>
<td class="column-6" style="display: none;">16</td>
<td class="column-7" style="display: none;">30</td>
<td class="column-8" style="display: none;">52</td>
<a class="mailme" href="">mailtolink</a>
</tr>
</tbody>
</table>
Make sure the tbody has an outside table or it can cause issues with jQuery. You were setting the value of the subject to the current iteration and not collecting them all. I put a variable named subject to add each td cells' HTML content. I separated each value in the subject with a dash - to make it cleaner.

If td has value "No" add class to different td

I have the following code:
<td class="bedrag">
#_ATT{Factuur bedrag}
</td>
<td class="paid">
#_ATT{Betaald}{Ja|Nee}
</td>
In the td paid the option can be given for Yes or No. I would like change the background of bedrag depending on what was chosen in the td paid. I figured the best way to go was to addClass using Javascript. So I googled around for a while and found this piece of code:
jQuery('a:contains("Sponsored")').closest('.post-item').addClass('sponz');
I changed it to fit my needs:
$('.paid:contains("Nee")').closest('.bedrag').addClass('sponz');
But that didn't work. So I tried the following code:
$('.paid:contains("Nee")').addClass('sponz');
This adds the class sponz to the td paid. But I want to add it to bedrag. So I then tried this:
('.bedrag:has(.paid:contains("Nee"))').addClass('sponz');
But this also didn't work.
Anyone know how to get this code working so that it will add sponz the the td bedrag when a user selects the option Nee? thanks in advance!
closest() isn't quite what you need as that looks for parents. .bedrag is a sibling of .paid, so you need to use prev() instead:
$('.paid:contains("Nee")').prev('.bedrag').addClass('sponz');
.sponz { color: #C00; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr>
<td class="bedrag">bedrag 1</td>
<td class="paid">Nee</td>
</tr>
<tr>
<td class="bedrag">bedrag 2</td>
<td class="paid">Ja</td>
</tr>
<tr>
<td class="bedrag">bedrag 3</td>
<td class="paid">Nee</td>
</tr>
</table>
Can't you just do an if?
if ($('.paid:contains("Nee")').length !== 0) { // there's at least an element
// add class to the right element
}

jquery how to remove a column from a table

I need to click in a Close img, and remove all the column where the img is located.
I'm trying to do something like this:
var colnum = $(this).closest("td").prevAll("td").html();
$(this).closest("table").find("tr td:eq(" + colnum + ")").remove();
but, its not working.
EDIT: GUYS, SORRY FOR THE FIRST POST, I WAS KIND A HURRY TO OPEN THE QUESTION.
I EDIT EVERYTHING. TAKE A LOOK IN THE DEMO
the html demo: New Demo
if you guys see the red stuffs in the table, that I need to remove when click que "CLOSE".
Remove the column where I'm clicking.
ps.: guys, the red class was just to you guys see where need to be the close event.
In your example demo, what should actually close?... I modified it slightly and the close column disappears, but I am unsure what else you are expecting to be removed.
See here: http://jsfiddle.net/gfosco/TdCYy/24/
The issue is being inside a nested table... You want to remove the column from the cell parent tables parent table.
Updated example here:
http://jsfiddle.net/gfosco/TdCYy/37/
You should be able to use the nth-child selector to get the cells in nth column, something like this:
$(this).closest("table").find("tr td:nth-child(" + colnum + ")").remove();
Check out this link, I have edited your demo http://jsfiddle.net/TdCYy/39/
This is the HTML unchanged, except for the class first-row added to the first red row:
<table border='1' width='100%'>
<tr>
<td>Somthing 1</td>
<td>Somthing 2</td>
<td>Somthing 3</td>
<td>
<table border='1' style='border: solid red;' width='100%'>
<tr class="first-row">
<td colspan='2'>
Something
<span style='float: right' class='img_romove_columm'>Close</span>
</td>
</tr>
<tr>
<td>Another</td>
<td>Another 1</td>
</tr>
</table>
</td>
</tr>
<tr>
<td>Result</td>
<td>Result</td>
<td>Result</td>
<td class='red'>Result</td>
</tr>
<tr>
<td>Result</td>
<td>Result</td>
<td>Result</td>
<td class='red'>Result</td>
</tr>
<tr>
<td>Result</td>
<td>Result</td>
<td>Result</td>
<td class='red'>Result</td>
</tr>
<tr>
<td>Result</td>
<td>Result</td>
<td>Result</td>
<td class='red'>Result</td>
</tr>
</table>
CSS is untouched.
Javascript should be (this works):
$(".img_romove_columm").click(function(){
// Hide the first row that has the close button, and also hide the row right after it (another, another1)
$('tr.first-row, tr.first-row + tr').hide();
// Hide everything that has the red class (result, result, result, result, )
$('td.red').hide();
});
Is this what you're looking for?
Here is an example I came up with. simply apply the same class (red) to all of the elements to want to disappear, including the nested table. Then you can call
$('.red').hide();
FIDDLE http://jsfiddle.net/Jaybles/TdCYy/42/

Testing the RemoveNode DOM function

I have the following test html:
<table width="80%" border="0" cellspacing="0" cellpadding="1" >
<tr>
<td class="tableBorder">
<table id="scriptsT" name="scriptsT" width="100%" border="0" cellspacing="1" cellpadding="0">
<tr>
<td colspan="4" class="tableTitle">› College Foo - ScriptList:</td>
</tr>
<tr class="rowHeaders">
<td width="4%">ScriptName</td>
<td width="2%">Main Script (Radio)</td>
<td width="2%">(Ext)</td>
<td width="2%">Del Script</td>
</tr>
<tr id="foo[1]" name="foo[1]" class="rowHeaders">
<td id="sTD" name="sTD" width="4%">Script1</td>
<td width="2%">
<input type="radio" name="main" id="main" value="">
</td>
<td id="tTD" name="tTD" width="2%">Php</td>
<td width="2%"><input type="Button" class="textbox" name="SelScript" id="" value="DelScript" onClick="javascript: DelScript(1); return false;"></td>
</tr>
</table>
</td>
</tr>
</table>
=======================================================
I'm trying to remove the node, using the "DelScript function, that tries to use an ID to select the given TR, based on each TR having a unique ID, in this case foo[1], etc..
In my test DelScript, I 1st get the table, and then try to get the childnode (the "TR") to delete.
//--handle/simulate the deletion of the tr in the scriptTBL for the id
function DelScript(id)
{
var scriptTBL=document.getElementById("scriptsT");
var a="foo["+id+"]"
var test=document.getElementById("foo[1]");
//scriptTBL.parentNode.removeChild(test);
scriptTBL.removeChild(test);
alert("foo");
var a;
}
However, I'm screwing something up, as I'm not able to delete the node.
I'm running FF4, and firefox seems to be saying the node can't be found (???).
I've also tried using the parentNode a well but get the same results.
Thank you for any pointers.
If you just want to
"delete the TR where the clicked 'delete' button is located"
You don't need any of those id attributes.
<input type="Button" onclick="DelScript(this);return false;">
function DelScript(theClickedButton) {
var tr = theClickedButton.parentNode.parentNode;
tr.parentNode.removeChild(tr);
}
The table rows are not children of the <table>, they're children of the <tbody> element inside it. Even if there's not a <tbody> in your markup, there's one in the DOM. You could go up the DOM from the child element itself, or you could find the <tbody>
var tbody = document.getElementById('scriptsT').getElementsByTagName('tbody')[0];
FF is likely inserting a <tbody> element in between your <table> and <tr>, as the HTML specification demands. You don't even need to know the table ID. The attempt you commented out was almost right, but you need test.parentNode instead of table.parentNode - you want to get the row's parent node, not the table's:
function deleteRow(n){
var el = document.getElementById('foo['+n+']');
return el.parentNode.removeChild( el );
}
The TR is not a child of the TABLE. It is a child of the TBODY that is implicitly a child of the TABLE. Try this:
scriptTBL.children[0].removeChild(test);
Also, install FireBug so that you can browse the DOM tree and set breakpoints in your scripts to examine what they are doing to the dynamically rendered HTML.

Combining Rows in Javascript

I'm looking for some help on the Javascript angle of this problem. I have a table that goes like...
<table>
<tbody>
<tr> (Row 1)
<td colspan="3">
<p>This Says Something</p>
</td>
</tr>
<tr> (Row 1a)
<td>
<select option>
</td>
</tr>
<tr> (Row 2)
<td colspan="3">
<p>This Says Something</p>
</td>
</tr>
<tr> (Row 2a)
<td>
<select option>
</td>
</tr>
<tr>
<td colspan="3">
<p>This Says Something</p>
</td>
</tr>
<tr>
<td>
<select option>
</td>
</tr>
<tbody>
</table>
There are actually more like 20 rows and row a's but I didn't think I'd want to copy them all.
I basically need to add a container row (a single row) around every two rows (# and #a). Something like:
<tr> (Container Row 1)
<td>
+<tr> (Row 1)
+<tr> (Row 1a)
</td>
</tr>
It needs to cycle through the whole table. Somehow it has to retain the HTML data inside since all of the "a"s have options.
I hope this makes sense...
Any help would be greatly appreciated, as I'm at a loss. I'm novice at best at javascript and am struggling my way through the DOM and TOM methods.
Thank you so much in advance for any help or headway.
[EDIT] For clarification, the table is already constructed from a third party database, I am editing it after it's constructed. I guess this clarifies why it would have to be javascript to be done through the DOM.
Embed another table:
<tr> (Container Row 1)
<td>
<table>
<tr><td>(Row 1a)</td></tr>
<tr><td>(Row 1b)</td></tr>
</table>
</td>
</tr>
Or if you are wanting to do that via Javascript, you can give the parent <td> an id and set it's innerHTML.
<tr> (Container Row 1)
<td id='rowX'>
</td>
</tr>
document.getElementById('rowX').innertHTML = "<table><tr><td>(Row 1a)</td></tr><tr><td>(Row 1b)</td></tr></table>";
As mentioned in another answer you can't add tr elements directly in td like you are trying.
You would first create an inner table.
If you were using jQuery you would do something like this:
//setup some click actions just to prove that they remain attached even after moving
$('#outterTable tr').click(function(){
alert('You clicked on row: '+$(this).text());
});
//update the table (group each even row with the one after it)
$('#outterTable tr:even').each(function() {
var $tr1 = $(this),
$tr2 = $tr1.next('tr'),
$t = $('<table></table>');
$('<tr></tr>').append($t).insertBefore($tr1);
//click actions will remain attached
//if that is not required, than use $tr1.remove()
$t.append($tr1).append($tr2);
});​
See this live jsFiddle example.
without jQuery it may look like that:
<script type="text/javascript">
<!--
function fx(table)
{
var tmp=document.createElement('table');
tmp.appendChild(document.createElement('tbody'))
while(table.rows.length)
{
if(table.rows.length%2==0)
{
var wrapper=tmp.lastChild.appendChild(document.createElement('tr'));
wrapper.appendChild(document.createElement('td'));
wrapper.getElementsByTagName('TD')[0].appendChild(document.createElement('table'));
wrapper.getElementsByTagName('TD')[0].lastChild.appendChild(document.createElement('tbody'));
}
wrapper.getElementsByTagName('TD')[0].lastChild.lastChild.appendChild(table.getElementsByTagName('TR')[0])
}
table.parentNode.replaceChild(tmp,table);
tmp.setAttribute('border',1);
}
window.onload=function(){fx(document.getElementsByTagName('table')[0]);}
//-->
</script>
Example#jsFiddle
But: why do you need this grouping?
If the only benefit is a visible grouping I would prefer to do this by setting the borders of the cells .
Give all cells a border and to the even a border-top:none / to the odd a border-bottom: none

Categories

Resources