How to change the height of a `<Div>` and its parent `<Td>` - javascript

I have the following mark-up inside a third part application. now for this third part application, I can write custom JavaScript and custom css against the generated markup.
<td style="height:75px">
<div style="height: 75px; opacity: 0.99;" id="MSOPictureLibrarySlideshowWebPart_ctl00_ctl40_g_79ca5882_ef72_482a_9f70_94b4a8c6804e_text">
<span id="MSOPictureLibrarySlideshowWebPart_ctl00_ctl40_g_79ca5882_ef72_482a_9f70_94b4a8c6804e_title" class="ms-slideshow-title"></span><br>
</div>
</td>
So how I can modify the height property, for the <div> and its parent <td> from style="height:75px" to style="height:0px"??

This would select all <td> elements, and all <div> elements that are directly inside a <td> and make their height 0px
$("td, td > div").height(0);
Try this first, but, I suspect this will select more things than you intend it to depending on what else is on this page.
If all the div elements have an ID that begins with MSOPictureLibrarySlideshowWebPart then you can start from there by selecting all of those, and then finding the parent elements. Check the jquery docs for how to do partial attribute matching.
$("div[id^='MSOPictureLibrarySlideshowWebPart']").each(function() {
$(this).height(0).parent().height(0);
});

Use .css()!
You can find each <td>, and use .find() to get the <div> element inside of it.
$('td').each(function(){
$(this).css('height', '0px');
$(this).find('div').css('height', '0px');
});

You can use set max-height:0 to the elements to set height 0 using your parent class
Stack Snippet
td,
div {
background: red;
max-height: 0;
}
<td style="height:75px">
<div style="height: 75px; opacity: 0.99;" id="MSOPictureLibrarySlideshowWebPart_ctl00_ctl40_g_79ca5882_ef72_482a_9f70_94b4a8c6804e_text">
<span id="MSOPictureLibrarySlideshowWebPart_ctl00_ctl40_g_79ca5882_ef72_482a_9f70_94b4a8c6804e_title" class="ms-slideshow-title"></span><br>
</div>
</td>

Related

Traversing on each span under table > tr > td > div

