jQueryUI draggable sets "position: relative" on my draggable divs - jquery-ui

I'm having an odd problem with jQuery draggable this morning, I wonder if anyone else has come across this.
I have many small divs inside a large div. They are absolutely positioned: "position:absolute" in CSS for their class, with the actual position itself calculated and set in JS on demand.
Now I'm adding functionality to allow these divs to be draggable.
But, as soon as I make one draggable, it is given "position:relative" directly on the element, which as you might imagine, seriously messes up the on screen position.
Does anyone know why it changes the "position" like this or how to tell it not to?
EDIT:
Just realised there is a rather obvious answer staring me in the face - !important on my position:absolute! This seems to fix it. BUT I'm still interested if anyone knows why it sets "position: relative" like this (and doesn't either make it configurable or check first if it needs position)...I'm wondering what problems I've just stored up for myself ;-)

"I came across the same problem today. The reason was I was applying draggable() on a dynamically created element. I was 'later' appending it to dom. The element should be in dom when you apply draggable() (if style is being applied by a class). In short, when it finds no position attached with the element , it adds relative." - Jashwant
Firs do: .append(jElement) Then: jElement.draggable()
For some reason Jashwant put his answer in the comment to the question. So I thought it will be convenient to other to repost it here.

It also happened to me, but only on Chrome. Reason?
It was like this:
$("#div-popup").draggable({ handle: ".top", containment: 'document'});
Then I removed the containment parameter, like this:
$("#div-popup").draggable({ handle: ".top"});
So it's about the Browser (Chrome in this case), which sets position to Relative when you specify which containment the element will be draggable.

in my case it seems to be a race condition between the stylesheets and javascript loading...
i realized i'd made the mistake of including the stylesheets AFTER the javascript in the document head. they should be included BEFORE the javascript because $(document).ready() does not account for the CSS being loaded by the browser: https://stackoverflow.com/a/1324720/3633109

Related

Custom scrollbars for <vaadin-combo-box> , impossible?

I'm using vaadin-combo-box and I have a problem. I have no clue how to customize look and feel of scrollbars for the dropdown. I read about styling parts and I know how to do it but this seems to be impossible. Cant figure out the way to select #scroller element because it has been design not to be a "part" to style. However that is the only way I can think of to apply custom style to dropdown scrollbars. How can that be accomplished?
Thanks in advance for help.
#Update
Turns out that as of today there is no way of having customized styling on scrollbars for vaadin-combo-box component. Element responsible for scrolling resides inside contents shadow DOM and is inaccessible from outside nor its going to inherit style implemented on the parent part [part="content"]
The dropdown part is called vaadin-combo-box-overlay, see: https://vaadin.com/components/vaadin-combo-box/html-api/elements/Vaadin.ComboBoxOverlayElement And it is available for styling.
This allows to style the dropdown to some extent, but there is additional shadow root, that prevents to apply e.g. ::-webkit-scrollbar styles on #scroller element.
So the last option would be to make a copy of the vaadin-combo-box html file in right place in frontend directory. It happens so that that file will be used instead of the one coming from webjar. Then you can edit that html file directly. Of course this means that if there are changes in future versions of vaadin-combo-box, you need to copy again, re-apply changes

Swapping table td on drag

I am trying to swap two TD elements in table on Drag&Drop. I found this plugin Swappable and it works in some way. But when I drag some element the cursor change position to some specific value. I do not want changing cursor position. But when I rework this plugin it stops work.
Does anyone have experience with it or know about any other plugin?
Thanks,
Zbynek
Usually I use the jQuery sortable. It does pretty much want you want. You can use it in a table too.
Then I do my stuff (including ajax updates) in a function setted in the receive event
Did you try the JQuery Sortable() option?
See http://jqueryui.com/sortable/#display-grid

jQuery UI resizable/selectable not working in Backbone View

