I have been trying for over a week now to slideToggle a table row when the 'more info' button is clicked but nothing seems to be working at all.
I'm new to Jquery so if anyone ca help me slideToggle the 'more-info-1', 'more-info-2', 'more-info-3' tr tags. the main problem is that those id's are created dynamically through php and I don't understand how to select them in Jquery - like using 'more-info-' or something.
I would like it to work like this example:
Here minus the iframes of course.
The user will click the 'more info' button and then the 'more-info-' tr will slide down.
Here is the page source: (I don't know how to insert HTML properly on Stack OverFlow, is there a special way of doing it - the code button does not work properly with HTML)
html
div id="output-listings"
div class="main-info"
table class="listings"
tbody
tr id="more-info-1" class="mi-1"
td
div id="more-1" class="more-information"/div
/td
/tr
tr id="main-info-1"
tdLeftlane News/td
tdwww.leftlanenews.com//td
tda id="link-1" class="more-info-link" href="#"More info/a/td
/tr
tr id="more-info-2" class="mi-2"
td
div id="more-2" class="more-information"/div
/td
/tr
tr id="main-info-2"
tdMotor Authority/td
tdwww.motorauthority.com/ /td
tda id="link-2" class="more-info-link" href="#"More info/a/td
/tr
tr id="more-info-3" class="mi-3"
td
div id="more-3" class="more-information"/div
/td
/tr
tr id="main-info-3"
tdAutoblog/td
tdhttp://www.autoblog.com//td
tda id="link-3" class="more-info-link" href="#"More info/a/td
/tr
/tbody
/table
/div
/div!--end output-listings--
/html
I would greatly appreciate the help.
Though craig's response works, you can limit your code and allow jquery to grab all of your TR elements within a certain scope, and parsing out the id as he suggested, etc.
$(".listings tbody tr").each(function(index) {
// hide by default
$(this).css({'display': 'none'});
// set the onclicks
$(this).click(function() {
// your dosomething can change your appearance
dosomething(the_id_you_parse_out);
});
});
Not sure if thats working code, I just threw it together so you could get the gist of how to use jquery's selector.
From a quick glance it looks like you want something like this.
$('#link-1').click(function(){
$('#more-info-1').slideToggle()
})
You can also generalize this script to work with all three by changing how the classes are set up, or by having the inner function parse the number of th link that is clicked and feed that into the inner jQuery call:
$('.more-info-link').click(function(){
var id = $(this).attr('id');
var num = id.substr(id.length-1,1);
$('#more-info-'+num).slideToggle();
})
To keep the trs from being visible add style='display:none' to them.
Depending on whether you need to assign a specific id to your elements for another purpose, you can actually do this without needing to give individual id's.
In this example, on load we first hide any tr that have the class toggleable. Then we tell jQuery to jump up the dom a couple of levels, and hide the next tr - this removes the need to call an id.
Example jQuery for this:
$(document).ready(function(){
$("#tableToggle tr.toggleable").hide();
$("#tableToggle .tableToggleButton").click(function(){
$(this).parent().parent().next('tr').slideToggle();
});
});
Example modified table:
<table id="tableToggle">
<tbody>
<tr>
<td><div class="tableToggleButton">More info 1</div></td>
</tr>
<tr class="toggleable">
<td>Main info 1</td>
</tr>
<tr>
<td><div class="tableToggleButton">More info 1</div></td>
</tr>
<tr class="toggleable">
<td>Main info 1</td>
</tr>
</tbody>
</table>
Since jquery code usually executes only when the DOM is ready, you'll always see the TR's even if only for a millisecond until your js code hides it if you don't use CSS initially to hide it.
So most of the contributors here probably answered your question. I'd just like to add that you could initially hide the TR's using CSS and then use JS to do the rest.
A good rule of thumb is to try and get your "default" pageview by only using CSS, and then add the rich functionality with the jquery code. Or at least that's what I'd do.
Related
I need to get all selector that match the condition so I can iterate thru it later on. My code does not return any values. Probably syntax is wrong so I would appreciate if you help me (haven't written lots in js).
Here is the html
function restore_hp(){
var percent_restore = document.querySelectorAll("table.table.table-condensed.table-top-spacing > tr > td[2]");
percent_restore.forEach((td)=>{
console.log(td.innerText)
});
}
You are probably looking for td:nth-child(2) at the end of your selector.
Your current td[2] would select such a table cell: <td 2="some-attribute-value">...</td>. Notice that this would be invalid HTML because a) 2 is an invalid attribut identifier (cannot start with a number) and b) even if it in general would be valid syntax it wouldn't be known for HTMLTableCellElement, and thus again, invalid HTML.
2nd issue:
> selects direct children only. tr is not a direct child of your table (it never is, missing tbody is auto-inserted by all browsers).
What you want is something called :nth-child pseudo selector. Learn more from the below link-
https://www.w3schools.com/cssref/sel_nth-child.asp
SO your function may be like-
function restore_hp(){
var percent_restore = document.querySelectorAll("table.table.table-condensed.table-top-spacing tr td:nth-child(2)");
percent_restore.forEach((td)=>{
console.log(td.innerText)
});
}
Codepen: https://codepen.io/ashfaq_haq/pen/WNNOYRR
You can add a HTML class to the elements you want to manipulate and simply query on the class :
...
<tr>
<td>Some text</td>
<td class="my-custom-class">Some other text</td>
</tr>
...
var percent_restore = document.querySelectorAll(".my-custom-class");
percent_restore.forEach((td)=>{
console.log(td.innerText)
});
That way you're not lost in your HTML tree.
What I am trying to do is to get an element out of a list. I want to take the text in a link and click on the link if it contains the right text. this is the html-code:
<table>
<td>
<tr><a href='...'>I need help</a></tr>
<tr><a href='...'>Oh hello</a></tr>
<tr><a href='...'>Lorem ipsum</a></tr>
</td>
</table>
I tried this:
.click('table > td > tr > a:contains("I need help")')
But for some reason it doesn't work.
I can't use this:
.click('table > td > tr:nth-child(1) > a)
because there will be added more tr tags as the site gets bigger.
Any ideas ?
You did not create table properly, it should be:
<table>
<tr><td><a href='...'>I need help</a></td></tr>
<tr><td><a href='...'>Oh hello</a></td></tr>
<tr><td><a href='...'>Lorem ipsum</a></td></tr>
</table>
and this js code working properly
$(document).ready(function(){
$("table tr td a:contains('I need help')").click(function(){
});
});
First of all, your HTML code is a bit twisted; a <td> has to be a child of an <tr> element, not the way around. I suggest to read the MDN Docs regarding <table> elements.
Regarding your problem with Dalek; Dalek uses the CSS selector engine of the browser that it executes. This will change in the future (Replaced by Sizzle as a unified selector engine), but I have no estimation when this future exactly will be.
Regarding the :contains() pseudo selector - As far as I know, this is gone. The current CSS3 spec has removed it & therefor you can't use that in your Dalek selectors.
Im havin problems in selecting my first 2 td of every tr(i need to make them lickable) and my last td of every tr(different links). Can someone help me with the code? I cant seem tofigure it out. The code seems legit but it doesnt work.
Here is the js and html:
JS
$(".rand_notif td:lt(2)").click(function(){
$(".rand_notif").html("asd");
})
HTML (somehow..still js but html)
$.each(data.notif,function(i,x){
var cant='';
if(x.cant>0){var cant = x.cant+"x";}
notificari+="<tr class='spacer_2'></tr><tr class='notificari rand_notif' record='"+x.id+"'><td>"+cant+"</td><td>"+x.nume+"</td><td>Refuz</td></tr>";
});
Actual html
<table cellspacing="0" id="tabel_notificari">
<tr class="spacer_1"></tr>
<tr class="table_head notificari">
<th width="30"></th>
<th>Notificari</th>
<th width="86"></th>
</tr>
</table>
EDIT: Problem solved. The problem was, as explained in the comments, the fact that the elements were first binded then added, therefore the bind didnt exist.
Solution:
$("#tabel_notificari").on("click", ".rand_notif td:lt(2)",function(){$(".rand_notif").html("asd");});
You are creating the table cells via javascript, so you need to use a different method to attach the click event to them. Try using the "ON" method attached to the table itself, as shown below. This will apply to any TD added to the table after the DOM loads.
$("#tabel_notificari").on("click", ".rand_notif td:lt(2)", function(e) {
$(this).html("asd");
});
There are no TD tags in your HTML. Did you mean TH?
I want to insert some table cells at a specific location into a table, so I mark this location with a , e.g.
<tr>
<td>first</td>
<div class='insert-here'></div>
<td>last</td>
</tr>
However, jquery removes the div where it should be included, for example
$('<tr><div class="asd"></div></tr>') returns [<tr></tr>]
The simple solution is to tag the first cell and insert after this. Since I am using backbone views, the view will have the context of the entire row, instead of just its cells.
Has anyone come up with a nice solution to this?
<tr> elements may only contain <td> or <th> elements as children.
something like this?
$("tr td .insert-here").before("<div id='new_div'>helo</div>");
$("tr td .insert-here").remove();
If I have a table
<table id="myTable"><tr><td>First Thing</td><td>First Value</td></tr>
<tr><td>Second Thing</td><td>Second Value</td></tr>
<tr><td>Third Thing</td><td>Third Value</td></tr>
</table>
How can I use JQuery or javascript to search to get the index of the row with text "Second Value" and remove it? Also is it possible to create a new row
<tr><td>Fourth Thing</td><td>Fourth Value</td></tr>
with the click of a button? Will I have to iterate through the existing rows to get the last index of the row to insert it in?
You can achieve this easily using the :contains() selector, the remove() function, and the append() function. You don't need to iterate through the rows to find what you're looking for.
To get the index:
$("#myTable").find("td:contains('Second Value')").parent().index();
To remove it:
$("#myTable").find("td:contains('Second Value')").parent().remove();
To add a row:
$("#myTable").append("<tr><td>Fourth Thing</td><td>Fourth Value</td></tr>");
working example: http://jsfiddle.net/hunter/PzJWC/
You should ideally generate id's per each tr/td - but thats if you getting data dynamically i suppose.
If you know the order of your tables then you can use these sleectors from jQuery
$('tr:last-child').html('<p>This is the absolouty last tr in the WHOLE page<p>')
$('tr:nth-child(even)').addClass('evenColors')
$('tr:nth-child(4n)').remove() //Removes the 4th from the top TR DOM Element
var theValueOf = $('tr:first-child').html() //assigns the innerHtml to your var
So if you have 10 tables each table should have an id or class
<table id="table1"> ...bla... </table>
$('table1 tr:last-child').remove() //Remove last TR from Table1
You will need to structure your html more with id's and classes
In your case you will have to restructure your table some how programatically to atach unique ids to each row then use jquery to select it. This is ideal world
But you do a loop and check each inner html until what you want and do a .remove()
But to get the INDEX use hunters reply! But from experience this is a headache on large and dynamic documents.
JQuery has .insertAfter and insertBefore. For targeting you can also use nth-child css selector or if you want it dynamic (like insert a row after the row they click) you can use the 'this' operator and some dom navigation. All that said be very careful when editing tables on the fly, they have some peculiarities about where things can be inserted and are heavy on performance.
i just did it ;)
to add row (you may not want to use append because your table may have tbody etc):
$('#myTable tr:last').after('<tr id="forth_row"><td>forth thing</td><td>forth value</td></tr>');}
to find and remove that row:
$('#myTable').find("#forth_row").remove();