How can I make jQuery to include other Elements into hover - javascript

i have a little problem concerning hover and jQuery:
I have created a table out of a mySQL-Database. There are some specific rows, that geht the Attribute display:none in order to not show them. But if you lay down the mous on the element obove the invisible one, the invisible element should become visible (maybe, there are more than one invisible elements, than all the invisible elements up to the next visible element should became visible. If you get the mouse off these elements, the invisible ones should disappear again. I have made a function, which does exactly what I want, exept one little thing. I would like to refer the hover not only to the visible row, but also to the invisible, which means, if you get the mouse off the visible element, to the former invisible elements, they aren't supposed to disappear, but they do! I have tried to organize the tr's with spans, but it seems at HTML don't like spans in tables, unless they aren't in td's. After that I have tried to solve the problem with the tr an mouse position, and bind the mousemove to all elements. This doesn't work either (In the following example I tried at first the xy-position of the visible Element itself, if i get this work, i will expand it to the former invisible elements.
$("#NH00").hover(
function(){
$('tr[name="hiddenNH00"]').show();},
function(){
$("*").one("mousemove", function(e) {
var offset = $(this).offset();
var xlt = offset.left;
var ylt = offset.top;
var xrb = offset.left + $(this).outerWidth(false);
var yrb = offset.top + $(this).outerHeight(false);
if(e.pageX < xlt || e.pageX > xrb || e.pageY < ylt || e.pageY > yrb){
$('tr[name="hiddenNH00"]').hide();
}
})
}
);

Take a look at the jExpand plugin.
The only possible issue I see is that it seems to expect for there to be one visible row, and one hidden row rather than multiples, as you describe.
If that is a problem, maybe you can re-work your markup so that the visible row is the same as now, but the hidden ones are in a nested table in the secondary row.
Make sure you read through the comments. Apparently there was an IE8 issue that someone fixed, and I'm not sure it made it back into the actual documentation.

Why not attach the same event handler to the "invisible" rows?
$("#NH00, tr[name='hiddenNH00']").hover(
function(){
$('tr[name="hiddenNH00"]').show();
},
function(){
$('tr[name="hiddenNH00"]').hide();
}
);
DEMO

Related

Apply position absolute style using JavaScript / jQuery

I am building a site with a right aligned nav.
The last menu item drop down runs off the page as it is positioned absolute to the left of its parent.
I am trying to create a solution for my menu below.
jsfiddle -http://jsfiddle.net/ashconnolly/6gjVr/
I cannot hardcode the pos left -xx style, because the width of the last menu item will vary (due to the text inside it), hence my use of js.
I've nearly cracked it, but i just need to apply a variable as a position absolute left style only on hover.
There maybe a better css only solution, but i couldn't find one.
Any help is appreciated! :D
Edit: updated explanation.
You have already calculated the left of your last menu, why didn't you use?
$(document).ready(function () {
var menuitemwidth = document.getElementById("last-menu-item").offsetWidth;
var menuitemdropdownwidth = document.getElementById("last-menu-item-drop-down").offsetWidth;
//alert(menuitemwidth);
var leftval = menuitemdropdownwidth - menuitemwidth;
//alert(leftval);
$("#last-menu-item").mouseenter(function(){
$("#last-menu-item-drop-down").css({'position':'absolute','left':'-'+leftval+'px','display':'block'});
});
$("#last-menu-item").mouseleave(function(){
$("#last-menu-item-drop-down").css({'display':'none'});
});
});
Check Here
As you probably already know, it is bad practice to "print" javascript values using a framework. It will pretty soon become unmaintainable.
But you can separate (element) logic from (element) presentation, i.e. print/format html elements in your templates by setting a data-attribute like this in your html:
<ul id="last-menu-item-drop-down" data-pos="left" data-val="-133px">
Then change your javascript to:
// cache last element, no need to jquery search on every hover
var last_elem = $("#last-menu-item-drop-down");
// set position and alignment
last_elem.css('position','absolute').css(last_elem.data("pos"), last_elem.data("val"));
// set dropdown meny visibility to hidden (do it by css)
last_elem.hide()
// show/hide
// ...
You can also do the offset calculations in javascript and only specify position in your templates
Fiddle at: http://jsfiddle.net/cYsp6/7/
I cant Make with css
$("#last-menu-item").mouseenter(function(){
var a=-(parseInt($("#last-menu-item-drop-down").css('width'))-parseInt($("#last-menu-item").css('width')));
$("#last-menu-item-drop-down").css('position','absolute').css('left',a);
$("#last-menu-item-drop-down").show();
});
$("#last-menu-item").mouseleave(function(){
$("#last-menu-item-drop-down").hide();
});
Updated Fiddle:
Fiddle

Convert Absolute Positioning Into Relative Positioning

Sorry if this is already out there somewhere, but I've been looking for a while and haven't found anything. I'd like to know if there's any way to, given the x and y coordinates/offset for an absolutely positioned element on a page, change that element into a relatively positioned element, but have it stay in the same visual spot, changing its location in the DOM. For example, given this html
<div id="divOne"></div>
<div id="divTwo"></div>
<div id="divThree"></div>
if divOne were positioned absolutely and its position happened to visually fall between divTwo and divThree, is there a way for me to convert its x,y position so I would be able to tell jQuery to place it after divOne and before divTwo in the DOM? I'm well versed in Javascript and jQuery, I'm just looking for a method I may not know about or for an answer from someone who may have come across this before.
by removing the absolute positioning of the dragged div you must place its tag to a different place in the dom in order to get it repositioned.
For example if you drag #divOne so that it visually moves between #divTwo and #divThree what you should do is remove the absolute positioning of #divOne and move its tag between the two other divs:
<div id="divTwo"></div>
<div id="divOne"></div>
<div id="divThree"></div>
If you have a well-defined grid this will work.
If I were you what I would do is to give a standard class to any div in my grid that I want be re-arrangeable. E.g., the class "arrangeable". When the drag-end fires I would calculate where my dragged div must be placed in the dom using this formula:
The dragged div should be moved to another place on the dom. What it will happen is that the dragged div will take the place of an existing one and "push" the existing just after it. For example by dragging #divOne between #divTwo and #divThree, #divOne takes the place of #divThree and pushes it after it. Supposing that the user stops the drag and releases left click when the dragged div is over the existing div whose place is going to be taken (let's name it "pushedDiv") by the dragged one then all you have to do is to recognize the pushedDiv, remove the dragged one from the dom, place right before the recognized one and make its position relative.
In order to realize which is the pushedDiv you can use this routine:
//on drag end, where mouse has x and y coords:
var pushedDiv;
$(".arrangeable").each(function(index,value){
var theoffset = $(this).offset();
if(x >= theoffset .left && x <= theoffset .left + $(this).width() && y >= theoffset .top && y <= theoffset .top + $(this).height()){
pushedDiv = $(this);
}
});
// if pushedDiv is still null then the user didn't release the left click over a div of class "arrangeable". Else, the pushedDiv will be the one we are looking for

jQuery offset, position element under another, where the right borders touch of the aligned elements

Ok, the subject is not super specific to the overall need I am looking to address. So I have this function that is called on a given element, which is a hidden submenu next to a triggering element. The way the page renders, and to keep the styling optimized I can't just style the position in via css. So I need javascript/jquerys help.
With that I have come up with a function that I can reuse as needed, and works fine all around. However my key problem is, that I have a couple cases where the submenu will overlap the edge of the <section> element it resides in. Which that elements overflow is set to hidden, that and its also about 30 pixels from the bottom of the page anyway. All in all the submenu element gets hidden a bit by either falling completely out of the pages view half way through the element, or it gets hidden by the section tags overflow state.
With that. In a case where this happens I am wanting to instead of have the element align to the bottom of the trigger element, have it align to the top instead so that way the menu in that case is above the trigger element and not below.
Problem is Im not sure how to compensate for that.
Here is the function I came up with to do what I need, now I just need some help in a sense catching when the menu element falls off the page so to speak, so I can adjust for it when it does.
function openSubOrgMenu(triggerID, elem)
{
orgSubOpenID = triggerID;
orgSubShowing = true;
elemOffset = elem.offset(); //trigger element
elemWidth = elem.width();
elemHeight = elem.height();
elemWrap = elem.siblings('.org_group_wrapper');//menu element
elemWrapWidth = elemWrap.width();
elemWrapHeight = elemWrap.height();
moveTop = elemHeight + elemOffset.top + 4;
moveLeft = elemOffset.left - (elemWrapWidth-elemWidth-15);
elemWrap.show().offset({top:moveTop, left:moveLeft});
}
Well here is a JS Fiddle, not necessarily showing a working logic of what I want, but demonstrating the desired effect when its an element that at the bottom of the page/section:
http://jsfiddle.net/4zwEr/

How to create a div that apears below a table row

Like in this demo
http://demos.telerik.com/aspnet-ajax/grid/examples/hierarchy/nestedviewtemplate/defaultcs.aspx
Except In this demo it's being added as an additional row. (click one of the ">" things and check the page source, it added a new row to the table). If I used this strategy, It would be difficult to sort, using a standard Jquery plugin, like table sorter.
Ideas?
went away and did some thinking about my comment, about finding row height and overlaying the div.. it's so close, but I'm no jQuery whiz, so perhaps someone can help tidy this up
I have it showing/hiding the div in the right position IF the div/row is closed before the next one is opened.. but if you click button 2 while div one is opened is doesn't get the right top position (it gets the position the row was at after being expanded not the original row position), I'm sure there must be a way to get that position while the rows are not expanded and store it??
anyway have at it.. I know it's very long-winded, variable wise, because I can only apply the CSS logic - I don't know enough about js or jquery functions and storing.. also I thought if I explained how I got to my variables and which ones were needed it might help those who do know how to make this better ;)
the input/buttons have no text but they're the click trigger
position() is maybe not the right thing to use, it needs for the div to be able to find the original position of the related row (inside table-wrap div?)
?
here's the Example
You can't. A <div> is not a valid child of <table> or <tbody>. You'll need to use a <tr>.
I don't know how that plugin works, but perhaps there's support for sorting multiple <tbody> elements, which would allow you to group your sets of rows.
That div is inside a td which is hidden until you click the >
Here is a demo: http://jsfiddle.net/maniator/7RLhL/1/
I don't know if you can do that. Putting a tag like inside a table isn't valid (X)HTML, and so probably won't give you the effect you were looking for
If you look at that demo, they're using a second <tr> below the first one with a <td> that spans most of the columns.
You can embed a detail table inside a table cell under each description cell which will be not visible and make it visible on tr click:
http://jsfiddle.net/bouillard/QmK4Z/
As mentioned in other answers, we cannot add a div inside the table without it being in a TD. However, there might be something that can be done to place the div over the row. To have the effect of the div being shown as inside the row, we could increase the height of the row while the div is being shown. Here is the very basic demo. Since the div is not really inside the table, if the table happens to sort, you would probably want to hide the div or relocate it to the new TR location. It would present its own challenges but you could play with it and see if it works for you.
I have an idea. It's really ugly. The only think I could think of doing is before sorting the rows, detach the additional rows(with the div) and use JQuery to store it somehow. Then after the sorting is done reattach the rows(with the div) in the right place(s).
That could, no I should say WILL, get ugly really fast, especially with paging and filtering...
You can use getBoundingClientRect to get the element's position and then set those values to a div css position left and top. Must also take into account the window scroll as getBoundingClientRect will return it relative to the window viewport.
The following example will locate a div named #tooltip under any tr row when hovering over it. I'm using jQuery for convenience but you can translate to vanilla JS easily.
<script>
$("tr").hover(
function () {
const row = this;
const bounds = row.getBoundingClientRect();
tooltip.css({
left: bounds.left + window.scrollX,
top: bounds.bottom + window.scrollY
});
},
function () {}
);
</script>
<table> ... </table>
<div id="#tooltip"> ... </div>
Be sure to make div positioning absolute and also to skip pointer events or the div will block hover events from reaching the table elements.
<style>
#tooltip {
position: absolute;
pointer-events: none;
}
</style>
Good luck!

