Detecting drag drop to HTML textbox? - javascript

I have a normal search box on my webpage. It is filled with text: Search this website
This text is removed when you click into the box to type your search query:
onfocus="if(this.value=='Search this website') { this.value=''};
But how can I detect when someone drags text from the page onto the search box, as I often do myself? onfocus is not triggered and the previous text remains.

You need to use the ondrop event, which will only fire if the ondragenter and ondragover events are cancelled. Turns out it's a bit trickier than that because the behavior is different in Firefox than IE, Safari and Chrome.
(function () {
var inp = document.getElementById("test"),
chg = false;
inp.ondragover = inp.ondragenter = function () {
chg = inp.value == "Drop here";
return false;
}
inp.ondrop = function (evt) {
evt = evt || event;
if (chg) {
this.value = evt.dataTransfer.getData("text")
|| evt.dataTransfer.getData("text/plain");
return false;
}
}
})();
Example - Firefox 3+, IE5+, Chrome and Safari. Near as I can tell, Opera doesn't support the event. At least you can get it working for 95% of your visitors though.
Drag Operations - MDC

Have you tried to use the onchange event?
BTW, there is a nifty little jQuery plugin called jquery-defaultvalue which handles all the corner cases for you. If you're using jQuery anyway, it's worth a look.

See - http://www.simplecoding.org/drag-drop-s-ispolzovaniem-html5.html , but page on the russian language (Google Translate would help).

Related

Is it possible to get selectionchange-like events for an input box in Firefox?

