Using slideToggle with table rows (nesting a div) not working - javascript

After reading around it seems that a good solution to using slideToggle() on table rows is to nest a div inside. I've tried the following, but it doesn't seem to work at all.
jQuery
function toggle_dropdown(entry_id) {
$(".library-dropdown-animation").slideUp("slow"); // Slide up any that are open
$(".library-edit-dropdown").style.display = "none"; // Set their table row displays to none
$("#library-dropdown-animation-" + entry_id ).slideDown("slow"); // slide the clicked one down
$("#library-edit-dropdown" + entry_id ).style.display = "block"; // set it's parent table row's display to block
}
HTML
<tr class="library-item-header">
<td class="library-item-title" onclick="toggle_dropdown(123);" style="cursor: pointer;">
<?php echo $anime_name; ?>
</td>
</tr>
<tr id="library-edit-dropdown-123" class="library-edit-dropdown" style="display: none;">
<td colspan="4">
<div class="library-dropdown-animation" id="library-edit-animation-123">
</div>
</td>
</tr>
<tr class="library-item-header">
<td class="library-item-title" onclick="toggle_dropdown(124);" style="cursor: pointer;">
<?php echo $anime_name; ?>
</td>
</tr>
<tr id="library-edit-dropdown-124" class="library-edit-dropdown" style="display: none;">
<td colspan="4">
<div class="library-dropdown-animation" id="library-edit-animation-124">
</div>
</td>
</tr>
<tr class="library-item-header">
<td class="library-item-title" onclick="toggle_dropdown(125);" style="cursor: pointer;">
<?php echo $anime_name; ?>
</td>
</tr>
<tr id="library-edit-dropdown-125" class="library-edit-dropdown" style="display: none;">
<td colspan="4">
<div class="library-dropdown-animation" id="library-edit-animation-125">
</div>
</td>
</tr>
So essentially, I've got a td in another row that when it's clicked it slides it's content row (right beneath it) down while sliding any other row up. Since we can't use slide on table row (hide() and show() and toggle() works perfectly fine by the way) i've used a containing div that has content, in this example i've left the content out. In any case, clicking on the td does nothing using this jQuery.
Here is a jsFiddle: http://jsfiddle.net/wxu3E/

Please check this solution: http://jsfiddle.net/wxu3E/2/
i added the events on the Anchor itself not the row by adding a class to it, also I added attribute entry_id
Click
and in the JQuery code the event will be attached to elements with class toggle_dropdown
$(".toggle_dropdown").click

Working Jsfiddle: http://jsfiddle.net/patelmilanb1/LzaZT/
Suggestion: data-attributes might come in handy here... i have added data-attribute in your HTML, please look at the HTML carefully in jsfiddle.
data-id="123"
so your final Jquery looks like this:
$(document).on("click", ".library-item-title", function (e) {
e.preventDefault();
var entry_id = $(this).data("id");
toggleDropdown(entry_id);
});
function toggleDropdown(entry_id) {
$(".library-edit-dropdown").slideUp("slow");
$("#library-edit-dropdown-" + entry_id).slideDown("slow");
}
Error in your code: you are missing - at the end in this line, as your DIV id deos contain -
$("#library-edit-dropdown" + entry_id ).style.display = "block";
try this fiddle for animation: http://jsfiddle.net/patelmilanb1/LzaZT/1/
function toggleDropdown(entry_id) {
$(".library-edit-dropdown").hide("slow");
$("#library-edit-dropdown-" + entry_id).show("slow");
}

Related

jQuery - ForEach function on rendered HTML

I have the following JS/jQuery which grabs the cell value of an ASP DetailsView control (rendered HTML), checks it for a condition, and hides a div based on said condition. It is basically checking to see if the cell value is formatted like an IP address or not...
$(document).ready(function () {
//Grab innerHTML in the IPAddress cell from DetailsView1
//See if it contains the characters: 10.
//If it does not contain '10.', hide the parent div for that user
var ip = document.getElementById("DetailsView1").rows[3].cells[0].innerHTML;
var addrFormat = ip.includes("10.");
if (addrFormat == false) {
$("#IDofDetailsView1ParentDiv").hide();
}
});
This works well, but I need to check several DetailsView controls, and potentially .hide() several elements by ID.
In JS/jQuery, is there a way to:
ForEach rendered HTML element like DetailsView, check format condition, then hide parent div for this control only, if condition is false
Thank you for any advice.
EDITED TO SHOW MARKUP
Here is the rendered HTML I am working with...
<div class="square" id="myId">
<div class="content">
<div><p id="myId2">Unavailable for Dispatch</p>
<div class="table">
<div class="table-cell">
<div id="UpdatePanel1">
<div>
<table class="Grid" cellspacing="0" rules="all" border="1" id="DetailsView1" style="border-collapse:collapse;">
<tr align="center">
<td colspan="2" style="border-style:None;">Text1</td>
</tr><tr align="center">
<td class="building" colspan="2" style="border-style:None;">Text2</td>
</tr><tr align="center">
<td colspan="2" style="border-style:None;">Text3</td>
</tr><tr align="center">
<td class="hide" colspan="2" style="border-style:None;">Text4</td>
</tr><tr align="center">
<td class="hide" colspan="2">Text5</td>
</tr>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
I have several of these on my page. Right now I am using:
var ip = document.getElementById("DetailsView1").rows[3].cells[0].innerHTML;
But I will probably need to use a class selector on "Grid" to process them all at once, correct?
Then I need to hide the very highest div by id, not the closest parent. But ONLY hide those divs whose td 'Text 4' value is false. I am not sure how to grab the innerHTML I am currently getting from "DetailsView1", if I use the Grid class instead.
Thank you again...
Uses for each and then use 'this' to target individual elements.
EDIT: Had to edit this and removed includes() as it does not work in very many browsers. Now I am converting the HTML of all .Grid elements toString() and then I use indexOf() on that string to determine if it contains 10.
New working fiddle:
https://jsfiddle.net/Lh5kenge/
Updated Code:
$(function(){
$('.Grid').each(function(){
var string = $(this).html().toString()
console.log(string)
if (string.indexOf("10.") > -1) {
$(this).closest('.square').hide()
}
})
})