Creating a stack-view control with CSS/Javascript

I Want to create a stack type control where a series of stacked sub-divs can be re-ordered within a container div.
The sub-div 'views' would be the same size and absolutely positioned on top of each other.
The z-index css property seems to apply z-order at the document level, which makes no sense to me- How can an element in a given div have a higher z-order than something that is placed after that div? It just ignores the nested div heirarchy?
So the question is: Is there a way to manipulate relative z-order within a given div?
Thanks,
Yarin
How can an element in a given div have
a higher z-order than something that
is placed after that div? It just
ignores the nested div heirarchy?
Z-index only modifies the "layer" (imagine Photoshop) that the element is displayed on. Structurally, the box-model is not changed. Visually, it appears to be, but only if the positioning for the elements have been modified (through CSS) so that the z-index actually means something. Here's an example; notice how B appears above A and C event though C has the greatest z-index.
To modify the z-index of elements, relative to the container div that they are contained in, you have to make sure that the lowest z-index in the container is greater than the greatest z-index outside of the container. Then, you adjust the other z-indexes to offset them. This function (uses jQuery) gets the element with the greatest z-index, from the passed elements:
function getTopElement(elems){
// Store the greates z-index that has been seen so far
var maxZ = 0;
// Stores a reference to the element that has the greatest z-index so far
var maxElem;
elems.each(function(){
var z = parseInt($(this).css("z-index"), 10);
// Ignore z-index of auto
if (!isNaN(z)){
if (parseInt($(this).css("z-index"), 10) > maxZ) {
maxElem = $(this);
maxZ = parseInt($(this).css("z-index"), 10);
alert (maxZ);
}
}
});
return maxElem;
};
Use:
var topDiv = getTopElement($("div"));
var topZIndex = topDiv.css("z-index");
That should get you started.
Edit:
To fill in missing z-indexes, use this code:
var elements = $("div");
var newZ = parseInt(getTopElement(elements).css("z-index"), 10);
elements.each(function(){
if (isNaN(parseInt($(this).css("z-index"),10))){
$(this).css("z-index", ++newZ);
}
});
What it does is it changes elements with a z-index of auto to one-plus whatever the greatest z-index is in the collection (elements);
To see what I mean, check out this demo.
If you want only one div to be visible then change its opacity to 1 in Firefox and 100 in IE and set the others to 0. Here's a slide show example that does just that. I would imagine yours wouldn't be based on a timer so you would need some other method to switch them.

Categories

Resources