Toggle selected elemens class - javascript

I have a dynamically loaded table with the following tr's:
<tr>
<td><span class="active">Task Name</span><br /><span class="icons_small">U</span><span class="contact_name tiny">Contact Name</span><span class="user_number tiny">(111111)</span><span class="icons_small" style="visibility:hidden;">!</span></td>
<td><span class="date_assigned">13/12/2012</span><br /> <div id="progressbar"></div></td>
<td class="icons_small"><span class="flag_task">f</span></td>
<td class="icons_small"><span class="set_reminder">A</span></td>
<td><span class="warning tiny" style="visibility:hidden;">Delete</span></td>
</tr>
Im trying to set the td with the spanclass "flag_task" (3rd td down) to toggleclass an additonal class, but only on the selected td with the spanclass "flag_task, not all instances of that class. This is what im currently using:
<script>
$(document).ajaxSuccess(function () {
$(".flag_task").click(function () {
$(".flag_task").toggleClass("warning");
});
});
</script>
Could someone please clarify how to effect only the selected instance.
Thanks,
Mark

In this section of the code, you're saying "grab all elements with a class of flag_task" instead of just "grab the clicked element."
$(".flag_task").click(function () {
$(".flag_task").toggleClass("warning");
});
So, to fix this issue, you just have to select the element that was clicked on.
This line:
$(".flag_task").toggleClass("warning");
Can be changed to:
$(this).toggleClass("warning");
Check out Understanding the "this" keyword

Related

Using same Class to use the click method to show the nearest hidden element by its class