How can I get the selected text inside an input box in Firefox?
This is apparently a fundamental difference in the way that JavaScript works between Chrome and Firefox. To reproduce:
Navigate to www.google.com
Open JS console
Type following line: document.addEventListener("selectionchange", () => console.log(document.getSelection().toString()))
Type "text" into Google search box and do not hit enter
Use the mouse to select different portions of the "text" in the search box
In Chrome, you will see the event raised for selected text within the input element. This is consistent across various web pages that use input fields. In Firefox, the event is raised for selections outside the input, but when the text in the box is selected, no event is raised.
I have not found any explicit reference to this difference in any Mozilla documentation, nor have I found mention of it on any other web page.
Related but different question
Firefox Web Extension “selectionchange” is an older question, and the dom.select_events.enabled config attribute is now defaulted to true in FF 56. There is a second config attribute, dom.select_events.textcontrols.enabled that seems like what I'm looking for, but changing that value to true doesn't seem to have any effect.
Additional info (Edit 1)
Apparently there isn't even a way to get selected text in a textbox in FF? The following code also doesn't work:
setInterval(() => console.log(document.getSelection().toString()), 1000)
In FF, this will never return the selected text in an input field. In Chrome, it will.
Is this just a feature gap in FF? Is there no other way to extract selected text from a form field?
For me, setting dom.select_events.textcontrols.enabled in firefox did not enable document.addEventListener("selectionchange"... events for within textarea changes, but what it enabled was <textarea onselectionchange="...">.
By adding your handler to both, and toggling that firefox flag, you should get something that works in Chrome, Safari, and Edge (through document selectionchange) and in Firefox (through textarea onselectionchange).
I wasn't able to detect document.onselectionchange events from inputs or textareas in Firefox (86), but I am able to detect select events from the textareas themselves (onselect).
(Thanks to this post [in Russian] for the answer)
Based on this answer I have been able to create the following:
window.addEventListener('mouseup', function () {
selection = getSelectedText();
});
function getSelectedText() {
let elem = document.activeElement;
let elemType = elem ? elem.tagName.toLowerCase() : 'none';
if (elemType === 'input' || elemType === 'textarea') {
return elem.value.substr(elem.selectionStart, elem.selectionEnd - elem.selectionStart);
}
if (window.getSelection) {
return window.getSelection().toString();
}
if (document.selection && document.selection.type !== 'Control') {
return document.selection.createRange().text;
}
return '';
}
My testing so far shows that this seems to work well for both Chrome and Firefox.

Fire event with right mouse click and Paste

I want to fire an event in a textarea immediately after paste some text inside the textarea. I can do that when Shift+Ins is used; however, I cannot do it when right mouse button and then paste (from the drop down menu) is chosen. Keyup fires after Shift+Ins. None of the rest fires when Paste is chosen after right mouse button clicking... What do I have to do?
<textarea name="message" id="message"></textarea>
$("#message").on('keyup contextmenu', function(event) {
alert("ok");
});
http://jsfiddle.net/f29vuwoL/7/
Thank you
Most browsers support the input event, which is fired when something is pasted or otherwise added, regardless of how:
$("#message").on('keyup contextmenu input', function(event) {
alert("ok");
});
Updated Fiddle
Note that using input is the most general method, firing when the control gets input regardless of how, and so if you hook multiple events (as above), you'll get multiple calls for the same input. For instance, if you hook both keyup and input, on browsers that support input, you'll get two calls. Similarly for paste and input when the user pastes, on browsers that support both.
If you need to support browsers that don't have either input or paste, I'm afraid the unfortunate answer is that you need to poll. Still, polling every (say) 250ms isn't asking the browser to do that much work, and you can feature-detect whether it's necessary:
var message = $("#message");
var events = null;
var previous;
if ('oninput' in message[0]) {
// Browser supports input event
events = "input";
} else if ('onpaste' in message[0]) {
// Browser supports paste event
events = "paste keyup contextmenu";
}
if (!events) {
// Ugh, poll and fire our own
events = "pseudoinput";
previous = message.val();
setInterval(function() {
var current = message.val();
if (current != previous) {
previous = current;
message.trigger(events);
}
}, 250);
}
console.log("Using: " + events);
message.on(events, function(e) {
console.log("Got event: " + e.type);
});
Updated Fiddle
You should use input event callback. See the demo here
You can use the dedicated paste event:
$("#message").on('paste', function(event) {
alert("ok");
});
Updated jsFiddle
However you might want to check browser support - I don't think jQuery normalizes this event.
If you need IE support, it might be a little more difficult, but it depends on your requirements - does it absolutely need to be a paste action? If not, TJ Crowder's answer is the way to go.
The on input is useful if you want to detect when the contents of a textarea, input:text, input:password or input:search element have changed, because the onchange event on these elements fires when the element loses focus, not immediately after the modification.The oninput event is supported in Internet Explorer from version 9.
$("#message").on('input propertychange', function() {
console.log($(this).val());
});
Fiddle

Disable opera map navigation

I've got a page setup where a map is displayed (ArcGIS Online) and a input box is presented.
In Opera, for some reason, you're unable to type some characters in the input box. Instead, Opera navigates through the map on that keypress. For example, when typing the letter 'a', Opera moves the map to the left corner.
The page with map is here
After a lot of searching the only thing I could came up with, is cathing the keypress event and return false, like this:
var cancelKeypress = true;
document.onkeydown = function(evt) {
evt = evt || window.event;
cancelKeypress = /^(112|113|65|97)$/.test("" + evt.keyCode);
if (cancelKeypress) {
return false;
} };
/* For Opera */ document.onkeypress = function(evt) {
if (cancelKeypress) {
return false;
} };
But for some reason, that doesn't do the trick. Secondly, I'm wondering if there isn't a nicer solution which hooks on to Opera and blocks all the map navigation at once, in stead of blocking every keypress by it's own.
I would be more then happy if someone could explain what Opera is doing different compared to other browsers, which makes the input box unusable. Hopefully that knowledge would lead to a sollution to the answer.
Thanks a million!
This might only elaborate your description of the problem. Have you tried things like:
preventDefault() / isDefaultPrevented()
stopPropagation() / isPropagationStopped()
stopImmediatePropagation() / isImmediatePropagationStopped()

focus doesn't work in IE

i have the following function
function change()
{
var input = document.getElementById('pas');
var input2 = input.cloneNode(false);
input2.type = 'password';
input.parentNode.replaceChild(input2,input);
input2.focus();
}
but focus() doesn't work in ie7, so what can i do!
i want to have the cursor inside of input!
thanks
update
great solution, thanks, but now it doesn't work in opera:(
For IE you need to use a settimeout function due to it being lazy, for example:
setTimeout(function() { document.getElementById('myInput').focus(); }, 10);
From http://www.mkyong.com/javascript/focus-is-not-working-in-ie-solution/
For opera, this may help:
how to set focus in required index on textbox for opera
UPDATE:
The following snippet of code handles the case when the element is unavailable and retries after a short period - perfect for slow loading pages and/or elements not available until some time after.
setTimeout(
function( ) {
var el = document.getElementById( "myInput" ) ;
( el != null ) ? el.focus( ) : setTimeout( arguments.callee , 10 ) ;
}
, 10 ) ;
We hit the same issue. For focusing we are using General function which is applying settimeout solution mentioned in:
http://www.mkyong.com/javascript/focus-is-not-working-in-ie-solution/
with 100 milliseconds.
Still on some screens it's not working properly. Especially when iframes are included.
There is another known and similar IE issue:
IE 9 and IE 10 cannot enter text into input text boxes from time to time ->
IE 9 and IE 10 cannot enter text into input text boxes from time to time
What I have noticed is when you have focus, without pointer, you can apply workaround by pressing TAB key (focus on next element) and than SHIFT+TAB which will return to our target element with focus and typing pointer.
In order to be sure we can type inside input we focus on random element and then on our target input.
$('body').focus();
n.focus();
So we applied the same solution in javascript/JQuery in our general focus function.
So there is an if statement
...
if($.browser.msie) {
setTimeout(function() { try {
$('body').focus(); //First focus on random element
$(n).focus(); //Now focus on target element
} catch (e) { /*just ignore */ } }, 100); //See http://www.mkyong.com/javascript/focus-is-not-working-in-ie-solution/
} else { //Standard FF, Chrome, Safari solution...
...
To be sure since there is big regression we are still keeping solution with settimeout as a backup.
Tested on IE10, IE11, Firefox 45, Chrome 49.0.2623.87
IE7 does not support the focus() method. I don't see any method.
I've had the same issue and was able to get IE to work using code behind by making a SetInitialFocus function and calling it in my PageLoad function.
Take a look at the following example and give it a shot, it worked for me.
http://www.cambiaresearch.com/c4/df9f071c-a9eb-4d82-87fc-1a66bdcc068e/Set-Initial-Focus-on-an-aspnet-Page.aspx
function change() {
var input = document.getElementById('pas');
var input2 = input.cloneNode(false);
input2.type = 'password';
input.parentNode.replaceChild(input2, input);
setTimeout(function () {
input2.focus();
}, 10);
}
In Case you are looking to set focus in 1st input element of last row in table.Name of my div where i have kept my table is tableDiv and i am setting focus to last row's 1st inputtext
setTimeout(function(){
$($('#tableDiv tr:last').find('input[type=text]')[0]).focus();
},2);
#Bojan Tadic THANK YOU!
Below Code did the trick :)
$('body').focus(); //First focus on random element
I think the issue comes up when you use input and a placeholder. Managed so solved this thanks to this answer, I was missing that $(body).focus. Made this code to run only on IE so that all my inputs can be freely accessed by 'tabbing'. Previously when I had only tabIndex on my inputs I was able to move to the next one but focus wasn't complete and couldn't write anything in it.
This is complete code.
$('input[name^="someName"]').on('keydown', function(e){
var keyCode = e.which || e.keyCode;
if(keyCode === 9){
e.preventDefault();
$('body').focus();
var nextTabIndex = parseInt($(this).attr("tabIndex"));
nextTabIndex++;
setTimeout(function(){$('input[tabIndex=' + nextTabIndex +']')[0].focus();},20);
}
});
Its is very easy using jQuery, not sure why you are doing it the hard way :)
In this example I have a class assigned to the input field I want the initial focus set called initFocus. You can use any selector you want to find your element. from your code I would use $("#pas").focus();
$(".initFocus").focus();

