How do you make text selectable on a jQuery draggable div? - javascript

I made a div draggable using jQuery. However, there is some text in that box, and I would still like to be able to copy and paste the text, but when I make an item draggable well when I click on the box it starts to move the box?

Use the cancel option when making the element draggable.
Prevents dragging from starting on specified elements.
$('.selector').draggable({ cancel: '.text' });

It doesn't make sense to allow dragging AND selecting text on the same element. However, if you keep thinking it's necessary, two things come to my mind:
Solution 1:
You can add a "handler" that will be the only child receiving the mouse down/up events to drag the div. For instance:
<div id="draggable">
<div class="handler"></div>
<div class="text">This is a selectable text</div>
</div>
And in your JavaScript code:
var draggableDiv = $('#draggable');
draggableDiv.draggable({
handle: $('.text', draggableDiv)
});
Solution 2:
You can disable the draggable thing when a user try to select text:
<div id="draggable">
<div class="text">This is a text</div>
</div>
And in your JavaScript code:
var draggableDiv = $('#draggable').draggable();
$('.text', draggableDiv).mousedown(function(ev) {
draggableDiv.draggable('disable');
}).mouseup(function(ev) {
draggableDiv.draggable('enable');
});
When someone tries to select something in .text, the draggable process is disabled.
The first solution is the proper one.