How to traverse on each span under table > tr > td > div ?
I would like to hide those span elements once click on the anchor tag that beneath the same tr level.
JSFiddle
$(document).ready(function() {
$(".hide").click(function(){
$('#table td div span').each(function(){
var $span = $(this);
$(this).siblings().hide();
var spanattr = $span.attr('class');
alert(spanattr);
});
});
});
HTML:
<table id="table">
<tbody>
<tr>
<td class="tdspan">
<div class="container">
<span class="spanelem">First</span>
</div>
</td>
<td class="tdspan">
<div class="container">
<span class="spanelem">Second</span>
</div>
</td>
<td class="tdspan">
<div class="container">
<span class="spanelem">3rd</span>
</div>
</td>
<td>
Hide
</td>
</tr>
</tbody>
<br>
</table>
<span id="text"></span>
I already searched for other questions and used the provided solution such as below link but I'm not able to figure it out.
jquery to traverse the div and get its span details
You don't need for loops there.
Simply .find() span with class .spanelem in a closest <tr> parent of the clicked element:
$(".hide").click(function(){
$(this).closest('tr').find('.spanelem').hide();
// Or using selector context (.find() equivalent but a bit shorter)
// $('.spanelem', $(this).closest('tr')).hide();
});
JSFiddle JSFiddle
References:
.closest()
.find()
selector context
Are you just trying to hide the spans themselves? You are hiding their siblings, and since they are the only children of their parent div, there is nothing else to hide. If you want to hide the spans themselves, then just change
$(this).siblings().hide();
to
$(this).hide();
If you have multiple rows, then you can just crawl up the tree from the .hide button that was clicked to its ancestor row, then find all the spans within that row. You may want to search on a particular class, or all spans, but I don't know for sure how you identify which elements you want to hide.
Something like
$(this).closest('tr').find('span').each(function() {
Updated JSFiddle here: https://jsfiddle.net/fk9jgrLx/4/
If your table structure is as in provided example, and if you will have multiple rows:
$(document).ready(function() {
$(".hide").click(function(){
$(this).parent().siblings().find('span').hide();
});
});
https://jsfiddle.net/L1j9psz6/1/ - remove all spans from row...

onmouseout not triggering but onmouseover is

Here is a simplified fiddle
I have a table with sub-groupings inside of it. I want these sub-groupings to be hidden until the user clicks the sub-header row, which looks like this:
<tr class="title" name="titleGroup"
onmouseover='this.innerHTML=this.innerHTML.replace("---","+++");'
onmouseout='this.innerHTML=this.innerHTML.replace("+++","---");'
onclick="$('.Group').toggle();">
<td colspan="2">--- Group ---</td>
</tr>
So, onmouseover, should change the row to look like: +++ Group +++
and onmouseout should change it back to: --- Group ---
However, only the onmouseover triggers and I cannot get the text to go back.
I initially had the mouse over/out calling a function, but that has the same result. Also note that this page is dynamically generated so the text is not always "Group".
What am I doing wrong and how can I get onmouseout to reset the text?
Maybe you wanted to use onmouseleave event? :)
The proper use of replace function in your case and onmouseleave event:
<table width="550px">
<tr class="title" name="titleGroup" >
<td
onmouseover='this.innerHTML=this.innerHTML.replace(/-{3}/g,"+");'
onmouseleave='this.innerHTML=this.innerHTML.replace(/\+{3}/g,"-");'
onclick="$('.Group').toggle();"
colspan="2">--- Group ---</td>
</tr>
<tr class="Group" style="display:none;">
<td>
<b>Group</b>
HCS:</td>
<td>
<input type="checkbox" name="did4" />
</td>
</tr>
<tr class="Group" style="display:none;">
<td>
<b>Group</b>
NCD:</td>
<td>
<input type="checkbox" checked="" name="did5" />
</td>
</tr>
</table>
ANOTHER EDIT:
Firefox doesn't support onmouseleave event on TR marks! Move those events deffinition to
<td>
Building off of adeneo's fiddle, using jQuery with mouseleave is the way to go. However, the text could include a - or + so I had to update a bit to specifically look for 3 in a row.
Here is the final jQuery:
$('.title').on('mouseenter mouseleave', function(e) {
$('td', this).text(function(_,txt) {
return txt.replace(/[+]{3}|[-]{3}/g, function(x) {
return x=='---' ? '+++' : '---';
});
});
});
http://jsfiddle.net/jQRR7/29/
Checkout http://jsfiddle.net/jQRR7/30/
This works (at least in webkit browsers, Firefox still to be done)
onmouseover='this.innerHTML=this.innerHTML.replace(/-/g,"+");'
onmouseleave='this.innerHTML=this.innerHTML.replace(/\+/g,"-");'
It contains 2 issues:
a) replace() will replace only 1x, unless you hand over a regular expression (attention: do not surround the regex by quotes!) More about replace() can be found at http://devdocs.io/javascript/global_objects/string/replace DevDocs.io JS replace()
b) mouse over seems to be called, but mouseout just 1x,so only 1 time +++ will be replaced
Can you switch to CSS3 (pseudo elements like :after are supported by all major browser version) or do you need to stick on js?
take a look at http://jsfiddle.net/jQRR7/31/
HTML
<table>
<tr class="title" name="titleGroup" style="background: #c3c3c3" onclick="$('.Group').toggle();">
<td colspan="2">Group with CSS3</td>
</tr>
</table>
CSS
.title td {
font-weight: bold;
text-align: center;
cursor: pointer;
}
td:before{
content: '+++ ';
}
td:after{
content: ' +++';
}
tr:hover td:before{
content: '--- ';
}
tr:hover td:after{
content: ' ---';
}

Jquery traversal not working with .closest(), .parent().parent() etc

I have an annoying problem whereby I can only get the top two parents of an element and it will not go beyond that. .closest() does not work either. When I look at the hierachy it should work according to the specifications outlined in the documentation.
Here is what I have:
<div id="telephonezone" class="bbox">
<table id="phones" cellspacing="0" width="100%">
<thead>
<tr><th width="70">Type</th><th>Phone number</th><th width="30"></th>
</tr></thead>
<tbody><tr style="background-color: rgb(255, 255, 255); background-position: initial initial; background-repeat: initial initial;">
<td class="primaryset">N/A</td>
<td class="primaryset">0208 989 8183</td>
<td class="primaryset">
<img data-id="0" data-dbid="1126" src="images/dandy-color/cancel.png" title="Delete."></td>
</tr>
</tbody>
</table>
</div>
My Jquery:
$('.bbox tr td img').live('click', function(){
id = $(this).attr('data-dbid') ;
cont = $(this).parent().parent().html() ;
alert(cont);
})
cont = $(this).parent().parent().html() ; gets me the contents of the < tr >, but if I try going higher than that I just get undefined. Same results with prevAll, prev, closest or any combination of them.
How do I select the ID of the div at line one when I click on that image inside the td?
html += '><img data-id="'+i+'" data-dbid="'+v[4]+'" src="images/dandy-color/cancel.png" title="Delete." /></td>' ;
Try specifying that you want the first div parent found in all ancestors.
$(this).parents("div:first").attr("id");
Probably you are trying to access deleted element parents. That's why traversal not working.
<a href="#" onclick="$(this).closest('tr').remove(); console.log('this should be null:' + $(this).closest('div'))">
In this example you can not access 'tr's parents since you have removed it from page.