JS: How to prevent the default action on images in browsers?

In IE, for example, when you press the left button on an image and keeping it pressed try to move the mouse, the drag n' drop action is taking place; how could I prevent this default action so that doing that way nothing will happen. I am building an image cropper, so you should understand why I need that. I am not much interested in knowing how to do so with help of jQuery or the like. As I study JavaScript, I prefer coding in plain-vanilla JS. It is important for me to learn how to make it cross-browser if there are any differences for such a thing.
Just like August's, but plain JS:
var imgs = document.getElementById("my_container")
.getElementsByTagName("img");
for (var i = 0; i < imgs.length; i++) {
imgs[i].onmousedown = function () {
return false;
};
}
If you want to do it 'new-style', google for 'addEventListener()' (all browsers but...) and 'attachEvent()' (...IE) methods.
Here's one in jQuery:
$("#my_container img").mousedown(function () {
return false;
});
http://www.google.com/search?q=cross+browser+event+hooking will probably teach you everything you need to know about cross browser event hooking. I don't know how to hook events without a framework, because that's an edge case IMHO. In The Real World (tm), you'll always use a framework.
The core here is that you have to stop the mousedown event from running. This will make drag and drop impossible, if you hook the event on text you won't be able to select that text, and so on.
If you're building an image cropper, you're going to put some kind of overlay on the image, probably a relatively or absolutely positioned div, inside of which you will "draw" a rectangle when the user clicks, holds and drags. This will make it impossible for the user to drag the image itself, so no fix for that is needed.
Even if you do not use an overlay, you are still going to hook the mousedown event - there is no other way to implement a JS cropper as far as I know. Hooking that event will by itself be enough to prevent the browser from initiating a drag and drop action.
I'm using code similar to the following to prevent dragging, which has the advantage of targetting actual drag-related events rather than the generic mousedown (which could conceivably have side-effects). Works in all the mainstream browsers except Opera.
function cancellingEventHandler(evt) {
evt = evt || window.event;
if (evt.preventDefault) {
evt.preventDefault();
} else if (typeof evt.returnValue !== "undefined") {
evt.returnValue = false;
}
return false;
}
function disableDragging(node) {
node.ondragstart = cancellingEventHandler;
node.ondraggesture = cancellingEventHandler;
}
disableDragging( document.getElementById("anImage") );

Categories

Resources