Detect click on body on empty spaces - jQuery selectable deselect - javascript

I have a jQuery selectable lislt and I want to deselect the items when clicked outside the list.
Initially I used : $('body').click(...) which worked but it detects click on all the elements inside the body. I want to detect it except for clickable elements such as tags like a, button, input, select etc.
So I modified my code as follows:
$("body").click(function (event) {
var tagname = event.target.tagName.toLowerCase();
if (tagname != "a" && tagname != "button" && tagname != "input") {
$('#selectable .ui-selected').removeClass('ui-selected');
}
});
which does not look like an elegant way to do it. And it would even miss certain elements if not defined.
Is there a better way to do this? A way to detect empty spaces in body with no text or click functions attached?

Related

How to find the top parent element of a text selection?

I have many contenteditable div.
When I select a text by hightlighting inside a contenteditable div, I want to retrieve the contenteditable div element.
For exemple :
<div contenteditable="true">
Hello World,
<i>this is <b>a dog</b> in the garden</i>
Thank you very much
</div>
So when I select the text "dog" by highlighting, I want to retrieve the contenteditable div element in order to know which contenteditable div I have used.
An idea ?
Edit :
I made this code, but it's not perfect :
var selection = window.getSelection();
var node = selection.anchorNode;
for(var i = 0; i < 50; i++)
{
node = node.parentNode;
if(node.getAttribute("contenteditable") == "true")
{
console.log("found");
break;
}
}
I think previous answers are over-complicating matters.
This is the same whether you select text or just click on an element.
You need to be able to identify the current element that you have clicked on or pressed a key on (otherwise I don't see how you can make contenteditable work sensibly).
Assuming you can do this, all you need to do is go back from CurrentElm to the parent that has the contenteditable attribute with a while loop -
while (Elm.contenteditable != true) {Elm=Elm.parent}
I confess to not providing full programming details, but I can if you need them.
The first issue is to be able to identify the CurrentElm on mouseclick or keypress.
If you can't do this, then get back to me and I'll explain - the rest then becomes easy.
You need an event to fire after the text is highlighted. Unfortunatley, there isn't a onhighlight event so you must use something like onmouseup.
Next, you need a way to add event listeners to all your contenteditable divs. One way to use this is document.querySelectorAll(). But you may find it easer to add one event listener to the "parent" of these divs and continue on with the directions below.
The event listener for mouseup will provide an event object. See https://developer.mozilla.org/en-US/docs/Web/Events/mouseup. This object has the value currentTarget which will give you the element where the mouseup event occured, which in turn is the element where the highlighting took place.
This question seems to have already been asked:
javascript to get paragraph of selected text in web page
Here is another example:
http://www.codetoad.com/javascript_get_selected_text.html

double click to change tree label

I have a javascript tree control that I have constructed with nested UL and LI's. I want to enable users to double click to change the label of an item in the tree. I put this line at the top:
<ul id="dhtmlgoodies_tree2" class="dhtmlgoodies_tree" ondblclick="change(event)">
and for the change function I have:
function change(ev) {
ev.preventDefault();
console.log(ev)
var it = prompt("Channel Name", "");
}
When I look at the value of ev, it is everything about the mouse click event (location, etc.). Is there some way I can get the handle to the tree and even better the LI on which they clicked?
ev also has a target property which is exactly the element user clicked on.
So, for example, adding ev.target.textContent = it; to your function will change the element text to user's answer.
You can easily do it with JQuery like this:
$("ul li").ondblclick(function(){
var text = $(this).text()
console.log(text)
});
Hope it helped you.

Check if a div has any children

I have the below code that checks to see if any of my divs has the class "wrong" and if so it shows the jQuery UI dialog box. However i want to extend the code so that it checks those divs and if there are any that are empty it should not show the dialog box.
I've looked around and some people are suggesting using children().length > 0 to accomplish this, but I'm not sure how to write this with my code.
js:
$("#run").click(function() {
if ($("[id^='Drop']").hasClass("wrong")) {
$("#dialog1").dialog("open");
}
});
The following selectors could be used to test if an element is empty or not:
:empty matches elements that have no children (thus, empty)+
:parent matches elements that have children+
Now, rephrasing your statement:
... so that it checks those wrong divs and if
there are any that are empty they are all full it should
not show the dialog box.
You would write:
var $allWrong = $("id[^='Drop'].wrong"),
$notEmpty = $wrong.filter(":parent");
if ($allWrong.length && $allWrong === $notEmpty) {
// show dialog
}
+ Text nodes are counted when counting children. <span> </span> contains a text node which contains a whitespace. Therefore it matches :parent and does not match :empty.
The logic consists of two parts:
Finding elements with id property starting with "Drop" and having the .wrong class.
Checking whether any of those elements are empty.
To do this, I'm saving the first step in an intermediate variable, before doing the final condition:
var $wrongFields = $('[id^="Drop"].wrong');
if ($wrongFields.length && !$wrongFields.filter(':empty').length) {
// at least one field exists with:
// - id starting with "Drop"
// - class of "wrong"
// and none of those fields are empty
$("#dialog1").dialog("open");
}
Demo
This would also work
$("#run").click(function(){
if ($("[id^='Drop']").hasClass("wrong") && $("[id^='Drop'].wrong:empty").length ) {
$( "#dialog1" ).dialog( "open" );
}
});

get all elements in a div and using tab key to navigate these elements in that div

I have a requirement of changing focus of elements in a div by using tab key. focus should not be moved away from the elements in the div. How can this be done. I am trying this approach:
1) get all the elements inside div to an array
2) bind a keypress event to each element in the array and passing the nxt element to it
3) handling keypress by a function that will shift the focus to next element.
sample code:
var elements = jQuery('xxx');
elements.each(function (index, element) {
element.bind("keypress", { nxt:elements[index+1] }, function(e) {
var keyCode = e.keyCode || e.which;
if (keyCode == 9) {
e.data.nxt[0].focus();
}
});
});
My doubt is,
1)how to get all the elements from the div that can be focused on tab key press.
2)Is there anything in jQuery that can get different type of elements in one go.(something like, to get input+select+a+textarea in one statement)
3)If this approach is not worth, please suggest one.
Check out this fiddle. It may help you
HTML code
<div id="container">
<input type="text" id="first"/>
<input type="text" id="second"/>
<input type="text" id="third"/>
</div>
JavaScript Code:
var elems = $('div#container input');
elems.each(function(index,element) {
console.log(element);
$(element).keydown(function(e) {
var code = e.keyCode || e.which;
console.log(code);
if(code === 9) {
$(this).next().focus();
e.preventDefault();
}
})
})
http://jsfiddle.net/tmFFk/1/
you don't need jquery for this. you can use tabIndex attribute to switch over. tabIndex.
<div tabIndex="1">asdasd</div>
<div tabIndex="2">asdasd 2</div>
<div tabIndex="3">asdasd 3</div>
demo : tabIndex
I had similar problem and created tiny jQueryUI plugin that limits fields that TAB affects. you use it simply:
$(".someGroup").tabGuard();
and that will make tab iterate over fields inside of .someGroup wrapper. This way you can group various forms on a page and the one in focus will keep iterating on TAB or Shift+TAB if that makes sense. Find it here:
http://tomaszegiert.seowebsolutions.com.au/tabguard/index.htm
It uses :tabbable to get all the elements that TAB can focus on and feel free to check source to see how its done. I hope you will find it useful.
If I'm reading it right, you need to switch in between DIVs with Tab press.
As per the Specification, Tabindex is not supported on Div's. It's only supported on A, AREA, BUTTON, INPUT, OBJECT, SELECT, and TEXTAREA.
As for the question, it's quite an unusual requirement but a very interesting one. I've never tried this out, but I can give my suggestions logically for each of your queries:
You can use .children() to get all child elements within that div.
You can use all selectors in one go by separating them with commas, or you can give them classes.
Let me know if it works out.

