I have a page which has a droppable element a1, as well as a specific element a2 which is sortable. Files dropped into a1 are read and deposited into a sortable list in a2. The upload and sortable scripts are not included in my code below as they are not relevant to the issue.
The problem is that if any file is dropped anywhere into other than a1, the browser will attempt to open the file for display in the browser. This is quite evident with image files..
I have tried to disable everything but a1 with the following code, but this still does not appear to have worked, I'm still getting the unwanted redirect...
I've Googled my butt off here, but it seems there's a lot about adding drag and drop, but very little with respect to preventing drag and drop...
Can someone please tell me what I am doing wrong here with the following code?
<div id="a1"></div>
<div id="a2"></div>
<script>
drop = $("not(#a1)");
drop.droppable("option",{disabled:true, tolerance:"pointer"});
drop.droppable("disable");
drop.on("drop",function(e){
e.preventDefault();
}
</script>
Many thanks in advance!
I created a simple JsFiddle to make it work. Basically you can cancel the event with a handler on the document itself, without worrying about where the file was dropped:
$("#a1").on('drop', function() {
// your logic here
alert('dropped on a1!');
});
$(document).on('drop dragover', function(e) {
e.preventDefault();
});
If you are using an older version of jQuery, you might have to replace the on function with live.
You have used wrong jQuery selector for not.
Try this
drop = $("div").not("#a1");
After enough tinkering I managed to come up with a more suitable solution...
Seeing I'm only really focusing on the prevention of files being dropped into sortable area, I decided to focus on determining the nature of the item being dropped...
drop = $(".all-slides");
drop.on('dragover', function(e){
e.preventDefault();
});
drop.on('dragenter', function(e){
e.preventDefault();
});
drop.on('drop', function(e){
e.preventDefault();
dt = e.originalEvent.dataTransfer;
if(dt.types != null && (dt.types.indexOf ? dt.types.indexOf('Files') != -1 : dt.types.contains('application/x-moz-file'))) {
alert('You cannot upload images here. \nIf you wish to upload files, \nclick on the "Upload Images" button.');
}
});
Put simply, the drop event listens for any possibility of data transfer, and if there is no data transfer possible, we know it's a DOM element... Otherwise we know it's a file, and we throw the alert...
Related
I know disabling right-click on images won't stop technical-minded people from downloading images. Using them as CSS backgrounds is not an option.
Ideally, I'd like to ONLY remove image-saving options and not the whole context menu. I have found 3 solutions. What do people recommend and why? Is there any specific part of the include file in which I should put this?
Many thanks :)
#1
$("body").on("contextmenu", "img", function(e) {
return false;
});
#2
$('img').bind('contextmenu', function(e) {
return false;
});
121 upvotes, src: Disabling right click on images using jquery
#3
$(document).ready(function() {
$("img").on("contextmenu", function() {
return false;
});
});
76 upvotes, src: How to prevent Right Click option using jquery
(2) uses a deprecated method: bind, so I won't recommend it.
(1) and (3) will do the same thing, the only difference is that in (3) the listener is added after the page is fully loaded.
There is no way to disable particular menu items from the default context menu. You may however write your own context menu for "img" elements which doesn't include save options, but I suspect for your purpose its not worth the trouble.
I have been asked to put in place disabling of the right clicks on a website, I've informed them there is so many ways that people can still download the images via Google Images, Cache, Firebug etc etc, but none the less my arguments have gone ignored and they insist this must be done.
Any, I've put in the footer some code that disables right clicking on all elements using <IMG src=""> this fails to work on NivoSlider, I did change the script to use window load on disabling the right click which works but after slide1 it stops working and I assume this is something to do with changes to the DOM.
JavaScript is by far my weakest point and I'm hoping that someone without to much trouble can either give me a full working solution or something to go on. Thanks in Advance.
They are using NivoSlider with the following trigger:
<script type="text/javascript">
(function($) {
$(window).load(function() {
$('#slider').nivoSlider();
});
})(jQuery);
</script>
And this is the code that I've placed in the footer that fails to work on slide2+
<script>
$(window).load(function() {
$('img').bind('contextmenu', function(e) {
return false;
});
});
</script>
You're absolutely right with the DOM changes. You need to delegate the event to a parent element.
Try something like this:
$('#slider').delegate('img', 'contextmenu', function(e) {
return false;
});
Or this if using jQuery > 1.7:
$('#slider').on('contextmenu', 'img', function(e) {
return false;
});
You might be able to do it by preventing the default behaviour of a right click on the image.
See this answer: How to distinguish between left and right mouse click with jQuery
Update: I still haven't figured this out, but saw Jquery - Jeditable: How Reset to non-editable without page refresh which looks similar to what I'm wanting to do. Tried to incorporate it but am not sure I'm doing it correctly since it is taking 2 clicks (or 2 ctrl-clicks) for it to behave in the way I'm expecting.
$("div.wanttoedit").click(function(e){
if (e.ctrlKey) {
$('div.wanttoedit').addClass('non_edit').removeClass('edit').unbind('click.editable');
alert('Ctrl was pressed');
} else {
alert('Ctrl was NOT pressed');
$('div.wanttoedit').addClass('edit').removeClass('non_edit');
$('.edit').editable('http://#request.host#/vp/metrics.cfc?method=updateMetrics&returnformat=plain');
}
});
<div id="#results.id#" class="wanttoedit non_edit">#val(value_disp)#</div>
Again, any help is mightily appreciated. Thanks.
I'm still very new to jquery/javascript/jeditable so please be kind and as explicit as possible. :)
I have a table with row labels = Metric Name and column labels = Months. The cells contain the corresponding metric values. I want to be able to single left-click and have the metric value be editable but also be able to ctrl-click (or right-click, shift-click or other) and be able to enter a reason why the metric was missed (if it was). These two things are updated in two different tables in my database, but both are linked back to the metric_id/name and timeframe/month they are associated to.
I have been able to get the single left-click editing of the metric value working through jeditable but I have been unsucessful so far in finding a way to make the field also allow the other-click pop-up of a dialog box to enter the miss information.
Any help would be sincerely appreciated especially if you can make it easy to understand for this rather simple girl.
I'm using Coldfusion (not sure if that is necessary knowledge, but thought I'd mention it just in case) and can provide any code snippets as necessary to allow you to help me get this fixed.
Here is a sample of my code, I'm using jquery tabs, so the editable is in a rather different place than usual (hopefully I'm including everything you need to see...if not just let me know what I might be missing)
$(document).ready(function() {
$("#cymteamtabs").tabs( {
cache: false,
load: function(event,ui) {
$(".editMetric").editable("http://#request.host#/vp/metrics.cfc?method=updateMetrics&returnformat=plain");
},
ajaxOptions: {cache: false}
}
);
<cfloop query="metrics">
<tr>
<td>#metrics.mdisplay#</td>
<cfloop query="dates">
<td id="#results.id#" class="editMetric">#val(value_disp)#</td>
</cfloop>
</tr>
</cfloop>
Oh and just to make sure I was clear on what I want it to do....if I ctrl-click on the field, the pop-up would appear allowing the entry of the miss info (the editing is disabled). Once that dialog is closed, if I left-click on the field it would enable editing of that field so, basically I don't want to ever turn off jeditable completely, I just want it to go into hibernation mode between the time that the user ctrl-clicks on the field and when the dialog box that pops-up because of that is closed.
Thanks in advance.
I'm not certain that this is the best way to do this, nor am I positive that it is doing exactly what I want it to do, but it so far appears to work.
$(document).ready(function()
{
$("#cymteamtabs").tabs(
{
cache: false,
ajaxOptions: {cache: false},
load: function(event,ui)
{
$(".editMetric").click(function(e) {
if (e.ctrlKey) {
var metric_id = $(this).attr('data-metric-id');
var date_type = $(this).attr('data-date-type');
var value_date = $(this).attr('data-value-date');
var url_tf = 'cym';
var url_view = 'edit';
scorecards.display.miss_details(metric_id,date_type,value_date,url_tf,url_view);
e.stopImmediatePropagation();
}
});
$(".editMetric").editable("http://<cfoutput>#request.host#</cfoutput>/vp/metricCFComponents.cfc?method=updateMetrics&returnformat=plain");
}
});
});
This appears to check first for the ctrl-click and if it is pressed, then the non-jeditable code runs and the e.stopImmediatePropagation(); appears to not allow the jeditable code below it to run.
The only way I can think of sorting this is a little bit of a hack.
There doesn't seem to be anyway of running a conditional on the event so what I propose is setting two event types and switching between them when ctrl is pressed
The problem is the event types - unbinding them seems a bit excessive.
The best option would be to set the editable element as the <td /> as you have but have a separate element (like a span) as the trigger.
To continue with your current html you could try this:
$('.editMetric').editable('url1', {
event: "nrmlClick"
}).editable('url2', {
event: "ctrlClick"
}).bind('toggleClick', function(e) {
if (e.ctrley) {
/* modal javascript here */
$(this).trigger('ctrlClick')
} else {
$(this).trigger('nrmlClick')
}
});
I don't have the facilities to test this properly but this should work.
I've never made up event names before so I don't know how good an idea that is (hopefully someone can enlighten us) but I can't see the harm right now.
Hope that helps!
I have a new site build on corecommerce system which does not have much access to HTML and non to PHP. Only thing I can use is JavaScript. Their system is currently not great on page load speed so I wanted at least customers to know something is happening while they wait 5-8 seconds for a page to load. So I found some pieces of code and put them together to show an overlay loading GIF while page is loading. Currently it will run if you click anywhere on the page but I want it to run only when a link (a href) on the site is clicked (any link).
I know you can do a code that will run while page loading but this isn't good enough as it will execute too late (after few seconds)
Anyway, this is my website www.cosmeticsbynature.com and this is the code I use. Any help will be great.
<div id="loading"><img src="doen'tallowmetopostanimage" border=0></div>
<script type="text/javascript">
var ld=(document.all);
var ns4=document.layers;
var ns6=document.getElementById&&!document.all;
var ie4=document.all;
if (ns4)
ld=document.loading;
else if (ns6)
ld=document.getElementById("loading").style;
else if (ie4)
ld=document.all.loading.style;
jQuery(document).click(function()
{
if(ns4){ld.visibility="show";}
else if (ns6||ie4)
var pb = document.getElementById("loading");
pb.innerHTML = '<img src="http://www.cosmeticsbynature.com/00222-1/design/image/loading.gif" border=0>';
ld.display="block";
});
</script>
Doing this will be easier if you include jQuery in your pages. Once that is done, you can do:
$('a').click(function() {
// .. your code here ..
return true; // return true so that the browser will navigate to the clicked a's href
}
//to select all links on a page in jQuery
jQuery('a')
//and then to bind an event to all links present when this code runs (`.on()` is the same as `.bind()` here)
jQuery('a').on('click', function () {
//my click code here
});
//and to bind to all links even if you add them after the DOM initially loads (`on()` is the same as `.delegate()` here; with slightly different syntax, the event and selector are switched)
jQuery(document).on('click', 'a', function () {
//my click code here
});
Note: .on() is new in jQuery 1.7.
what you are doing is binding the click handler to the document so where ever the user will click the code will be executed, change this piece of code
jQuery(document).click(function()
to
jQuery("a").click(function()
$("a").click(function(){
//show the busy image
});
How about this - I assume #loading { display:none}
<div id="loading"><img src="http://www.cosmeticsbynature.com/00222-1/design/image/loading.gif" border=0></div>
<script type="text/javascript">
document.getElementById('loading').style.display='block'; // show the loading immediately
window.onload=function()
document.getElementById('loading').style.display='none'; // hide the loading when done
}
</script>
http://jsfiddle.net/vol7ron/wp7yU/
A problem that I see in most of the answers given is that people assume click events only come from <a> (anchor) tags. In my practice, I often add click events to span and li tags. The answers given do not take those into consideration.
The solution below sniffs for elements that contain both events, which are created with jQuery.click(function(){}) or <htmlelement onclick="" />.
$(document).ready(function(){
// create jQuery event (for test)
$('#jqueryevent').click(function(){alert('jqueryevent');});
// loop through all body elements
$('body *').each(function(){
// check for HTML created onclick
if(this.onclick && this.onclick.toString() != ''){
console.log($(this).text(), this.onclick.toString());
}
// jQuery set click events
if($(this).data('events')){
for (key in($(this).data('events')))
if (key == 'click')
console.log( $(this).text()
, $(this).data('events')[key][0].handler.toString());
}
});
});
Using the above, you might want to create an array and push elements found into the array (every place you see console.log
Tried...
<div data-role="page" data-cache="30">
<div data-role="page" data-cache="never">
<div data-role="page" data-cache="false">
<div data-role="page" cache="false">
Nothing seemes to work... so at the moment I'm fixing the problem on the server-side via...
.'?x='.rand()
.'&x='.rand()
I don't want to disable the AJAX just the caching. There has to be a better way though... am I missing something?
Thanks,
Serhiy
Thank you for the answers guys, and even though they didn't quite work for me they did point me in the direction to find the code I was looking for.
This is the code that I found on this gentleman's Github Gist.
https://gist.github.com/921920
jQuery('div').live('pagehide', function(event, ui){
var page = jQuery(event.target);
if(page.attr('data-cache') == 'never'){
page.remove();
};
});
There is also a back button code in that Gist, but I don't seem to need it really as my back button seems to work just fine...
Page caching is now off by default in jQM RC1. See the extract below from the jQM website about page caching: http://jquerymobile.com/demos/1.0rc1/docs/pages/page-cache.html
If you prefer, you can tell jQuery Mobile to keep previously-visited pages in the DOM instead of removing them. This lets you cache pages so that they're available instantly if the user returns to them.
To keep all previously-visited pages in the DOM, set the domCache option on the page plugin to true, like this:
$.mobile.page.prototype.options.domCache = true;
Alternatively, to cache just a particular page, you can add the data-dom-cache="true" attribute to the page's container:
<div data-role="page" id="cacheMe" data-dom-cache="true">
You can also cache a page programmatically like this:
pageContainerElement.page({ domCache: true });
The drawback of DOM caching is that the DOM can get very large, resulting in slowdowns and memory issues on some devices. If you enable DOM caching, take care to manage the DOM yourself and test thoroughly on a range of devices.
Have you tried to overwrite the default value ?
$(document).bind("mobileinit", function(){
$.mobile.page.prototype.options.domCache = false;
});
This works for me
Method 1
This disables AJAX
Read
http://jquerymobile.com/demos/1.0a2/#docs/api/globalconfig.html
Set ajaxLinksEnabled to false and it will not load and cache those pages, just work as normal links.
Method 2
Second idea is to remove cached elements. You can bind to pagehide event and make it remove the page instead. If not present in DOM, the page will be loaded again.
It can be done with this code as a proof of concept:
$('.ui-page').live('pagehide',function(){ $(this).remove(); });
But it needs a little work. The above code breaks the history. It prooves that you will only be able to use it with pages you intend to be leaves in your sitemap tree. Therefore you have to create a special selector for them or bind it to only certain pages.
Also you can bind to a button's click or mousedown event, get its href, generate page id out of it and find the div by id to remove it before jqm tries to look for it.
I have found no advised way of disabling the cache or forcing loading.
Martin's answer should be the right one in my opinion but jQuery Mobile cache the first page no matter what. https://github.com/jquery/jquery-mobile/issues/3249
I've opted to "patch" the behaviour of $.mobile.page.prototype.options.domCache = false and data-dom-cache="true"
$(document).on('pagehide', function (e) {
var page = $(e.target);
if (!$.mobile.page.prototype.options.domCache
&& (!page.attr('data-dom-cache')
|| page.attr('data-dom-cache') == "false")
) {
page.remove();
}
});
Here's my working solution:
$('.selector').live( 'pagebeforecreate', function () {
$.mobile.urlHistory.stack = [];
$.mobile.urlstack = [];
$( '.ui-page' ).not( '.ui-page-active' ).remove();
});
I wrote an (original in German) article about that topic, maybe that helps.
Link to google translated article