Javascript Intercepted "Ctrl+O" Does Not Open My File Dialog - javascript

I have an <input type="file" id="browse-button"/> file-browser input in my HTML.
I have another button with ID choose-file-button that, when clicked, calls document.getElementById("browse-button").click();. When this button is clicked, it correctly clicks #browse-button and the file dialog opens.
Now, I took code from this answer to intercept a Ctrl+O keypress and open my file dialog, so I have this:
$(window).bind('keydown', function(e)
{
if (e.ctrlKey || e.metaKey)
{
switch (String.fromCharCode(e.which).toLowerCase())
{
case 's':
e.preventDefault();
// doesn't matter for this question
return false;
case 'o':
e.preventDefault();
document.getElementById("choose-file-button").click();
return false;
}
}
return true;
});
As you can see, when I intercept Ctrl+O I click on my #choose-file-button button, which calls document.getElementById("browse-button"); in its onclick handler. I have put a breakpoint in this click handler, and when I press Ctrl+O it does arrive at this breakpoint. However, the file dialog never shows up.
Through debugging, I found out that if I put an alert(...); after the #choose-file-button click() line, then the alert shows up and the normal page "Open File" dialog shows up (not my file dialog). If I do not have this alert, however, nothing shows up at all.
Is this a bug? How can I fix it and make my file dialog show up via the intercepted Ctrl+O?
Edit: I just tested in Chrome, and it works perfectly. However, it still does not work in Firefox.

There's some browser security magic going on here. When using timeouts or intervals or any other methods I try, the code carries on as normal but the browser simply refuses to open a file upload dialog. This is probably deliberate, to stop malicious JS from trying to grab users' files without consent. However, if you bind to a click event on a link, it works perfectly using jQuery or regular JS.
Edit: As suspected, most browsers keep track of whether an event is trusted or not based on the type of event and whether it was created by the user or generated programmatically. Se this answer for the full details. As you can see, since keyboard events aren't in the list, they can never be trusted.
Test JSFiddle
<form action="#" method="post">
<div>
<input type="file" id="myfile" name="myfile" /> Click me
</div>
</form>
$("#mylink").click(function () {
$("#myfile").click();
});
$(window).bind('keydown', function (e) {
if (e.ctrlKey || e.metaKey) {
switch (String.fromCharCode(e.which).toLowerCase()) {
case 'o':
e.preventDefault();
console.log("1a");
$("#myfile").click();
//alert("hello");
console.log("1b");
return false;
}
}
return true;
});
I think there are only two options here, and they're both workarounds, not solutions.
One is to use a link to trigger the file upload dialog, and ask people to use ALT+SHIFT+O instead of CTRL+O (because I added an accesskey attribute to the link in the example).
The other alternative is to use one of the new HTML5 JavaScript APIs for drag-drop file uploading.
Addendum: I also tried using pure JavaScript in Firefox to grab a click event and check to see if it's trusted using the isTrusted property. For the clicks on the link, it returned true. However, attempting to store and re-use the event elsewhere doesn't work, because it's already been dispatched by the time you get a reference to it. Also, unsurprisingly, creating a new event and attempting to set isTrusted = true doesn't work either since it's read-only.

Browser map many Ctrl+ shortcuts to own commands, for instance CTRL+O to open a file (in firefox).
On the same time browser behave different when you try to override such shortcuts in javascript. Some browsers allow you to do so, some don't, and sometimes the default browser action may pop up together with the action of your javascript.
Here is another thread discussing this topic.
Probably the best you can do is to choose a different shortcut.

You can try with Mousetrap library. It overrides the most problems that key capturing makes.
Official website and complete refference:
https://craig.is/killing/mice
Good luck

You cannot do that in all browsers, as far as I am concern only IE allow it. I guess this is due to security issues, so that programmer are disabled to set the file name on the HTML File element automatically(without permission of client).
have a look on this link for more details:
In JavaScript can I make a "click" event fire programmatically for a file input element?
Show input file dialog on load?

Related

Enable copy and paste for a site that doesn't allow it