jquery - How to determine if a div changes its height or any css attribute?

How can I trigger an event when a div changes its height or any css attribute?
I have a div with id = mainContent. I want jquery to automatically trigger an event when it changes its height. I did something like this:
$("#mainContent").change('height', function() {
$("#separator").css('height', $("#mainContent").height());
});
I know its wrong.
Here's my whole code (I pasted all of it because I can't get into jsfiddle for some reason I don't know):
$(document).ready(function() {
$("#separator").css('height', $("body").height());
});
$(function() {
$("#btnSample1").click(function() {
$("#mainContent").css('height', '400px');
$("#mainContent").css('width', '600px');
$("#mainContent").css('background-color', '#F0F0F0');
});
$("#btnSample2").click(function() {
$("#mainContent").css('height', '1600px');
$("#mainContent").css('width', '700px');
$("#mainContent").css('background-color', '#F0F0F0');
});
$("#mainContent").change('height', function() {
$("#separator").css('height', $("#mainContent").height());
});
});
html, body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
#separator {
border-right: 1px solid black;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table style="width: 100%;">
<tr>
<td valign="top" style="width: 19%;">
<table id="mainMenu">
<tr><td><input id="btnSample1" type="button" value="Sample 1" /></td></tr>
<tr><td><input id="btnSample2" type="button" value="Sample 2" /></td></tr>
</table>
</td>
<td valign="top" style="width: 1%;" >
<div id="separator"></div>
</td>
<td valign="top" style="width: 80%;">
<div id="mainContent"></div>
</td>
</tr>
</table>
I am trying to adjust the height of the div id=separator based on the height of mainContent whenever the height of mainContent changes.
PS: In this case I know I can use the button event to do this but I want the div to trigger the event when the height is changed.
First, There is no such css-changes event out of the box, but you can create one by your own, as onchange is for :input elements only. not for css changes.
There are two ways to track css changes.
Examine the DOM element for css changes every x time(500 milliseconds in the example).
Trigger an event when you change the element css.
Use the DOMAttrModified mutation event. But it's deprecated, so I'll skip on it.
First way:
var $element = $("#elementId");
var lastHeight = $("#elementId").css('height');
function checkForChanges()
{
if ($element.css('height') != lastHeight)
{
alert('xxx');
lastHeight = $element.css('height');
}
setTimeout(checkForChanges, 500);
}
Second way:
$('#mainContent').bind('heightChange', function(){
alert('xxx');
});
$("#btnSample1").click(function() {
$("#mainContent").css('height', '400px');
$("#mainContent").trigger('heightChange'); //<====
...
});
If you control the css changes, the second option is a lot more elegant and efficient way of doing it.
Documentations:
bind: Description: Attach a handler to an event for the elements.
trigger: Description: Execute all handlers and behaviors attached to the matched elements for the given event type.
Please don't use techniques described in other answers here. They are either not working with css3 animations size changes, floating layout changes or changes that don't come from jQuery land. You can use a resize-detector, a event-based approach, that doesn't waste your CPU time.
https://github.com/marcj/css-element-queries
It contains a ResizeSensor class you can use for that purpose.
new ResizeSensor(jQuery('#mainContent'), function(){
console.log('main content dimension changed');
});
Disclaimer: I wrote this library
For future sake I'll post this. If you do not need to support < IE11 then you should use MutationObserver.
Here is a link to the caniuse js MutationObserver
Simple usage with powerful results.
var observer = new MutationObserver(function (mutations) {
//your action here
});
//set up your configuration
//this will watch to see if you insert or remove any children
var config = { subtree: true, childList: true };
//start observing
observer.observe(elementTarget, config);
When you don't need to observe any longer just disconnect.
observer.disconnect();
Check out the MDN documentation for more information
Another simple example.
For this sample we can use 100x100 DIV-box:
<div id="box" style="width: 100px; height: 100px; border: solid 1px red;">
// Red box contents here...
</div>
And small jQuery trick:
<script type="text/javascript">
jQuery("#box").bind("resize", function() {
alert("Box was resized from 100x100 to 200x200");
});
jQuery("#box").width(200).height(200).trigger("resize");
</script>
Steps:
We created DIV block element for resizing operatios
Add simple JavaScript code with:
jQuery bind
jQuery resizer with trigger action "resize" - trigger is most important thing in my example
After resize you can check the browser alert information
That's all. ;-)
As far as regards the height or any other dimension parameter, you can use the ResizeObserver interface.
First, you get your HTML element:
const divElem = document.querySelector('#mainContent');
The element type is not restricted to DIVs, it can be anything.
Then, you create an instance of the ResizeObserver interface:
let myObserver = new ResizeObserver(entries => {
console.log("Height changed. New height: "+$("#mainContent").height());
});
Finally, you call the observe() method, which starts the specified element:
myObserver.observe(divElem);
Each time the element will be resized, the observe() method will be triggered.
Please note: the ResizeObserver interface does not work with Internet Explorer.
Other valuable answers are here:
How to detect DIV's dimension changed?