Apply jQuery to every instance of foreach loop but only operating on the element clicked upon

I am looking to apply jQuery to every instance of foreach loop but only operating on the element clicked upon.
The php foreach loop is below:
#foreach ($entries as $entry)
<?php $row = DB::table('workout_trainings')->where('date', $entry->format('Y-m-d'))->where('user_id', Auth::user()->id)->count(); ?>
<tr style="border-top: 2px solid black;">
<th rowspan={{$row}}><p>{{ $entry->format('l- d/m/Y') }}</p>
<button class="btn btn-default" id="goals_btn">Goals</button>
<button class="btn btn-default" id="logs_btn">Log Workout</button>
</th>
<?php $ws = DB::table('workout_trainings')->where('date', $entry->format('Y-m-d'))->where('user_id', Auth::user()->id)->get(); ?>
#foreach ($ws as $w)
<td>{{$w->exercise}}</td>
<td>{{$w->weight}}</td>
<td>{{$w->sets}}</td>
<td>{{$w->reps}}</td>
</tr>
#endforeach
<tr id="goals">
<td colspan='5'>.</td>
</tr>
<tr id="logs">
<td colspan='5'>.</td>
</tr>
#endforeach
</tbody>
</table>
<?php echo $entries->setPath('')->render(); ?>
The jQuery I have is simply:
$(document).ready(function(){
$("#goals").css("display","none");
$("#goals_btn").click(function(){
$("#goals").toggle(200);
});
});
Which obviously works for the top item.
UPDATE
Slide now works however only on elements with less than two rows filled.
Wednesday doesn't work but Thursday and Friday do in this example.
Thanks
$(document).ready(function(){
$("#goals").css("display","none");
$("#goals_btn").click(function(){
$(this).find("#goals").toggle(200); // use this to point clicked instance
});
});
You need to change the HTML your PHP code is generating as you will have lots of elements with the same id attribute which is invalid; they must be unique within the document. A class would seem more appropriate in this case.
From there you can use the this keyword to reference the element that raised the event and traverse the DOM to find the related tr.goals. Try this:
.goals {
display: none;
}
$(document).ready(function(){
$(".goals_btn").click(function(){
$(this).closest('tr').next('.goals').toggle(200);
});
});

Strikethrough Table and/or DIV

I currently utilized this method Linethrough/strikethrough a whole HTML table row and it works great.
However how do I attach it to a HTML check box onclick method?
http://jsfiddle.net/deaconf19/DrEhv/
<table border 1>
<tr>
<td>Status</td>
<td>Priority</td>
<td>Date</td>
<td>Event</td>
<td>Updated</td>
</tr>
<tr>
<td contenteditable/>Checkbox</td>
<td contenteditable/>3</td>
<td contenteditable/>02/07/2014</td>
<td contenteditable/>code needs updating again</td>
<td contenteditable/>02/07/2014</td>
</tr>
<tr class="strikeout">
<td contenteditable/>Checkbox</td>
<td contenteditable/>1</td>
<td contenteditable/>02/07/2014</td>
<td contenteditable/>code needs updating</td>
<td contenteditable/>02/07/2014</td>
</tr>
</table>
You can use jQuery, to find check box parents parent and add a class to it when status of checkbox changed
if ( this.checked) {
$(this).parent().parent().addClass("strikeout");
} else {
$(this).parent().parent().removeClass("strikeout");
}
Example
Just use javascript to change the table class. If using jQuery:
$('#myCheckbox').change(function(){
$('#myTableRow').toggleClass('strikeout', $(this).prop('checked'));
})
The text below assumes that you have a checkbox with id="myCheckbox" and a table row with id="myTableRow".
Why use jQuery if pure JS can do the same thing:
In your HTML, add onclick handler for checkboxes:
<input type="checkbox" onclick="strike(this)">
Then change class of TR element based on checkbox value, like this:
function strike(elm) {
if(elm.checked) {
elm.parentNode.parentNode.className = "strikeout";
} else {
elm.parentNode.parentNode.className = "";
}
}
As simple as that !