First off, I want to say that I very little knowledge of coding so please bear with me. I'm trying to paste in a site that doesn't allow it. This is the link to the javascript that they used to block it, https://mychatdashboard.com/js/messages.js?v=1.3
A friend of mine is helping me with it and he suggested that I put this in the javascript console in the DevTools of Google Chrome,
handler = function(e){ e.stopImmediatePropagation(); return true; }
document.querySelector('#conversation-content .conversation-message-text').addEventListener('keyup', handler, true)
document.querySelector('#conversation-content .conversation-message-text').addEventListener('input', handler, true)
This does solve the problem but it creates another issue. It seems that it interferes with this section of the javascript that I have linked to,
* Function to update the messagebox. (Enable/disable send button,
* change the color class, update the counter)
* #return void
So what would happen is that when a message is typed in the textbook, there's a character counter at the top which shows how many characters are written. When 80 characters(I think it's 80) are typed, the send button will be enabled so that I can send the message. However, with the javascript code that my friend suggested that I used, it stops the counter from working altogether so the send button never gets highlighted.
Is there any way around this? Please let me know if further clarifications are needed since it's the first time I'm asking a question of this nature.
The JavaScript you're entering into the DevTools console is defining a function named handler and then adding it as an event handler for keyup and input events for a field on the page you're viewing (presumable the chat window textbox).
The way that the handler is defined and attached prevents other events from firing (such as those that enable the send button when you've typed enough characters).
For this sites (and I haven't been able to test it) instead of the code you've used you could try running this in the DevTools console (once the page is loaded):
restrictCopyPasteByKeyboard = function () { return true; };
This should redefine the function that's preventing you from using paste (I can't test it out because I can't access that site).
There are numerous way through one can copy contents from Right Click protected sites
By disabling browser JavaScript in browser
Using Proxy Sites
By Using the source code of the site
Disabling JavaScript in Browsers [Google Chrome]
In Chrome browser, you can quickly disable JavaScript by going to settings. See the screenshot for better explanation:
screenshot
Through Viewing Source Code
f you have to copy the specific text content and you can take care of HTML tags, you can use browser view source options. All the major browser give an option to source of the page, which you can access directly using the format below or by right click. Since, right click is out of question here, we will simply open chrome browser and type: view-source: before the post URl Like
view-source:Enable copy and paste for a site that doesn't allow it
Press ctrl+u
And find the paragraph or text you want to copy and then paste it into any text editor.
I'm sure there are many ways of restricting user's ability to copy/paste. In my experience, it's always been a JS function that you can overwrite.
Slight variations of the below have always worked for me:
document.getElementById("#ElementWithDisabledPaste").onpaste = null

Select tag value doesn't restore to previous value after hit go back in browser [duplicate]

I need a way to clear all the fields within a form when a user uses the browser back button. Right now, the browser remembers all the last values and displays them when you go back.
More clarification on why I need this
I've a disabled input field whose value is auto-generated using an algorithm to make it unique within a certain group of data. Once I've submitted the form and data is entered into the database, user should not be able to use the same value again to submit the same form. Hence I've disabled the input field in the first place. But if the user uses the browser back button, the browser remembers the last value and the same value is retained in the input field. Hence the user can submit the form with the same value again.
What I don't understand is what exactly happens when you press the browser back button. It seem like the entire page is retrieved from cache without ever contacting the server if the page size is within the browser cache limit. How do I ensure that the page is loaded from the server regardless of browser setting when you press the browser back button?
Another way without JavaScript is to use <form autocomplete="off"> to prevent the browser from re-filling the form with the last values.
See also this question
Tested this only with a single <input type="text"> inside the form, but works fine in current Chrome and Firefox, unfortunately not in IE10.
Modern browsers implement something known as back-forward cache (BFCache). When you hit back/forward button the actual page is not reloaded (and the scripts are never re-run).
If you have to do something in case of user hitting back/forward keys - listen for BFCache pageshow and pagehide events:
window.addEventListener("pageshow", () => {
// update hidden input field
});
See more details for Gecko and WebKit implementations.
I came across this post while searching for a way to clear the entire form related to the BFCache (back/forward button cache) in Chrome.
In addition to what Sim supplied, my use case required that the details needed to be combined with Clear Form on Back Button?.
I found that the best way to do this is in allow the form to behave as it expects, and to trigger an event:
$(window).bind("pageshow", function() {
var form = $('form');
// let the browser natively reset defaults
form[0].reset();
});
If you are not handling the input events to generate an object in JavaScript, or something else for that matter, then you are done. However, if you are listening to the events, then at least in Chrome you need to trigger a change event yourself (or whatever event you care to handle, including a custom one):
form.find(':input').not(':button,:submit,:reset,:hidden').trigger('change');
That must be added after the reset to do any good.
If you need to compatible with older browsers as well "pageshow" option might not work. Following code worked for me.
$(window).load(function() {
$('form').get(0).reset(); //clear form data on page load
});
This is what worked for me.
$(window).bind("pageshow", function() {
$("#id").val('');
$("#another_id").val('');
});
I initially had this in the $(document).ready section of my jquery, which also worked. However, I heard that not all browsers fire $(document).ready on hitting back button, so I took it out. I don't know the pros and cons of this approach, but I have tested on multiple browsers and on multiple devices, and no issues with this solution were found.
Because I have some complicated forms with some fields that are pre-fill by JS, clearing all fields is not suitable for me. So I found this solution, it detects the page was accessed by hitting the back/forward button and then does a page reload to get everything back to its original state. I think it will be useful to someone:
window.onpageshow = function(event) {
if (event.persisted || performance.getEntriesByType("navigation")[0].type === 'back_forward') {
location.reload();
}
};
As indicated in other answers setting autocomplete to "off" does the trick, but in php, what worked for me looks like this...
$form['select_state'] = array(
'#type' => 'select',
'#attributes' => array('autocomplete' =>'off'),
'#options' => $options_state,
'#default_value' => 'none');

How to obtain image from clipboard in a button click?

I'm trying to retrieve an image stored in the clipboard using jQuery. So far, I've managed to find a solution which works perfectly using the onpaste event. But, as per the requirements I want the same functionality in a "button click" instead of a "paste" event. I've tried to put the same code in a button click event, but with no luck. What am I missing here?
Here's my jsfiddle
If possible please tell me how I can do the same in IE(10 & above) & Mozilla Firefox.
Exapmle : Demo Applet
As mozdev states, this feature should be available in FF since version 22.
https://developer.mozilla.org/en-US/docs/Web/Events/paste
"Caniuse" states that too btw: http://caniuse.com/#feat=clipboard
Maybe you have to use a browser prefix or the event attributes have different names. Is your event not fired in other browser than chrome or is it fired but you don't receive data?
EDIT:
Additionally 'paste' is an event, you can't trigger it manually by a button. (Well you can but it doesn't make any difference.) This wouldn't make sense because you can't directly access the clipboard for security reasons and therefore you don't have the data available. in browser. With a button you have to use the file-select and upload method, which i think needs a webserver in the back to handle the request, so no pure js solution.

Is it possible to acquire the users response from IE "NATIVE" dialog boxes triggered by onbeforeunload event handler

I have a scenario where I need to capture the response received from a dialog box INVOKED by IE from an onbeforeunload event handler. The dialog box is a familiar one,
"Are you sure you want to navigate away from this page? You will lose any unsaved modifications to this document. Press OK to continue or Cancel to stay on the current page."
I will emphasize for the sake of anyone misinterpreting this question, that the dialog box I am interested in capturing is THE BROWSER's dialog window, NOT a dialog window that one might create using a third party library such as JavaScript, Telerik or etc. as the source.
I am really not that concerned with capturing a click of the OK button (although it would be a plus) but more concerned with the clicking of the Cancel button because it requires more than simply retaining the user on the current page and our company would like to implement some additional logic on click of the Cancel button.
I believe I have diligently searched all resources available inclusive of Stack Overflow but I cannot find any specific answer or information regarding how to acquire the handle on the dialog and determine which button the user clicked.
Since our companies primary browser for this application is IE, the question is only with respect to IE. Can this be done and if so, where might I find the appropriate documentation or acquire a lead? Seeing as I haven't found any definitive answer to date, I am presuming it is not possible but would like others responses to this.
EDITED:
This question is specific to acquiring the users input (Using IE's Native Dialog or the Browser's native prompt). E.g. Again, Not Dialog boxes or Prompts developed by (You) as the Developer.
NOTE: --> There is a very significant difference in that developing with a Third Party library you as the Developer already have a reference to the object because YOU create it. Whereas you don't have an obvious handle to a Dialog Box created by the Browser.
You can't actually get the result of what was clicked, but you can use setTimeout in your onbeforeunload event to run some code if the user chooses to stay on the page.
For example:
var afterStayFunction = function() {
$("body").append("Thanks for staying.");
};
$(window).on("beforeunload", function(e) {
var prompt = "Are you sure you want to leave?";
e.returnValue = prompt;
setTimeout(function() { afterStayFunction(); });
return e.returnValue;
});
Live example here

Using form submit handler in jQueryMobile for validation, but preventing sending

I'm building an app in jQueryMobile and PhoneGap. I have an approach to validate forms that works nicely while testing in Chrome and on my Nexus S Android phone, but that I'm not sure will work on all devices.
This is the situation:
I have a few simple forms. The data that the user enters is stored locally. So I don't need POST or GET requests (in fact, I want to avoid them like the plague). I could just create a few inputs and a button and add a click handler to the button for everything to work nicely.
Except I really like the HTML5 form validation stuff. And that validation only (mostly) takes place when the submit event is fired on the form. So I have chosen to put the inputs and the button inside a form element, make one button a submit button, and listen for the submit event being fired on the form.
Another approach (shown here for the 'Delete' button) is to simply listen for a click on the button without making any use of the submit process. After all, if a user wants to delete an item, there is no need to validate the form (in my case anyway).
<form id="oneExpenseForm" action="javascript:void(0);" method=''>
<button type="submit" id="submitExpense">Save</button>
<button id="deleteExpense">Delete</button>
</form>
<script>
$('#oneExpenseForm').on('submit',function(){
submitExpense();//This function takes care of everything I want
})
</script>
This seems to work fine. I've also tried setting the form action differently:
<form id="oneExpenseForm" action="submit" method=''>
But that caused the browser to start a GET request, which causes a page reload (which is a really bad and unwanted thing when working with jQueryMobile).
What I'm worried about is that I may be setting things up for failure in certain browsers. After all, some browsers might see this action attribute...
action="javascript:void(0);"
...as a reason to not fire the submit event at all. That would be bad, since I need the submit event to fire for validation and
Am I taking needless risks here? Or do all browsers fire the submit event even when the form action is set to null, void, etc?
One more thing:
I could of course just specify...
action="javascript:submitExpense();"
...in the HTML file. But this is something that I want to avoid, since I am protecting my Js code with obfuscation. That involves changing the names of functions to unreadable code like aR3df(); using a special piece of software. I would prefer not to have to look up the obfuscated names and enter them in the HTML every time I am publishing an update.
EDIT:
After the first answer came in to use e.preventDefault() and that did not work, I figured it might be relevant that I am binding the submit event handler inside another function. That's because jQueryMobile wants you to only do your custom handling stuff after the "page" has been initialized.
In previous jQuery versions it didn't work to use the .live() binder within other functions. But this is not the problem either. Even when I bind the handler the ".live()" way using the new .on() binder...
$(document).on('pageinit','#oneExpensePage',function(event){
$('#oneExpenseForm').on('submit',function(){
submitExpense();//This function takes care of everything I want
})
})
... the page reload (i.e. form submit) persists.
Leave action empty action="" and prevent the event's default action on submit:
<script>
$(function() {
$('#oneExpenseForm').on('submit',function(e){
e.preventDefault();
submitExpense();
});
});
</script>

Categories

Resources