complex jquery selector : challenge

I've searched among jquery selectors for some time now, but can't find any solution to my problem.
I've got an html table filed by a foreach. On each line, several links that pop up tooltips. My problem : can't find the right selector.
<table>
<?php foreach($article) :?>
<tr>
<td>
<div class="none" style="display:none;">
<div class="tooltip_1">
"The content of my tooltip_1"
</div>
<div class="tooltip_2">
"The content of my tooltip_2"
</div>
</div>
<div class="cell">
a link
a link
</div>
</td>
<tr>
<?php endforeach; ?>
</table>
To show my tooltip, I use qTip, and it works like this :
$('a[class="link_to_tooltip_1"]').qtip({
content: $('jquery selector'),
(... other options)
});
So basicaly, I would need something like
content: $('self.parentNode.parentNode > div[class="none"] > div[class="tooltip_1"]'),
in other words :
start from link "link_to_tooltip_1"
go back to parent div "cell"
go back to parent td
then go to child div "none"
and finally select child div "tooltip_1"
Thanks a lot.
// this is "complex" version;
// assumes .cell and .none are nested inside same container, whether <td> or <li> or anything
$(".link_to_tooltip_1").each(function () {
console.log($(this).closest(".cell").siblings(".none").find(".tooltip_1"));
// $(this).qtip({ content: /* use above selector */ });
});
// this is the "not-so-complex" version;
// assumes both items are nested arbitrary level deep inside same <td>
$(".link_to_tooltip_1").each(function () {
console.log($(this).closest("td").find(".tooltip_1"));
// $(this).qtip({ content: /* use above selector */ });
});
jsFiddle Link
$('a.link_to_tooltip1').closest('tr').find('.tooltip_1');
is probably what you're seeking for ?
why not place your tooltip like this ? :
<table>
<?php foreach($article) :?>
<tr>
<td>
<div class="cell">
<span class="tooltip_1" style="display:none;" >"The content of my tooltip_1"</span>a link
<span class="tooltip_2" style="display:none;" >"The content of my tooltip_2"</span>a link
</div>
</td>
<tr>
<?php endforeach; ?>
</table>
and
$('a[class="link_to_tooltip_1"]').qtip({
content: $(this).children("span"),
(... other options)
});
Edit
I didn't know you can't use $(this). So in this context, you can do :
$('a[class="link_to_tooltip_1"]').each(function(){
var content = $(this).prev("span");
$(this).qtip({
content: content,
(... other options)
});
Here is the selector you are looking for:
"td:has(.cell .link_to_tooltip_1) .none .tooltip_1"
Explanations:
You can't go backwards (match an element, and then its parent). However you can select an element and verify that it contains elements that match an other selector:
"td:has(.cell .link_to_tooltip_1)"
This selects the parent <td> of .link_to_tooltip_1. So this does exactly the .link_to_tooltip_1.parentNode.parentNode you described.
Then you just have to select .none .tooltip_1 in the selected <td>:
"td:has(.cell .link_to_tooltip_1) .none .tooltip_1"
So your example code becomes:
$('a[class="link_to_tooltip_1"]').qtip({
content: $("td:has(.cell .link_to_tooltip_1) .none .tooltip_1"),
(... other options)
});
And as you were asking for, this is done with just a jquery selector :-)
I'd try something like this:
add a class to the elements with tooltips and rel attribute with the target class of element holding data
link with tooltip yar!
then in JS
$('a.iHaveATooltip').bind('mouseenter', function(){
$(this).addClass('showingTooltip');
}).bind('mouseleave', function(){
$(this).removeClass('showingTooltip');
}).qtip({
content: function(){ return $('.' + $('.showingTooltip').attr('rel')).html() },
(... other options)
});
it's the only idea I can come with to cheat the lack of support for generic data referencing based on DOM structure. Though can't promise it will work as I don't know the plugin and don't know if passing function as an argument won't collide with how it's implemented - you might have to change the plugin to allow it to accept function as content parameter.
good bye and good luck,
Tom

Categories

Resources