I created a form with the option to either 'drag and drop', or 'click to upload' a file. When either of the 2 happens, I want it to trigger an action.
I used the onchange event to trigger an action when a value in the form changes.
$("#uploadform").on('change', function (e) {
e.preventDefault();
alert("Something Changed");
});
That only gets triggered when I 'click to upload' a file. When I 'drag 'n drop' a file, the event doesn't get triggered.
How can I trigger the same event when I 'click to upload' or 'drag 'n drop' happens?
Please post answers in JQuery.
JSFiddle
$(document).ready(function () {
"use strict";
$("#uploadform").on('change', function (e) {
e.preventDefault();
alert("Something Changed");
});
$('#browseFileDiv').click(function (e) {
$(this).find('input[type="file"]').click();
});
$('#browseFileDiv input').click(function (e) {
e.stopPropagation();
});
// Setup Drag 'n Drop
function handleFileSelect(evt) {
evt.stopPropagation();
evt.preventDefault();
}
function handleDragOver(evt) {
evt.stopPropagation();
evt.preventDefault();
evt.dataTransfer.dropEffect = 'copy';
}
var dropZone = document.getElementById('browseFileDiv');
dropZone.addEventListener('dragover', handleDragOver, false);
dropZone.addEventListener('drop', handleFileSelect, false);
});
#browseFileDiv {
height: 100px;
width: 200px;
background-color: greenyellow;
}
#browseFileDiv > input {
display:none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form action="upload.php" enctype="multipart/form-data" method="POST" id="uploadform">
<div id="browseFileDiv">
<input id="openFile" name="img" type="file" />
</div>
</form>
EDIT:
Trying to implement the change and drop listener properly.
$("#uploadform").on('change drop', function (e) {
e.preventDefault();
e.stopPropagation();
alert("Something Changed");
});
// No longer need for `drop` event listener on the `dropZone` element.
// In particular DO NOT stop propagation, otherwise the form will not receive it.
Updated demo: http://jsfiddle.net/jytL8heo/2/
A workaround would be to simply fire the "change" event manually on drop.
function handleFileSelect(evt) {
// Manually fire the change event.
$("#uploadform").trigger("change");
evt.stopPropagation();
evt.preventDefault();
}
Demo: http://jsfiddle.net/jytL8heo/1/
Related
I am trying to open the file dialog using jQuery but it's not opening inside the pop-up screen. If I am putting it outside the pop-up div it's working fine. I am providing my code below.
$(document).ready(function(){
$(document).on('click', '.brevent', function(e){
var file = $(this).parent().parent().parent().find('.file');
file.trigger('click');
e.stopImmediatePropagation();
e.preventDefault();
console.log('hello');
});
$(document).on('change', '.file', function(){
$(this).parent().find('.form-control').val($(this).val().replace(/C:\\fakepath\\/i, ''));
});
})
$(document).ready(function() {
$("#addeventdiv").on('click', function(e) {
e.stopPropagation();
});
$(".daterangepicker").on('click', function(e) {
e.stopPropagation();
});
$("#addeventclose").click(function() {
$("#addeventdiv").fadeToggle(400);
});
$("#addevent").on('click', function(e) {
$("#addeventdiv").fadeToggle(400);
e.stopPropagation();
});
$("body").on('click', function(e) {
if (e.target.className == "#addeventdiv") {
} else {
$('#addeventdiv').css("display", "none");
}
});
});
Here is my full plunkr code. I have one Add event button. When user will click on this button the form will display and there user has to click on Attachment button which is not working as per expected.
Your delegation fails. Likely because the dialog blocks the document click.
Just add this to any of the loads since the button click does not need to be delegated since it exists in the code at load time
$('.brevent').on("click", function(e){
e.preventDefault();
var file = $(this).parent().parent().parent().find('.file');
file.trigger('click');
e.stopImmediatePropagation();
console.log('hello');
});
Your handler for all clicks in #addeventdiv gets the event first and stops propagation. I think https://plnkr.co/edit/FWRAKwlUeIRarY6bZl9n?p=preview will work as you expect:
$(document).ready(function() {
$(".daterangepicker").on('click', function(e) {
e.stopPropagation();
});
$("#addeventclose").click(function() {
$("#addeventdiv").fadeToggle(400);
});
$("#addevent").on('click', function(e) {
$("#addeventdiv").fadeToggle(400);
e.stopPropagation();
});
$("#addeventclose").on('click', function(e) {
$('#addeventdiv').css("display", "none");
});
$("body").on('click', function(e) {
if (!$(e.target).parent("#addeventdiv").length) {
$('#addeventdiv').css("display", "none");
}
});
});
Just as a stylistic nitpick, you only need one document ready handler per file
I have a problem. Each time I click in Confirmation 'Cancel', the next time needs one more click to close dialog.
$('.boton-estado').unbind().click(function () {
$('#id_estado').val($(this).val());
$("#estados").submit(function (event) {
if (!confirm("¿Realizar cambio de estado?")) {
event.preventDefault();
event.stopPropagation();
}
});
$("#estados").submit();
});
Ideas?
Thx
Try this: put submit button handler outside the button handler
$(function(){
$('.boton-estado').unbind().click(function () {
$('#id_estado').val($(this).val());
$("#estados").submit();
});
$("#estados").submit(function (event) {
if (!confirm("¿Realizar cambio de estado?")) {
event.preventDefault();
event.stopPropagation();
}
});
});
I just have a problem with drop zone for my photos, dataTransfer doesn't work end return as undefault. Please help me and show where I made a mistake. Thank you.
jQuery(document).ready(function ($) {
$('#dropbox').on("dragenter dragstart dragend dragleave dragover drag drop", function (e) {
e.preventDefault();
});
$('#dropbox').on('drop', function(e){
e.preventDefault();
var files = e.dataTransfer.files;
console.log(files);
if(files.length>1) console.log("noooo!");
else
{
console.log("Drop!");
}
});
});
div {
width:600px;
height:300px;
background:#FFFCCC;
}
<html>
<body>
<div id="dropbox"></div>
</body>
</html>
Since you are using jQuery, the event you have (inside the drop) is not the original event, but a jQuery wrapper.
You can use the e.originalEvent to get the original event, and there you have the dataTransfer.files:
e.originalEvent.dataTransfer.files
Here is a working example:
jQuery(document).ready(function ($) {
$('#dropbox').on("dragenter dragstart dragend dragleave dragover drag drop", function (e) {
e.preventDefault();
});
$('#dropbox').on('drop', function(e){
e.preventDefault();
debugger;
var files = e.originalEvent.dataTransfer.files;
console.log(files);
if(files.length>1) console.log("noooo!");
else
{
console.log("Drop!");
}
});
});
div {
width:600px;
height:300px;
background:#FFFCCC;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="dropbox"></div>
I'm trying to move links (.link) from one div (.folder) to another but the drop event is not firing. I think I made all .link divs droppable areas by preventing default behaviour in dragenter and dragover events. Here's the code:
$(document).ready(function() {
//Logic for create folder button
$("#create-folder-button").click(createFolder);
// //Logic for drag and drop for the links
$(".folder").on("dragstart", function(e) {
console.log("dragstart");
});
$(".folder").on("dragenter dragover", function(e) {
e.preventDefault();
});
$(".folder").on("drop", function(e) {
e.preventDefault();
console.log("drop");
});
});
The "dragstart" prints but the "drop" doesnt.
You need to use event.stopPropagation():
$(".folder").on("drop", function(event) {
event.preventDefault();
event.stopPropagation();
alert("Dropped!");
});
How to prevent click event on anchors (redirects to href url, in demo redirecting to google) inside some wrapper when making touch and mouse drag events on this wrapper? With preventDefault and stopPropagation I can only limit bubbling up the DOM, right?
I want to disable links when dragging, and enable click while not dragging.
Here's demo with the problem.
var items = $('#items');
function start(event) {
event.preventDefault();
console.log('touchstart mousedown');
items.on('touchmove mousemove', move);
items.on('touchend mouseup', end);
return false;
}
function move(event) {
console.log('touchmove mousemove');
return false;
}
function end(event) {
console.log('touchend mouseup');
items
.off('touchmove mousemove')
.off('touchend mouseup');
return false;
}
items.on('touchstart mousedown', start);
https://jsfiddle.net/9oxr4quz/4/
I came up with two solutions:
First:
when the mousemove event is triggered, bind a click event and call preventDefault on the event object, to prevent the browser to follow the link. Turn off the jquery click handlers when the touchstart and/or mousedown are triggered.
Javascript:
var items = $('#items a'); // Notice I changed the selector here
function start(event) {
event.preventDefault();
console.log('touchstart mousedown');
items.off('click');
items.on('touchmove mousemove', move);
items.on('touchend mouseup', end);
return false;
}
...
function move(event) {
items.on('click', function(event){ event.preventDefault(); });
console.log('touchmove mousemove');
return false;
}
...
Working demo: http://codepen.io/anon/pen/WvjrPd
Second:
Handle the click events by yourself, that way you can decide when the browser should visit another site and when should do nothing. This can be achieved by replacing the href attribute by a data-link or data-href attribute.
Now, when the touchstart or mousedown events are triggered, turn on the click events; if any of those events lead to a mousemove event, turn off the click events:
HTML:
<div id="items" class="items">
<div class="item">
<a data-link="http://google.com">Anchor</a>
</div>
<div class="item">
<a data-link="http://google.com">Anchor</a>
</div>
</div>
Javascript:
var items = $('#items a'); // Notice I changed the selector here
function start(event) {
event.preventDefault();
console.log('touchstart mousedown');
items.on('click', click); // Turn on click events
items.on('touchmove mousemove', move);
items.on('touchend mouseup', end);
return false;
}
function move(event) {
items.off('click'); // Turn off click events
console.log('touchmove mousemove');
return false;
}
...
function click(event) { // Visit the corresponding link
var link = $(this).attr('data-link');
alert('Visit link: ' + link);
// window.location.href = link;
}
items.on('touchstart mousedown', start);
CSS:
.item {
background-color: gray;
}
.item + .item {
margin-top: 10px;
}
.item a {
cursor: pointer;
display: inline-block;
background-color: blue;
color: white;
padding: 9px;
width: 100%;
height: 100%;
}
Working demo: http://codepen.io/anon/pen/EjmPrJ
What about a CSS approach with JavaScript of using disabling all pointer events when touching or or move then add them back. A quick one is define CSS like this:
a.prevent-me {
pointer-events: none; /* This line */
cursor: default;
}
the using jquery add the class and remove the class like below as needed in your events.
...
$(".item a").addClass("prevent-me");
...
...
$(".item a").removeClass("prevent-me");
...
So the whole solution, I havent tested it might be
var items = $('#items');
function start(event) {
event.preventDefault();
console.log('touchstart mousedown');
$(".item a").addClass("prevent-me"); //remove all click events
items.on('touchmove mousemove', move);
items.on('touchend mouseup', end);
return false;
}
function move(event) {
console.log('touchmove mousemove');
return false;
}
function end(event) {
console.log('touchend mouseup');
items
.off('touchmove mousemove')
.off('touchend mouseup');
$(".item a").removeClass("prevent-me"); //enable back click
return false;
}
items.on('touchstart mousedown', start);