Select empty element in TinyMCE on click

I would like to have the behaviour of the img element applied to another inline element: when clicking on it, it should get selected.
Specifically, I'd like to have an empty q or span tag and when the user clicks on it he should be able to add some attributes. I've written a plugin that works similar to the link-button but it doesn't work for empty elements because they never get selected in the first place. The reason for all this is that I want to replace these elements on the server with a footnote generated from the saved attributes.
I found how it's done for the img element, from tinymce/jscripts/tiny_mce_src.js:
// Workaround for bug, http://bugs.webkit.org/show_bug.cgi?id=12250
// WebKit can't even do simple things like selecting an image
// This also fixes so it's possible to select mceItemAnchors
if (tinymce.isWebKit) {
t.onClick.add(function(ed, e) {
e = e.target;
// Needs tobe the setBaseAndExtend or it will fail to select floated images
if (e.nodeName == 'IMG' || (e.nodeName == 'A' && dom.hasClass(e, 'mceItemAnchor'))) {
t.selection.getSel().setBaseAndExtent(e, 0, e, 1);
t.nodeChanged();
}
});
}
But when I try to copy and adapt this I run into the problem taht e.target is already the surrounding paragraph element instead of the empty q element I clicked on (I've styled it with CSS's :before pseudoclass). At least on WebKit that's what happens. In Firefox it actually works, when using a double click instead of a single click.
Thanks for your help.
I finally got it working! Thank you Thariama for your help :)
Note: important is that the q element is styled with display: inline-block; Otherwise you'll never be able to select it.
//makes an empty q.citation tag selectable
ed.onClick.add(function(ed, e) {
e = e.target;
var dom = tinyMCE.activeEditor.dom;
if (e.nodeName == 'Q' && dom.hasClass(e, 'citation') ) {
ed.selection.select(e);
//add class 'selected' for styling
dom.addClass(e, 'selected');
ed.onNodeChange.add(function(ed, cm, n) {
//remove class 'selected'
dom.removeClass(e, 'selected');
});
}
});

Categories

Resources