I have a little problem with the containment, I want it to have a relative size to the current element. There is no fix amount of elemtens in the container and they can be scaled and rotated. The elements should be allowed to be placed partially outside the container, at least 10% of the element should be inside.
I tried to work with $(this) to get the diemensions of the selected element, but it seems that this relates to the window. For the right and left side, this should always work, but the left and the top side would only work, if all elements had the same dimension.
containment: [//"#container",
$("#container").offset().left*0.7,
$("#container").offset().top*0.2,
$("#container").width() + $("#container").offset().left*0.95,
$("#container").height() + $("#container").offset().top*0.9
],
Here is a little plunk:
example
I use $.each to individually set the containment field. I would imagine that you can recursively call on itself on draggable stop function.
http://plnkr.co/edit/McjFd5CQISlWpBA93BJC?p=preview
$('.ui-draggable').each(function(){
$elem = $(this);
var contain = [
$elem.offset().left,
$elem.offset().top,
$elem.width() + $elem.offset().left,
$elem.height() + $elem.offset().top
];
$elem.draggable({
containment:contain,
scroll:false
})
})
Related
http://dev.clickymedia.co.uk/rdicoursefinder/course-finder/
If you view the link, you will see that there are a number of filters acting at the same time. The overall height of the box is adjusted dependant on the amount of items showing by the filter plugin.
We then have a popup box when you click on each item. This also has a varying height, and pushes the next items down. We need the height of the container to adjust, taking into account the original height of the container before the item is clicked, and the popup box's height.
I have written some jQuery to do this, however, as you will see, each time it is adding the height of the blue popup box to the overall height again and again when you click the item to show the box, instead of once one is showing, adjusting the height of the container accordingly.
The jQuery I have used for the height is below:
var originalHeight = $('#filter-results').height();
var thisHeight = 70 + $('.resultsShowing').height();
var overallHeight = originalHeight + thisHeight;
$('#filter-results').height(overallHeight);
Any help would be much appreciated!
This line
var originalHeight = $('#filter-results').height();
will need to be outside your click() event, and should be done only once on $(document).ready()
This is because you're using the new height every time you're generating more height.
You need to move the originalHeight to one specific point, the first time you need it, and leave it alone there. Then, only thisHeight needs to get updated, and the result height should bet the former (static) + the latter (dynamic).
Remove this first of all
window.setInterval(function(){
///etc
}), 1);
It's killing my machine in Chrome.
if you want to know the blue element height before you display it, you should create it in memory:
var blueBox = $('<div />').html( ... );
var height = blueBox.height();
now you can add this height to the overall container and display blue element:
blueBox.appendTo('.overall');
ps. sorry about pseudo code
I am trying to create an 'application' contained in a div on a web page. This can't be any larger than certain dimensions (lets say: 550px by 280px). I have a menu with at least 1-3 sub menus for each item. The problem is, while I know the submenu is no larger than 280px high, the submenus often extend beyond the parent div's bounds (except for the last one which always grows upward not down).
Is there any way to make the menus grow up or down depending on whether it will extend beyond the div's bounds?
Here is a JSFiddle: http://jsfiddle.net/3FqcG/
Notice how the "Salzburg" submenu grows down beyond the bounds of the black DIV? I want that to grow up if it is too long and down if there is enough room.
Currently, I am just using the basic initialization: $( "#menu" ).menu();
Thanks!
I don't believe you can do this in CSS.
This leaves us with javascript. The basic idea is to:
calculate the baseline of the menu
if this lies outside the boundary
move the menu upwards to correct the position
live almost happily ever after
But, we have one major issue:
Though we capture the focus of an element, we don't know when its submenu is displayed & positioned. So although your problem is technically solved, it is by far not a desirable solution.
UPDATE
The best workaround I could come up with was to:
Turn off the animation (to avoid ugly glitches)
Add a watcher that would constantly monitor the element that is about to be opened
If opened, apply the position correction
Anyway, if you consider coming this far, you might as well override the default positioning of the jquery ui component, with the note that you will not be able to easily update the library. Update: or try Rudy Garcia's version if it works
Demo
Code of the demo:
var BASE_OFFSET = $('#menuContainer').offset().top;
var MAX_OFFSET = $('#menuContainer').height(); // get the offset of the container
var whenVisible = function($el, callback){ //executes callback when $el is visible
if($el.is(':visible')){ // if visible
callback(); // execute callback
}else{ // otherwise
setTimeout(function(){whenVisible($el, callback);},10); // do the same check in 10 ms
}
};
var fixPosition = function($menu){ // correct the position of the menu in respect to #menuContainer
var h = $menu.outerHeight(true); // take the height of the menu
var menuBottom = $menu.offset().top + h - BASE_OFFSET; // the baseline of the menu (taking into consideration the BASE_OFFSET)
if(menuBottom > MAX_OFFSET){ // if this is outside the MAX height
var diff = MAX_OFFSET - menuBottom; // calculate the difference
var newTop = $menu.position().top + diff; // modify current positioning with the calculated diff value
$menu.css('top', newTop + 'px'); // apply it to top (which is also used by jquery to position submenus
}
$.fx.off = false; // switch animations back on
};
$( "#menu" ).menu().on('menufocus', function(ev, ui){ // on the event menufocus
var $ui = $(ui.item); //take the focused element
var $menu = $ui.children('ul'); // take its related submenu
if($menu.length === 0){ // if there is none
return; // just terminate
}
$.fx.off = true; // switch off jQuery effects (otherwise you'll have glitches)
whenVisible($menu, function(){fixPosition($menu);}); // execute fixPosition when $menu is visible
});
You could also look at the API for this widget:
http://api.jqueryui.com/menu/
You can use the position option to position the elements how you want.
This will change the position so that they are within the box, however you will want to dynamically access the last to give it the position you want as the code below will change all menu items to move up 50.
$( "#menu" ).menu({ position: { my: "left top", at: "right+5 top-50" } });
A complete list of positioning options are also found here: http://api.jqueryui.com/position/
Apparently jquery UI has accounted for this and has given the option "within" to make sure your element stays within another element of your choice.
Therefore Your solution should be this:
$( "#menu" ).menu({ position: {within: '#menuContainer' } });
I have two horizontal divisions and i want to insert a slider in between then so that the height can be dynamically adjusted. The code am using is
<script type="text/javascript">
$(function() {
var stopFromTop = 58;
var stopToTop = 158;
var i = 0;
$("#handle").draggable({ axis: 'y',
start: function(event, ui) {
TopStart = $('#top').height();
BottomStart = $('#bottom').height();
},
drag: function(event, ui) {
$('#top').height( TopStart + (ui.position.top-ui.originalPosition.top) );
$('#bottom').height( BottomStart - (ui.position.top-ui.originalPosition.top) );
//$("#handle").css({"top":108 + "px" }).show();
//alert(ui.position.top);
},
containment: [0,stopFromTop ,0,stopToTop ]
});
});
</script>
But this is not working the way it should. The slider is not following the mouse when it is dragged. There must be something which I am doing wrong. Unable to get it!! :(
Here is the link to the page.
You could use jQuery UI's draggable element. Then simply calculate it offset from the top and set that as the top div's height. Then do some math to find the bottom div's height.
Edit
You have the slider's position set to relative, so basically it will appear right below the top div. Additionally you change its top value (which also moves it. So basically it is moving TWICE as much as it needs to). Either:
Set the sliders position to absolute (and play with top to position it right); <-- ALOT OF WORK, DO NOT ATTEMPT
Simply stop changing slider's top value
Seems to be a css problem with jquery. Changing the css property of separater to position:absolute fixed the problem.
This is a followup question for this:
Scrollpane on the bottom, css is hacky, javascript is hard
I ended up doing the scrolling in the same way explained in the accepted answer.
Now there is a request that one item is selected somehow (eg. as an url parameter or by some javascript calls) I should scroll the pane to the item with the corresponding ID in the scrollpane. Like a link to an anchor () would work!
I want to make a javascript call like this
function scrollTo(id) {
$('#middle').magicallyScrollThatItemWouldBeVisible(itemid);
}
But this is not in jQuery (or at least I don't know of it). So is there a way to make it?
I'll post a simple jsFiddle here:
http://jsfiddle.net/ruisoftware/U6QdQ/4/
Help me write that scrollTo function!
A .animate would be fine too.
UPDATE: If it was not clear I would like it to only align to the left or right side of the panel, it it was overflowed on that side (so the minimum possible amount of scrolling happens)
It's not jQuery, just JavaScript, and I've actually never used it all, so I'm not sure how you would have to mess with it to get it to work in this situation, but there is a scrollIntoView function:
yourElement.scrollIntoView();
Since the elements have a fixed width, you can count the number of elements by using .index() + 1, and animate to this value (after subtracting the container's width).
If you want the element to be centered, use - Math.round(middle.width()/100)*50.
Fiddle: http://jsfiddle.net/U6QdQ/17/
//This code should be run on load / DOMReady
(function($){ //Run on load / DOMReady
$.fn.magicScrollTo = function(){
var middle = $("#middle");
var currentScrollLeft = middle.scrollLeft();
var width = middle.width();
var newScrollLeft = this.offset().left + currentScrollLeft - middle.offset().left;
if(newScrollLeft >= currentScrollLeft && newScrollLeft <= currentScrollLeft + width - this.outerWidth()) return;
if(newScrollLeft > currentScrollLeft){ //If the element is at the right side
newScrollLeft = newScrollLeft - width + this.outerWidth();
}
middle.animate({
scrollLeft: newScrollLeft,
}, 'fast')
}
})(jQuery);
Usage:
//Select the 4rd element, and scroll to it (eq is zero-based):
$('.item').eq(3).magicScrollTo();
Something along these lines would be a good start:
http://jsfiddle.net/vHjJ4/
This will bring the target into the centre of the carousel. I think you will have to add in some extra checks to make sure that it didn't scroll to far, for example if you targeted the first or last element...unless this is built into the scroll function (it might be).
I'm not sure I understand your question exactly, but it sounds like you're asking how to scroll horizontally to the selected item in the bottom pane. If so, try something like this:
//get the position of the element relative to the parent ("middle")
var pos = $("#itemid").position();
if (pos){
$("#middle").scrollLeft(pos.left);
}
From here, you can use the width of middle to center the item if needed.
Is it possible to change DIV position from absolute to relative (and from relative to absolute)?
DIV should remain on same place.
Because formatting in comments is not work I will publish solution here
$(object).css({position: 'absolute',top: dy, left:dx});
// dy, dx - some coordinates
$(object).css({position: 'relative'});
Does not work: element position after changing to relative is different.
But when I stored offset and set it again after changing to relative, position is the same:
$(object).css({position: 'absolute',top: dy, left:dx});
var x = $(object).offset().left;
var y = $(object).offset().top;
$(object).css({position: 'relative'});
$(object).offset({ top: y, left: x });
you can change that attribute with
$(object).css({position: 'absolute'});
For instance:
You could use jQuery's methods .position() or .offset() to set "top" and "left"
css attribute aswell, that way your object should stay at it's position changing
from relative -> absolute.
I don't think that works vice versa.
demo code: http://jsbin.com/uvoka
If you really want to get the total top offset of an element that is a child of elements with absolute and relative positions you could use this function
function calcTotalOffsetTop(elm)
{
var totalOffsetTop = 0,
curr = elm;
while( curr.parent().is(':not(body)') )
{
curr = curr.parent();
totalOffsetTop += curr[0].offsetTop;
}
return totalOffsetTop;
}
this is the basically the code for the solution given by plodder above.
You can quite easily change it from relative to absolute by using it's offsetLeft and offsetTop values as left and top styles.
The other way around is harder. You would basically have to change it to relative and see where it ended up, then calculate new offset values from the current offset and the desired location.
Note that when the positioning is relative, the element is part of the page flow and may affect other elements. When the position is absolute, the element is outside the page flow and doesn't affect other elements. So, if you change between absolute and relative positioning, you may need to do changes to other elements also if you don't want them to move.
prototype.js has element.absolutize() and element.relativize which work very well.
The problem with going from relative to absolute is that
element.offsetTop and offsetLeft
only give the offset of your element to its parent.
You need to measure the cumualtive offset (i.e.
the offset of your element to its parent +
the offset of the parent to its parent +
the offset of its parent to its parent +
etc.)