I have a view for my model, and in the initialization I use the following code
initialize: function (){
_.bindAll(this, 'render');
this.listenTo(this.model, "change", this.render);
this.$el.draggable({
opacity: 0.5,
containment: "parent"
});
this.$el.resizable();
this.$el.selectable();
},
Although draggable works, resizable and selectable do not (I haven't tested other jQuery UI interactions to check if they work). I tried placing this.$el.resizable inside the render function, but that wouldn't work either. I'm using jQuery 1.8.3 and jQuery UI 1.9.2 (I do include the necessary jquery-ui.css in my html). When the view renders, I inspect the element in my browser and it does indeed have a class of ui.draggable, ui.resizable and ui.selectable as it is supposed to, yet it's only draggable.
Trying to work around this issue, I've used CSS3 property resize: both in the class of the element I want to resize and it works just fine, but I'd really like to utilize jQuery UI for resizing, and I'm curious why it won't work.
Any ideas what I might be doing wrong?
EDIT: Added jsfiddle example http://jsfiddle.net/IgnorantUser/u7JkX/ the problem described is in the initialization of the ButtonInCanvas backbone view
ok so, apparently using this.$el.html(this.template(this.model.toJSON())); in my render function on the ButtonInCanvas view was causing the problems. The aforementioned gets the "caption" attribute of the model, and passes it into the view as html content.
There solution is to put this.$el.html(this.template(this.model.toJSON())); in the init function.
In case it's needed to be done in the render function, there should be another div, within the one we want to resize, that will get the caption property from the model. In the following JSBIN you can see a solution using a div inside the button. (thanks to user shoky, from the #jquery freenode irc channel for the implementation and his heads up)
http://jsbin.com/uxequq/1/edit
I don't really understand why the problem was occurring though (maybe this.template(this.model.toJSON()) in my render function, was causing a re-rendering of the view?) so feel free to point me out why, and help me understand further!
Cheers!

jQuery UI Collision - detect divs that are NOT collided

I'm very new to JavaScript so forgive me if this question is naive/obvious. I'm using jQuery UI drag and drop (and the jQuery Collision Detection library from this site: http://eruciform.com/static//jquerycollision/jquery-collision-drag-collision-example.html). Although I have no problems detecting which divs are colliding with each other (and doing things to said divs with ($(this).collisions(".collisionclass")).each(function() ...)), I haven't been able to find this list of divs that have NOT collided with each other or the target collider, at least not an elegant solution (and the reason is I wanted to do other actions on those remaining, uncollided divs).
Does anyone know of an elegant way to find which divs have not collided without resorting to brute force (e.g., add all such divs to a collection and every time there is a collision event check which ones from original collection are not in the resulting collision collection)? The example source code via the link above seems to simply add and remove dynamic div overlays on portions of original divs that are collided, but that doesn't tell me how to detect not-collided divs...
You can use the jquery not method.
var not_collided = $(".item").not(".collisionclass")
Technically this will check all the items if they have the "collisionclass" class, however it is still efficient until you get to huge numbers of items.

jQuery UI Autocomplete with scrollbar z-index help

I have a textbox that I am attaching jQuery UI's Autocomplete functionality to and I am using CSS to give it a max height via the example here. My problem is that doing this causes the z-index problem that bgiframe solves to come back again, but in a different way. The initial autocomplete menu is above all the controls underneath it, but when I begin to scroll the autocomplete menu falls behind them.
Any suggestions?
EDIT:
This is purely an IE6 bug.
As you can see, after scrolling down the autocomplete falls behind the other controls.
I could solve the problem by replacing offsetHeight by scrollHeight in the following line (from jquery.bgiframe.js) :
height:'+(s.height=='auto'?'expression(this.parentNode.offsetHeight+\'px\')':prop(s.height))+';'+
This change solved the bug for the autocomplete fields with vertical scrollbars. I could not spot any regression in other kinds of dialogs (but I did not run extensive tests).
You need to reverse the z-index order of the form elements (or their containers) using javascript. I.e., "Social Worker" has the lowest, "DX Code" the highest z-index.
You could change the offsetHeight to scrollHeight, like Siggen says, but I have encountered problems when there is only 1 result returned from the autocomplete. The 1 result is squished into a window that only like 2 pxs high.
I found a fix though.
When you have a data.length<2, you should use the offsetHeight, rather than the scrollHeight.
You have to modify autocomplete.js.
Locate this code:
if($.fn.bgiframe)list.bgiframe();
And make it this:
if($.fn.bgiframe){
if(data.length<2)
list.bgiframe({height:'expression(this.parentNode.offsetHeight+\'px\')'});
else
list.bgiframe();
}
Remember, this code should be used in combination with Siggen's fix.
I have used a combination of both parameter for the height like this:
'height:'+(s.height=='auto'?'expression(Math.max(this.parentNode.offsetHeight,this.parentNode.scrollHeight)+\'px\')':prop(s.height))+';'
Look at the max function. Now it is good with no scroll bar (shorter list and longer list as well)
and now the autocomplete component looks perfect in IE6.

Resources