I need some help for doing a menu built automatically with jQuery.
I have the following HTML structure
<table width="99%" border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td height="20">Descripción</td>
</tr>
<tr>
<td height="20">Preguntas Frecuentes</td>
</tr>
<tr>
<td height="20">Incompatibilidades</td>
</tr>
</tbody>
</table>
...
<a name="descripcion"></a>
<h1>Descripcion</h1>
...
<a name="preguntas"></a>
<h1>Preguntas</h1>
In this case the anchor "incompatibilidades" doesn't exist, so what I need is to create a jQuery script which look for any "a" tag which has its corresponding link.
The result I expect is the following:
<table width="99%" border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td height="20">Descripción</td>
</tr>
<tr>
<td height="20">Preguntas Frecuentes</td>
</tr>
</tbody>
</table>
I'll appreciate your help!
If I understood correctly, you could do something like this:
var menu = $("#menu");
$("a").each(function() {
var $this = $(this);
var name = $this.attr("name");
if (typeof(name) !== 'undefined') {
var links = $("a[href='#"+name+"']");
var link;
if (links) {
link = links.eq(0);
}
if (link && typeof(link) !== 'undefined') {
menu.append("<tr><td><a href='#"+name+"'>"+link.text()+"</a></td></tr>");
}
}
});
You have to add "menu" id in a new table to create what you expect.
If you would like to remove the the table row which contains the mentioned anchor tag which does not exist, you could use:
$(document).ready(function() {
$('a[href="#incompatibilidades"]').closest('tr').remove(); // Or detach, possibly
});
If you would like to add in an h1 + a and append it to your DOM, you could use:
$(document).ready(function() {
var anchor = $('<a></a>', { 'name' : 'incompatibilidades' });
var h1 = $('<h1></h1>', { text: 'incompatibilidades' });
// Append these to the DOM here.
});
First, you shouldn't be using named anchors, but ids instead (the "name attribute on the a element is obsolete1"), to give:
<h1 id="descripcion">Descripcion</h1>
...
<h1 id="preguntas">Preguntas</h1>
Also, using a <table> element to present a list is a little non-semantic, since it's non-tabular information; instead use an ordered list, <ol>. So, with that in mind, I'd suggest the following jQuery:
$('h1[id]').each(function() {
var target = this.id;
$('#toc').append(function() {
return '<li>' + target + '</li>';
});
});
#toc {
text-transform: capitalize;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ol id="toc"></ol>
<h1 id="descripcion">Descripcion</h1>
...
<h1 id="preguntas">Preguntas</h1>
This approach is based on an assumption that you want to build a table of contents to link to those elements that are on the page.
Notes:
http://www.w3.org/TR/html-markup/a.html#a-constraints.
Without testing, and if I get your question correct - you are looking for something like this:
$().ready(function() {
// scan all links in your menu
$('table').find('a').each(function() {
// grep href attribute
var target = $(this).attr('href');
// element does not exist?
if(! $(target).length) {
// remove parent row
$(this).closest('tr').remove();
}
});
});
And - as #David Thomas mentioned correctly, you shouldn't be using named anchors, but ids instead - if you do so, you can use the anchor ('#xyz') directly as id selector as I did in the function above.
Related
I'm looking to retrieve the text inside a HTML table that is rendered via a webgrid. The text that I want is located inside a div with the class productID. My starting reference point is in the same row but the last td with the class span2. I'm trying to use jQuery's closest() method however I'm not getting any value returned.
Please see below for a section of the rendered HTML and my jQuery function:
HTML:
<tr>
<td class="span1"><div class="productID">1</div></td>
<td class="span2">Listing</td>
<td class="span2">Full Districtution</td>
<td class="span2">$1,350.00</td>
<td class="span2">2016-01-01</td>
<td class="span2"><div title="This is my brand new title!" data-original-title="" class="priceToolTip">2016-04-30</div></td>
<td>Select</td>
</tr>
jQuery:
$(".priceToolTip").mouseover(function () {
var row = $(this).closest("span1").find(".productID").parent().find(".productID").text();
console.log("Closest row is: " + row);
});
The .closest() method looks for a match in the ancestors. So you can use it to grab the tr then look for .productID like so:
var productID = $(this).closest('tr').find('.productID').text();
Or:
var productID = $(this).parent().find('.productID').text();
Or:
var productID = $(this).siblings('.span1').find('.productID').text();
.span1 is not the closest element of .priceToolTip. Use closest("tr").find(".span1 .productID") like following.
$(".priceToolTip").mouseover(function () {
var row = $(this).closest("tr").find(".span1 .productID").text();
console.log("Closest row is: " + row);
});
I need help with hiding and show a table in Javascript. My javascript is very short and that is because I want to use setAttribute and getAttribut I some way to hide and show the table when clicking on the link "Hide/show".
HTML
Hide/show</p>
<table class="show" class="hide">
<thead>
<tr>
<th>First</th>
<th>Second</th>
<th>Third</th>
</tr>
</thead>
</table>
CSS
.hide{
display:none;
}
.show{
display:block;
}
JAVASCRIPT
var linkhideShow = document.querySelector("#hideshow");
var show = document.querySelector(".show");
var hide = document.querySelector(".hide");
link.onclick = function() {
if (){
}
else{
}
};
Regards!
Give your table a id like this, and use only one class attribute:
<table class="table" id="table1">
<thead>
<tr>
<th>First</th>
<th>Second</th>
<th>Third</th>
</tr>
</thead>
</table>
Then set your default value in the css class table or however you want to call it to display:hidden; or display:none'
And then check if your element is shown or hidden and edit the attribute like this:
var table = document.getElementById("table1");
document.getElementById('link').onclick = function() {
if(table.styl.display == "none"){
table.style.display = "block";
}else{
table.style.display = "none";
}};
Here is a working Fiddle
using jquery you can simple do it as follows
$('#linkId').click(function () {
$('#tabelId').toggle();
});
Try this way :
Hide/show</p>
<table id="table "class="show">
<thead>
<tr>
<th>First</th>
<th>Second</th>
<th>Third</th>
</tr>
</thead>
</table>
<script>
document.getElementById('link').onclick = function() {
var t = document.getElementById('table');
if(t.classList.contains("show")){
t.className='hide';
}else{
t.className='show';
}};
</script>
Chagne HTML as show below
Show/Hide
<table id="table" class="show">
<thead>
<tr>
<th>First</th>
<th>Second</th>
<th>Third</th>
</tr>
</thead>
In Script tag put following
function ToogleClass() {
var tableS = document.getElementById("table");
if ( tables.getAttribute("class") == "hide"){
tables.setAttribute("class","show");
}
else {
tables.setAttribute("class","hide");
}
}
To get you started (fiddle here):
<a href="#" id="link" onclick="
var elm = document.getElementsByTagName('table')[0];
elm.style.display = elm.style.display ? '' : 'none';
">Hide/show</a>
<table>
<thead>
<tr>
<th>First</th>
<th>Second</th>
<th>Third</th>
</tr>
</thead>
</table>
Edit (after your updated question):
link.onclick = function(){
var elm = document.getElementsByTagName('table')[0];
elm.style.display = elm.style.display ? '' : 'none';
}
Updated fiddle here.
Short explanation:
the ternary statement (elm.style.display = elm.style.display ? '' : 'none';) is like an if else:
variable = condition ? /*true*/ : /*false*/ ;
if(condition){variable = /*true*/;} else {variable = /*false*/;};
Normally elements have their style.display unset, so it is an empty string. Empty strings evaluate to false in javascript. So, when the style.display is 'none', then the string is not empty. Thus, when style.display is set (to none), then set it to '' otherwise set it to 'none'.
Another important note: when an element's style.display is unset, the browser will render the element in the element's default display mode. Inline elements (like span) will be inline, block elements (like div) will have block and table elements will have table (not block).
So, setting the elements style.display to '' (instead of 'block') we assure the element get's it's default display mode (also it solves some weird cross browser issues).
Naturally you could also make a toggle function this way (passing the element to toggle as an argument):
function toggle(elm){
elm.style.display = elm.style.display ? '' : 'none';
}
// example use: toggle( document.getElementsByTagName('table')[0] );
NOTE:
Your table should NOT have two class attributes like this: class="show" class="hide".
Also note: In HTML an element's class attribute can have multiple classes separated by spaces: <elm class="class_a class_b"></elm>. In order to reliably add/delete a class one would require another (somewhat heavy) function (because if you would set the full class-attribute, you'd overwrite it completely).
It would be better to give the table an unique ID and reference it via this ID.
Hope this helps!
I have a table that looks like this:
<table id="table">
<thead>
<tr class='tablehead'>
<th>Test</th>
</tr>
</thead>
<tbody>
<tr class='tablecell'>
<td>
</td>
</tr>
</tbody>
</table>
I want to be able to double click on a row and then trigger a link.
An ID has to be transmitted somehow. Where should I define this? This allows me to edit the selected row afterwards.
Any idea how to do this?
Do you have any jQuery you've written yet? Here's a headstart...
Define your ID in the row:
<tr id="something">...</tr>
Then use something like this:
$('tr').dblclick(function(){
var id = $(this).attr('id');
//do something with id
})
This may help you:
jQuery(function($) {
$('#table tr').click(function() {
return false;
}).dblclick(function() {
window.location = url;
return false;
});
});
Do you mean something like this:
$(document).ready(function() {
$('.tablecell').click(function() {
return false;
}).dblclick(function() {
window.open("your_url");
return false;
});
});
and you could create a hidden field and populate that field with the id when double clicked.
Working demo: http://jsfiddle.net/Xr7LC/ (created from the sample code you provided)
Use dblclick api http://api.jquery.com/dblclick/
You can use $(this).attr('id') to get the id, and obviously you will define the id in a tag.
jQuery code for dblclick:
$(document).ready(function() {
$('#table >thead > tr').dblclick(function() {
alert('Row dblclicked');
alert($(this).attr('class'));
});
});
I'm building a jQuery sortable list where the user can add items from a table, drag and sort and/or remove them. I can add and sort no problem, but I can't work out how to remove an item element after it has been added. I'm relatively new to js / jQuery, so I have a feeling there's something new to learn here about how it works!
I'll leave out the ui.sortable stuff here as I'm only concerned with removing items..
<table>
<tr>
<td><a class="addrelease" href="#" cat_id="1">add</a></td>
<td>Item 1</td>
</tr>
<tr>
<td><a class="addrelease" href="#" cat_id="2">add</a></td>
<td>Item 2</td>
</tr>
</table>
<div id="list"></div>
<script>
$("a.addrelease").click(function (e) {
e.preventDefault();
cat_id = $(this).attr('cat_id');
remove_str = " remove";
str = cat_id + remove_str;
$(str).appendTo("#list").hide().fadeIn();
});
$("a.remove").click(function (e) {
alert("This function doesn't seem to be called");
$(this).parent().remove(); //Doesn't happen..
});
</script>
I'm guessing that javascript doesn't recognize the new generated items - but I'm not sure, so I'm not sure where to start fixing it
Cheers
You should use live function to attach events to dynamically added elements.
Try this to bind click event to a.remove elements:
$("a.remove").live("click", function (e) {
alert("This function doesn't seem to be called");
$(this).parent().remove(); //Doesn't happen..
});
You're absolutely right, javascript won't recognise new items.
jQuery selectors will normally only match against elements currently in the document. When you use $("a.remove").function(), jQuery builds a list of nodes matching "a.remove", then calls function() on each of them.
The .live() function is special, and doesn't attach events directly to elements - instead, events bubbling up to the top of the DOM are evaluated to see if they match the selector.
IMHO, the best approach is to bind the remove handler when you create the new list entry:
str = cat_id + remove_str;
var remove = $(str);
remove.appendTo("#list").hide().fadeIn();
remove.click(function(e) { .... })
Disclaimer: Typed late at night & not tested!
Here is my answer of how I think you should modify your code:
http://jsfiddle.net/RY5CP/
<table>
<tr>
<td><a class="addrelease" href="#" rel="1">add</a></td>
<td>Item 1</td>
</tr>
<tr>
<td><a class="addrelease" href="#" rel="2">add</a></td>
<td>Item 2</td>
</tr>
</table>
<div id="list"></div>
<script type="text/javascript">
$("a.addrelease").click(function(e) {
e.preventDefault();
var catId = $(this).attr('rel');
var itemName = $(this).closest('td').next('td').text();
var newItem = '<p>' + catId + ' ' + itemName + ' remove';
$(newItem).appendTo('#list').hide().fadeIn();
});
$("a.remove").live('click', function(e) {
$(this).parent('p').remove();
});
</script>
It's not valid to use cat_1, cat_2 as HTML attributes. You can use the rel attribute if you need to have a specific value to be associated to your items
Use the live() method to have the click event handler automatically attached to items dynamically created
How do I remove the parent element and all the respective nodes using plain JavaScript? I'm not using jQuery or any other library.
In other words, I have an element and when user clicks on it, I want to remove the parent of the parent element (as well as the respective children nodes).
<table id='table'>
<tr id='id'>
<td>
Mohit
</td>
<td>
23
</td>
<td >
<span onClick="edit(this)">Edit</span>/<span onClick="delete_row(this)">Delete</span>
</td>
<td style="display:none;">
<span onClick="save(this)">Save</span>
</td>
</tr>
</table>
Now,
function delete_row(e)
{
e.parentNode.parentNode.removeChild(e.parentNode);
}
Will remove only last <td>.
How do I remove the <tr> directly>?
e.parentNode.parentNode.getAttribute('id')
returns the id of the row...
Is there any function like remove() or delete() ?
Change your function like this:
function delete_row(e)
{
e.parentNode.parentNode.parentNode.removeChild(e.parentNode.parentNode);
}
You can now use node.remove() to remove the whole element
so in your case you'd do
function delete_row(e) {
e.parentElement.remove();
}
You can read more on it here
https://developer.mozilla.org/en-US/docs/Web/API/ChildNode/remove
node.parentNode.parentNode.removeChild(node.parentNode)
Edit: You need to to delete parent of parent, so add one more .parentNode
node.parentNode.parentNode.parentNode.removeChild(node.parentNode.parentNode)
Or for those who like a one-liner
<button onClick="this.parentNode.parentNode.removeChild(this.parentNode);">Delete me</button>
Change this:
onClick="delete_row(this)"
To this:
onClick="removeParents(this, document.getElementById('id'))"
function removeParents(e, root) {
root = root ? root : document.body;
var p = e.parentNode;
while(root != p){
e = p;
p = e.parentNode;
}
root.removeChild(e);
}
http://jsfiddle.net/emg0xcre/
You can specify it even more. Instead of parentElement.parentElement you can do something like this:
static delete_row(element) {
element.closest("tr").remove();
}
The other preferred way of handling such scenario would be event propagation instead of adding onclick to html element:
document.querySelector("#id").addEventListener("click", (e) => {
UI.handleEvents(e.target);
});
static handleEvents(el){
if (el.classList.contains("delete")) {
el.closest("tr").remove();
}
if (el.classList.contains("edit")) {
// do something else
}
if (el.classList.contains("save")){
// save records
}
}
<tr id='id'>
<td>Mohit</td>
<td>23</td>
<td >
<span class="edit">Edit</span> |
<span class="delete">Delete</span>
</td>
<td style="display:none;"><span class="save">Save</span></td>
</tr>
Simple function to do this with ES6:
const removeImgWrap = () => {
const wrappedImgs = [...document.querySelectorAll('p img')];
wrappedImgs.forEach(w => w.parentElement.style.marginBottom = 0);
};
I know it's a little too late, but someone else might find it useful.
e.target.parentElement.parentElement.parentElement.remove()
<div>
<span>1<button onclick="removeParents(this);">X</button></span>
<span>2<button onclick="removeParents(this);">X</button></span>
<span>3<button onclick="removeParents(this);">X</button></span>
<span>4<button onclick="removeParents(this);">X</button></span>
</div>
<script>
function removeParents(e) {
var root = e.parentNode;
root.parentNode.removeChild(root);
console.log(root);
}
</script>
working sample
If you want to delete whatever is inside the <tr> tags, by clicking on the "Delete", give that span a class name (whatever you want).
Then, in JS code: you basically select the element people will click with the document.querySelector(), add an Event Listener to it & on clicking on that span with that .whatever class, the element with the ID name "id" will be removed.
document.querySelector('.wtvr').addEventListener('click', function () {
document.getElementById('id').remove();
});
<table id="table">
<tr id="id">
<td>Mohit</td>
<td>23</td>
<td><span>Edit</span>/<span class="wtvr">Delete</span></td>
<td style="display: none">
<span>Save</span>
</td>
</tr>
</table>
I took the onclick away because you can delete a DOM element just using CSS class and a bit of JS.