What I am trying to achieve: What I am trying to achieve is very simple I have a table with 2 table body tags. The first one gets shown as its just the main content. The last td element has an anchor tag, this anchor tag when clicked should show the next tbody tag using the jQuery method slideToggle().
Problem: The problem I am having is these are dynamically made tables using Angular.js. So if there are 5 items then there are 5 div elements each with a table that all have the same class for each tbody within the div. This makes sense as for each I would like the click function to show that specific tables second div if the user wants to see additional content related to that item.
Things tried:
$(this).next('.test').slideToggle();
$(this).closest('tbody').find('.test').slideToggle();
$(this).closest('.test').slideToggle();
$(this).closest('tr').find('.test').slideToggle();
Posts look into on StackOverflow for similar issue:
affect only the clicked element in jquery for multiple elements with same class
Using a class name in jQuery's .closest()
jQuery closest(); not working
Jquery adding click function to several spans with the same Class
Non Stack Overflow sites:
https://www.sitepoint.com/jquerys-closest-parents/
HTML:
<div class="productsList" ng-repeat="products in productListing.products">
<div class="productSection">
<div class="figureDiv">
<figure class="img">
<img ng-src="{{products.image}}" />
</figure>
</div>
<div class="description">
<h2 ng-bind="products.summary"></h2>
<summary ng-bind="products.description"></summary>
</div>
<table class="productTable">
<tbody>
<tr><td><b>Product Name</b></td><td ng-bind="product.merchantName"></td></tr>
<tr><td><b>Valid:</b></td><td>{{products.validityStart}} to {{products.valididtyEnd}}</td></tr>
<tr><td><b>Product Type:</b></td><td>Appliance</td></tr>
<tr><td><b>Testing:</b></td><td>Yes<a class="testLink" href="">Show More ></a></td></tr>
</tbody>
<tbody class="test">
<tr><td><b>Extra</b></td><td>Extra</td></tr>
<tr><td><b>Extra</b></td><td>Extra</td></tr>
<tr><td><b>Extra</b></td><td>Extra</td></tr>
<tr><td><b>Extra</b></td><td>Extra</td></tr>
</tbody>
</table>
</div>
</div>
jQuery (current implementation):
function init() {
jQuery(document).ready(function(){
$(document).on("click", ".productTable .testLink", function (ev) {
ev.stopImmediatePropagation();
$(this).closest('tr').find('.test').slideToggle();
$(".test").slideToggle();
});
}
Visually from Dynamic content (3 items):
Table class="productTable"
tbody
anchor tag class="testLink"
tbody class="test"
Table class="productTable"
tbody
anchor tag class="testLink"
tbody class="test"
Table class="productTable"
tbody
anchor tag class="testLink"
tbody class="test"
Ending
As you can see visually there are 3 tables created each having same classes. So for the first table if the user clicks the anchor tag then the body tag right after in that specific table will be displayed with toggle. Only that one should be shown not all of them which is the current problem.
I tried many solutions however nothing is working, every implementation is making all of them toggle which is horrible.
I think something like this.
$(".productTable .testLink").on("click", function() {
$(this).parents('.productTable').children('.test').slideToggle();
});
.testLink {
color: blue;
text-decoration: underline;
}
.test {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table class="productTable">
<tbody>
<tr>
<td><b>Product Name</b>
</td>
<td ng-bind="product.merchantName"></td>
</tr>
<tr>
<td><b>Valid:</b>
</td>
<td>{{products.validityStart}} to {{products.valididtyEnd}}</td>
</tr>
<tr>
<td><b>Product Type:</b>
</td>
<td>Appliance</td>
</tr>
<tr>
<td><b>Testing:</b>
</td>
<td>Yes<span class="testLink">Show More ></span>
</td>
</tr>
</tbody>
<tbody class="test">
<tr>
<td><b>Extra</b>
</td>
<td>Extra</td>
</tr>
<tr>
<td><b>Extra</b>
</td>
<td>Extra</td>
</tr>
<tr>
<td><b>Extra</b>
</td>
<td>Extra</td>
</tr>
<tr>
<td><b>Extra</b>
</td>
<td>Extra</td>
</tr>
</tbody>
</table>
I think the problem is in this line of your jQuery $(".test").slideToggle(); as it will execute slideToggle on all .test try removing it. Also update.closest('tr'); to .closest('table'); as the .test is in the table tag not the tr
From what I make out, you are looking for JQuery's .next() method. Just for the parent tbody and call .next()
Example would be
$('.testLink').parentsUntil('tbody').next().show();

Using each() for checking which class is clicked

So here's my problem, I'm new to jQuery. What I am trying to do here is check for user to click on a certain table cell/row and it would then display a div named popup of an index the same as the table cell votes. Without having to make separate functions of all the rows in my table.
Using some numerical value will display all the dialogs from a click of the cell of the same value the first time and from the second time only the correct one.
I bet there's some other way to do it and maybe there's just a stupid error.
Using the index value in the click and dialog function won't work.
I am open to suggestions on improvement also.
The scripts:
<script type='text/javascript'>
$(document).ready( function() {
$('.votes').each(function(index) {
$('.votes:eq(index)').click(function() {
$('.popup:eq(index)').dialog();
});
});
});
</script>
HTML for the table part, only a snippet
<td class='votes'>5</td>
<td class='votes'>15</td>
<td class='votes'>25</td>
HTML for the div part, only a snippet of the div:
<div class='popup'>
<ul>
<li>John Johnsson</li>
<li>John Doe</li>
</ul>
</div>
<div class='popup'>
<ul>
<li>Matt Theman</li>
<li>Peter Watley</li>
</ul>
</div>
jsFiddle Demo
You don't have to iterate using each for .click, that will happen internally. You can use .index() to get the index of the element clicked with reference to its parent.
$('.votes').click(function() {
$('.popup').eq($(this).index()).dialog();
});
Initially, the main problem is that you are not using string concatenation to apply the index to the selector (demo):
$('.votes:eq(index)')
// the Sizzle selector engine doesn't know what the string "index" is.
instead of
$('.votes:eq(' + index + ')')
// using concatenation calls the .toString() method of index to apply "0" (or "1", "2", etc.)
// so that the parsed string becomes '.votes:eq(0)' which the Sizzle selector engine understands
Once the Sizzle selector engine understands which elements to target (demo), the second problem is how jQueryUI changes the DOM with the .dialog method.
Inital markup:
<table>
<tbody>
<tr>
<td class="votes">5</td>
<td class="votes">15</td>
<td class="votes">25</td>
</tr>
</tbody>
</table>
<div class="popup">
<ul>
<li>John Johnsson</li>
<li>John Doe</li>
</ul>
</div>
<div class="popup">
<ul>
<li>Matt Theman</li>
<li>Peter Watley</li>
</ul>
</div>
Once the first click event is handled, one of the div.popup elements is transformed into a jQueryUI Dialog and is appended to the body, removing it from its initial position, like so:
<table>
<tbody>
<tr>
<td class="votes">5</td>
<td class="votes">15</td>
<td class="votes">25</td>
</tr>
</tbody>
</table>
<div class="popup">
<ul>
<li>Matt Theman</li>
<li>Peter Watley</li>
</ul>
</div>
<div class="ui-dialog ui-widget ..."> ... </div>
So your initial indexes no longer apply. Fortunately, there are several solutions to both problems (a few of which I've listed below).
Solutions to Problem 1:
Use string concatenation as described above.
Use the .eq method instead, which will accept the index variable as-is
Use a delegate handler instead and grab the index from within the handler:
Example of 2:
$('.votes').eq(index);
Example of 3:
$('table').on('click', '.votes', function (e) {
var vote = $(this),
index = vote.parent().index(vote);
});
Solutions to Problem 2:
Create all of the dialogs initially and open them as needed.
Create the dialogs using a deep clone of the div element. (Not recommended)
Remove the td element to match the removed and re-appended div element. (Not recommended)
Example of 1:
var popups = [];
$('.popup').each(function (i, elem) {
var popup = $(elem).data('index', i).dialog({
"autoOpen": false
});
popups.push(popup)
});
$('table').on('click', '.votes', function (e) {
var vote = $(this),
index = vote.index();
popups[index].dialog('open');
});
I'm sure there are other solutions as well, but these are the ones I thought of of the top of my head.
Functional demo: http://jsfiddle.net/2ChvX/2/
UPDATE:
With your chosen table structure, you're actually looking for the index of the parent tr element as that is what corresponds with the div.popup element. To get the index of the parent tr element, change the line that gets the index from:
index = vote.index();
to:
index = vote.parent().index();
Updated fiddle: http://jsfiddle.net/AZpUQ/1/
Updated
FWIW, here's an example using the jQueryUI dialog (which I presume you are using?) and javascript sectionRowIndex and cellIndex.
Reusable code allowing you to identify the cell the user clicked in and perform appropriate action.
http://jsfiddle.net/KbgcL/1/
HTML:
<table id="myTable">
<tr>
<th>Label:</th>
<th>Washington</th>
<th>Idaho</th>
<th>California</th>
</tr>
<tr>
<td class='label'>Votes</td>
<td class='votes'>5</td>
<td class='votes'>15</td>
<td class='votes'>25</td>
</tr>
<tr>
<td class='label'>Voters</td>
<td class='voters'>5,000</td>
<td class='voters'>15,000</td>
<td class='voters'>25,000</td>
</tr>
</table>
<div id="msg"></div>
jQuery/javascript:
var myTr;
$('#msg').dialog({
autoOpen:false,
title: 'Report:'
});
$('#myTable tr td').click(function() {
myTr = $(this).closest('td').parent()[0].sectionRowIndex;
myCell = this.cellIndex;
myState = $('#myTable').find('tr:eq(0)').find('th:eq(' +myCell+ ')').html();
myVoters = $('#myTable').find('tr:eq(' +myTr+ ')').find('td:eq(' +myCell+ ')').html();
if (myTr==2 && myCell==3){
//California
$('#msg').html('There are ' +myVoters+ ' voters in ' +myState);
$('#msg').dialog('open');
}else if(myTr==1 && myCell==1){
$('#msg').html('There were ' +myVoters+ ' votes made in ' +myState);
$('#msg').dialog('open');
}
});

How to do this hide all rows except one row in jQuery?

How to hide All rows except current (clicked Row) using jQuery?
I want to hide all rows when i click the particular row except current one row.
<table>
#foreach (var item in Model)
{
idValue++;
<tr class="tableRow" id="#idValue">
<td class="master" id="#item.Batch_Seq">
<a href= "#" >#(item.Batch_Name)></a>
</td>
<td>
#(item.Present)
</td>
<td>
#(item.Absent)
</td>
<td>
#(item.HalfDay)
</td>
<td>
#(item.Batch_count)
</td>
</tr>
}
</table>
I tried like this
$('.tableRow').hide();
$(this).closest('tr:not(.tableRow)').hide();
Could anyone help me?
You seem to want this :
$('.tableRow').click(function(){
$('.tableRow').hide(); // hide all rows
$(this).show(); // show the clicked one
});
Note that the user can't notice the row was hidden then shown : the screen isn't repaint until the event handler ends.
Use .not() to select all elements with class tableRow except for the one that was clicked(this)
$('tr.tableRow').click(function() {
$('tr.tableRow').not(this).hide();
});
You can use not() to hide everything that isn't "this":
$('table tr.tableRow').click(function(){
$('table tr').not(this).hide(); // hide everything that isn't "this"
});
or you can use .siblings() to hide the siblings of the clicked row
$('table tr').click(function(){
$(this).siblings().hide(); // hide the siblings of the clicked row
});
Working example : http://jsfiddle.net/ouadie/U7eUR/

onclick defined text-var returns emptystring on log

var listname=$(this).parents(".x-grid3-row-table").children(".x-grid3-cell-inner.x-grid3-col-1").text();
console.log(listname);
the console.log returns following:
(an empty string)
can you help me on why listname is empty? and could you also tell me how to pass listname as parameter to a server-side method in an Ext.Ajax.request?
this is the html-code coming from my generated page:
<table class="x-grid3-row-table>
<tr>
<td class="x-grid3-col x-grid3-cell x-grid3-td-1 " tabindex="0" style="text-align: left;width: 265px;">
<div class="x-grid3-cell-inner x-grid3-col-1" unselectable="on">foo_bar#domain.de</div>
</td>
<td class="x-grid3-col x-grid3-cell x-grid3-td-2 x-grid3-cell-last " tabindex="0" style="width: 59px;">
<div class="x-grid3-cell-inner x-grid3-col-2" unselectable="on">
<span class="free">free</span>
</div>
</td>
</tr>
<tr class="x-grid3-row-body">
<!-- 7 Elements Markup down, who all act wrapping for the following -->
<div class="details">
<!-- some other markup elements, who also contain data, but are not further interesting-->
<td class="data"> foo bar detail data </td><!-- not of interest-->
<td class="edit"><input value="edit" onclick="see function on top" type="button" /> </td>
</div>
</tr>
</table>
target is to extract: foo_bar#domain.de and pass it to a server-method as parameter. the method is supposed to make a Window, but that's a different story.
the onclick call is from a expanded grid panel body, which is wrapped in a table('.x-grid3-row-table') with the given html-code.
You have a space between class names in your children selector, however your markup suggests that both the class names are of same elements.
To select an element with more than one class names the selector should not have space between class names as .classname1.className2.
var listname=$(this).parents(".x-grid3-row-table").children(".x-grid3-cell-inner.x-grid3-col-1").text();
console.log(listname);
should work.
Further clarification:
If you have space between class names as in question it would mean that you are trying to select an element having .x-grid3-col-1 class within .x-grid3-cell-inner class. Which is parent child relationship.
Edit:
If your button is in the next row you can use .prev() selector of JQuery with combination of using tr as parent selector rather than table.
listname=$(this).parents("tr").prev().children(".x-grid3-cell-inner.x-grid3-col-1").text();
Or if it is in same row then simply
listname=$(this).parents("tr").children(".x-grid3-cell-inner.x-grid3-col-1").text();
There might be a cleaner way of doing this but I came up with this as your button click handler, it assumes that the text() your looking for is one table row up from the button.
var $rows,button=this,i;
$rows=$(".x-grid3-row-table tr");
for(i=0;i<$rows.length;i++){
// get the button of that row
// not sure how to as your button is not
// in a table row with the code you posted
if($rows[i].getElementsByTagName("input")[0]===
button){
break;
}
}
// I assume the button is in a row before the button
console.log($($rows[i-1])
.find(".x-grid3-cell-inner.x-grid3-col-1")
.text()

jQuery .next() elements

This change from mootools drives me crazy.
HTML
<tr class="teamicon">
<td style="text-align: center;" width="100%" valign="middle">
//Blahblah
</td>
</tr>
<tr class="teamval">
<td valign="middle" width="100%">
//Blahblah
</td>
</tr>
What I want to achieve. When with class "teamicon" is clicked I want to show/hide tr with class teamval with animation. However, I can't make it animate properly. Looks like inside "teamval" must be animated first (or am I wrong?).
My try:
jQuery(document).ready(function(){
$('.teamval').slideUp(400);
$('.teamicon').click(function(){
if ($(this).next('tr').is(":hidden"))
{
$(this).next('tr.teamval').$('td').slideDown(400, function(){
$(this).next('tr.teamval').slideDown(400);
});
}
else
{
$(this).next('tr.teamval').$('td').slideUp(400, function(){
$(this).next('tr.teamval').slideUp(400);
});
}
});
});
OFC. This is wrong ("$(this).next('tr.teamval').$('td')" returns error in firebug). How can I achieve this?
I can't swap to div though.
You could do one of:
$(this).next('tr.teamval').slideDown(...) // whole tr
$(this).next('tr.teamval').find('td').slideDown(...) // td descendant
The error is because you are trying to access a $ property on the jQuery element set, which doesn't exist. Instead we can use find, which searches for matching descendants of elements in the current set.
EDIT:
Okay, I think you want:
if ($(this).next('tr').is(":hidden"))
{
var nextTeamval = $(this).next('tr.teamval');
nextTeamval.find('td').slideDown(400, function(){
nextTeamval.slideDown(400);
});
}
The only potential problem is if teamval contains a td within a td (nested table). You can try this jsFiddle demo.

Categories

Resources