jQuery replace and add new element

I have the following HTML
<tbody class="t_bdy">
<tr class="Quotation_List_td">
<td class="item"><a class="button2 crm_insert" href="#">Insert</a><a class="button2 crm_delta" href="#">Delete</a></td>
<td class="Quotation_List_ItemTD description"> </td>
<td class="quantitiy"> </td>
<td class="unit_price"> </td>
<td class="discount"> </td>
<td class="total"> </td>
</tr>
<tr class="Quotation_List_td">
<td class="item"><a class="button2 crm_insert" href="#">Insert</a><a class="button2 crm_delta" href="#">Delete</a></td>
<td class="Quotation_List_ItemTD description"> </td>
<td class="quantitiy"> </td>
<td class="unit_price"> </td>
<td class="discount"> </td>
<td class="total"> </td>
</tr>
</tbody>
I need to insert new <tr> when I click on button with .crm_insert class.
When .crm_insertis clicked, it need to insert a new row at the current location. All
other rows will move down. For example, if insert against row 3 is clicked then
row 3 will be new row inserted and current row 3 etc will move down to become
row 4 etc.
How can I achieve this ?
All answers are good, but I can only accept one : Thanks all
I'd try something like this using closest() and before()
$('a.crm_insert')
.click(function()
{$(this).closest('tr.Quotation_List_td').before(htmlcodeofyounewTRhere);}
)
Hope this will help
Assuming:
Your new row is in the same structure as your current row
You want the new row to also have the 'Insert' functionality
You want a click event handler which does something to this effect:
$('.crm_insert', '#table').on('click', function() {
var currentRow = $(this).closest('tr');
currentRow.clone(true).insertBefore(currentRow);
});
Where #table is the id of your table.
Here's a simple example
If you are inserting something completely different, then you do not need to use on() or clone(), and the code becomes simpler:
$('.crm_insert').click(function() {
var currentRow = $(this).closest('tr');
$('<tr />').insertBefore(currentRow);
});
Where <tr /> would be whatever you are trying to insert.
This might work for you. It'll find the parent tr of the button you just clicked, clone it (including the onClick functionality of the button) and insert that before the parent tr. This will result in a new row containing the same information as the target row though. Depending on what results you want to show in the new row, you might want to alter the code to clear out any copied values too.
$(".crm_insert").live("click", function(){
var tr = $(this).parents("tr.Quotation_List_td");
tr.clone().insertBefore(tr);
});
You can try this
$('.crm_insert').live('click', function(){
var self = $(this);
self.parents('tr.Quotation_List_td').before('add your row here');
});
The latest versions of jquery employ on instead of live.

hide/show not working properly with jquery

I have a page with three rows of main information that all have a 'More Info' button attached, sort of like wefollow.com and their info button.
When the 'More Info' link is clicked a <tr> with a class of "mi" slides down above the main info.
The problem that I am getting is hiding the <tr> before the 'More Info' link is clicked. There is just a blank space where the <tr> is. The info in the <tr> is being hidden with jQuery (script below) and then displays when 'More Info' is clicked.
I tried hiding the "mi" with CSS but when the 'More Info' button is clicked, nothing happens.
Any help would be awesome. Thanks.
Scripts
index
<table>
<tbody>
<tr id="info-1"> </tr>
<tr class="mi">
<td>
<div id="1" class="more-information" />
</td>
</tr>
<tr class="">
<td> </td>
<td> </td>
<td> <a id="1" class="more-info" href="#">More info</a> </td>
</tbody>
</table>
listing.js
$(function(){
$(".more-information").hide();
$(".more-info").click(function () {
var divname= this.id;
$("#"+divname).load("getinfo.php").slideToggle("slow").siblings().hide("slow");
return false;
});
First problem is you're repeating IDs. They need to be unique. That's no doubt throwing off your code.
<table>
<tbody>
<tr id="info-1"> </tr>
<tr class="mi">
<td><div id="more-1" class="more-information">More information</div></td>
</tr>
<tr>
<td></td>
<td></td>
<td><a id="1" class="more-info" href="#">More info</a></td>
</tr>
</tbody>
</table>
combined with:
$(function() {
$("a.more-info").click(function() {
$("#more-" + this.id).load("getinfo.php").slideToggle("slow").siblings().hide("slow");
});
});
Not sure why you need to hide siblings in the above though.
Also, I wouldn't hide the "more-information" divs in jquery. Just add CSS for that:
div.more-information { display: none; }
You are hiding the more-information div but you are not hiding its parent element, the <tr> with class mi. Try putting the id attribute in the <tr> instead of the enclosed div, and hiding the whole row. Also, you'll have to take cletus' advice about not repeating id's and unnecessary sibling hiding.

Categories