(As talked by the other 2 answers, but if you need an practical example, here it is (if I understood correctly): )
jsfiddle: Draggable demo
The point is to:_
add an extra child <span> as an dragHandler, in the (parent) <span> that you want to drag.
<span class="commentNt" id="commentDraggable_123">~//? was it not "single bounded context" in choreography?<br/>
<span class="dragHandler">Drag</span></span>
for the parent <span>, use following code to register that child <span> for dragging
(dragging will now only be triggered in child <span>'s region).
$('#commentDraggable_123').draggable({ handle: '.dragHandler' });
now, only dragging the child <span>, the whole parent <span> will then be dragged along with.
As for:
Q: Can I do this without introducing another child <span> inside the parent <span>?
ie: Can I just drag the "blank area", then the whole parent <span> is dragged;
while I drag on the "text area", the text can be selected instead of being dragged?
A: idk, I hope there is a way.

Related

How to temporarily block selectable elements

I am working on a popup menu on my webpage. The menu contains various selectable items, and I would like to only allow selection of certain items after a top-selection has been made. Now I could hide all items lower-down, but that would make the popup look weird. I'd rather show them, but dimmed. My idea was to enclose the follow-up selections in a div, and have that div act as a blocker. Now the question is how to do it - I tried setting the z-index of the selBlocker div higher than the rest, also to give it absolute positioning, but didn't get anywhere yet. I am using a javascript library to handle the selections in general.
<div id="SelPopup" >
<div id="topSelect"></div>
<div id="selBlocker">
<div id="selectable2"></div>
<div id="selectable3"></div>
</div>
</div>
I would append a class to the items you dont want to select, and add the not() selector to your jQuery.
For example:
$("div:not('.selected').....
Instead of
$("div").....
Ofcourse you can add an opacity to the class .selected, to make it a little bit less visible.
You can try below:
Instead of using id for selection blocked element use class="selectBlocked" and for menu div use class="selectMenu"
<div id="SelPopup" >
<div id="topSelect" class="selectMenu"></div>
<div id="selBlocker1" class="selectMenu selectBlocked">
<div id="selectable2"></div>
<div id="selectable3"></div>
</div>
<div id="selBlocker4" class="selectMenu selectBlocked">
<div id="selectable5"></div>
<div id="selectable6"></div>
</div>
</div>
Now right jQuery for handling selection of menu and do nothing if selected menu is with class="selectBlocked"
$('.selectMenu').click(function(){
if($(this).hasClass("selectBlocked"))
return false;
// do your stuff if above condition fails
});
Thank you all for the suggestions, I actually found what I was looking for:
$("#selBlocker").css("pointer-events", "none");
This will nicely disable all interaction, and with
$("#selBlocker").css("pointer-events", "all");
I can restore it. Can add the change in opacity easily alongside it.

jQuery, DOM and on() method

I have a problem with jQuery, DOM and on() method. This is my div:
<div class="box">
<p class="addBox">Add Box</p>
<p class="remBox">Remove Box</p>
<textarea name="box[]"></textarea>
</div>
And a jQuery code:
$(document).on("click", ".addBox", function(event){
$(this).parent().append('<div class="box"><p class="addBox">Add Box</p><p class="remBox">Remove Box</p><textarea name="box[]"></textarea></div>').children(':last').hide().fadeIn(1000);
});
$(document).on("click", ".remBox", function(event){
$(this).parent().hide(1000).delay(1000, empty());
});
What I'm trying to achieve is a box with two buttons, one of them will make another copy of this box, and the other one will delete the chosen box. Two copies of the box are 'hardcoded' in index file, thus available in DOM from the start.
Buttons do they basic purpose, but DOM structure is getting crazy. If I press the 'add box' link on a newly created box, the new one will show up right after the one I clicked. However, sometimes it will show up at the end of the list. It's the same with 'del box' link, sometimes it deletes only one box, sometimes the one I want and two or three more. What do I do wrong? Thanks!
You probably want .after() (or .before()), but not .append(). That, and your .delay() syntax isn't correct.
$(document).on("click", ".addBox", function (event) {
$(this).parent().after('<div class="box"><p class="addBox">Add Box</p><p class="remBox">Remove Box</p><textarea name="box[]"></textarea></div>').children(':last').hide().fadeIn(1000);
});
$(document).on("click", ".remBox", function (event) {
$(this).parent().hide(1000).delay(1000).remove();
});
jsFiddle example
The reason that you're seeing all of your boxes removed sometimes is that you're appending new boxes to the parents of the .addBox item, which is the box div -- so you're getting boxes nested in boxes, rather than a bunch of .box divs in a row. If you change
$(this).parent().append( ... // removed for clarity
to
$('body').append( ... // the rest of your code
You won't get that improper nesting, and your boxes will correctly remove only themselves.

Mouseover on child element, not on parent

I'm implementing a highlight feature, which highlights the current hovered div and i have html structure something like this:
<div> <!-- this is the parent -->
<div> content ... </div><!-- a child -->
<div> content ... </div><!-- another child-->
</div>
how it should work:
- if i hover over the parent, then it should highlight the parent element.
- if i hover over a child element, the parent element's highlighting should fade and it should only highlight the child element
i'm using jquerys' mouseenter and mouseleaves events for that, the code looks like this
(actually its a bit different because im working with gwt and the native javascript interface, but it works the same way):
$(element).mouseenter(function(event)
{
showHighlightContainer();
});
$(element).mouseleave(function(event)
{
hideHighlightContainer();
});
the problem is: when i hover over the parent element, the element is beeing highlighted and everything is fine.
but when i hover over a child element, the child elemend AND the parent element are highlighted.
am i using the wrong mouse events? how could i solve that?
You need to use mouseover and mouseout
$(element).mouseover(function (event) {
event.stopPropagation();
showHighlightContainer();
}).mouseout(function (event) {
event.stopPropagation();
hideHighlightContainer();
});
Demo: Fiddle

closests jquery

<div class="panels">
<div>
<h2>
Test
</h2>
</div>
<div class="inner_panel statict">
Test2
</div>
</div>
I want so that when people click on Test, Test2 appears. If not, they don't see Test2, How can I make that happen using jquery?
I tried the following but it does not work.
$('.inner_panel').hide();
$('.panels').click(function () {
$(this).closest('div .inner_panel').toggle();
});
I have multiple divs with class panels in the file, so I don't want click on Test affecting the other "panels."
closest method looks up in the DOM tree, not down. You can check it here. http://api.jquery.com/closest/
Maybe you should use .children('div.inner_panel') to get your element. children method allows you to get elements, that are a single level down the DOM. Check http://api.jquery.com/children/ fo details.
You have an extra space -> $(this).closest('div .inner_panel').toggle();
This should be: $(this).closest('div.inner_panel').toggle();
But .closest() is not going to work for you because it travels up the DOM tree and not up and then down to siblings etc.
I would do this:
$('.inner_panel').hide();
$('.panels').click(function () {
$(this).find('div.inner_panel').toggle();
});
See jsbin demo
$('.inner_panel').hide();
// Within .panels get the div's which contain an H2
var containers = $('.panels h2').closest("div");
// make them clickable
containers.click(function () {
// For the clicked panel, get the next element div which
// has the inner_panel class
$(this).next('div.inner_panel').toggle();
});

Get value of text inside span

I am working with Flexigrid plugin with JQuery. Ok so I have a div with two span elements, they would contain the text/display text for the buttons that flexigrid provides. The problem is, there is no mechanism to add ids to those buttons, except for adding different text.
<div class="tdiv2>
<div class="fbutton">
<div>
<span class="view" style="padding-left: 20px;">Add</span>
</div>
</div>
<div class="fbutton">
<div>
<span class="view" style="padding-left: 20px;">Delete</span>
</div>
</div>
</div>
This is how the buttons are arranged. So onclick of that button, I get the text inside the span, as Add and Delete. Now I want to add a class tag to that span, to differentiate between the active button and the other one.
So I came up with the idea, that if I could get span-text that matches to the text being returned, I could add the class to that span.
But when I do
alert($('.tDiv2 span').html());
I am only getting the text of the first span and not the second one. Could somebody help me with getting the html of both spans and not just the first one.
Try this >
$('.tDiv2 span').each(function(index, el) { alert($(el).html()); });
You need each.
$('.tDiv2 span')each(function(node){ alert(node.html()); });
However, I would like to point out that this approach is likely to cause accessibility problems for screen reader users. If you absolutely must re-invent buttons for some reason, then use ARIA attributes so that your blind visitors have some hope of getting it to work right.
jQuery automatically selects the first element in a series if you try to get a property like html or text from it. to get the second (or any number) try:
alert($('.tDiv2 span').eq(1).html()); //returns 2nd element's html content
You can substitute any 0 based index in for 1.

Categories

Resources